Fancy new buttons and more consistent colors

This commit is contained in:
Lei Nelissen
2021-02-11 23:43:21 +01:00
parent 42eb7a169b
commit 7adc96ba12
34 changed files with 15540 additions and 452 deletions

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect } from 'react';
import { StackParams } from '../types';
import { Text, ScrollView, Dimensions, Button, RefreshControl, StyleSheet } from 'react-native';
import { Text, ScrollView, Dimensions, RefreshControl, StyleSheet, View } from 'react-native';
import { useGetImage } from 'utility/JellyfinApi';
import styled, { css } from 'styled-components/native';
import { useRoute, RouteProp, useNavigation } from '@react-navigation/native';
@@ -13,9 +13,11 @@ import { ALBUM_CACHE_AMOUNT_OF_DAYS, THEME_COLOR } from 'CONSTANTS';
import usePlayAlbum from 'utility/usePlayAlbum';
import TouchableHandler from 'components/TouchableHandler';
import useCurrentTrack from 'utility/useCurrentTrack';
import { colors } from 'components/Colors';
import TrackPlayer from 'react-native-track-player';
import { t } from '@localisation';
import Button from 'components/Button';
import Play from 'assets/play.svg';
import useDefaultStyles from 'components/Colors';
type Route = RouteProp<StackParams, 'Album'>;
@@ -23,18 +25,15 @@ const Screen = Dimensions.get('screen');
const styles = StyleSheet.create({
name: {
...colors.text,
fontSize: 36,
fontWeight: 'bold'
},
artist: {
...colors.text,
fontSize: 24,
opacity: 0.5,
marginBottom: 24
},
index: {
...colors.text,
width: 20,
opacity: 0.5,
marginRight: 5
@@ -61,6 +60,8 @@ const TrackContainer = styled.View<{isPlaying: boolean}>`
`;
const Album: React.FC = () => {
const defaultStyles = useDefaultStyles();
// Retrieve state
const { params: { id } } = useRoute<Route>();
const tracks = useTypedSelector((state) => state.music.tracks.entities);
@@ -112,25 +113,27 @@ const Album: React.FC = () => {
<RefreshControl refreshing={isLoading} onRefresh={refresh} />
}
>
<AlbumImage source={{ uri: getImage(album?.Id) }} style={colors.imageBackground} />
<Text style={styles.name} >{album?.Name}</Text>
<Text style={styles.artist}>{album?.AlbumArtist}</Text>
<Button title={t('play-album')} onPress={selectAlbum} color={THEME_COLOR} />
{album?.Tracks?.length ? album.Tracks.map((trackId) =>
<TouchableHandler
key={trackId}
id={trackId}
onPress={selectTrack}
onLongPress={longPressTrack}
>
<TrackContainer isPlaying={currentTrack?.id.startsWith(trackId) || false} style={colors.border}>
<Text style={styles.index}>
{tracks[trackId]?.IndexNumber}
</Text>
<Text style={colors.text}>{tracks[trackId]?.Name}</Text>
</TrackContainer>
</TouchableHandler>
) : undefined}
<AlbumImage source={{ uri: getImage(album?.Id) }} style={defaultStyles.imageBackground} />
<Text style={[ defaultStyles.text, styles.name ]} >{album?.Name}</Text>
<Text style={[ defaultStyles.text, styles.artist ]}>{album?.AlbumArtist}</Text>
<Button title={t('play-album')} icon={Play} onPress={selectAlbum} />
<View style={{ marginTop: 15 }}>
{album?.Tracks?.length ? album.Tracks.map((trackId) =>
<TouchableHandler
key={trackId}
id={trackId}
onPress={selectTrack}
onLongPress={longPressTrack}
>
<TrackContainer isPlaying={currentTrack?.id.startsWith(trackId) || false} style={defaultStyles.border}>
<Text style={[ defaultStyles.text, styles.index ]}>
{tracks[trackId]?.IndexNumber}
</Text>
<Text style={defaultStyles.text}>{tracks[trackId]?.Name}</Text>
</TrackContainer>
</TouchableHandler>
) : undefined}
</View>
</ScrollView>
);
};

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef, PureComponent, ReactText } from 'react';
import React, { useCallback, useEffect, useRef, ReactText } from 'react';
import { useGetImage } from 'utility/JellyfinApi';
import { Album, NavigationProp } from '../types';
import { Text, SafeAreaView, SectionList, View } from 'react-native';
@@ -9,13 +9,12 @@ import { useTypedSelector } from 'store';
import { fetchAllAlbums } from 'store/music/actions';
import { ALBUM_CACHE_AMOUNT_OF_DAYS } from 'CONSTANTS';
import TouchableHandler from 'components/TouchableHandler';
import ListContainer from './components/ListContainer';
import AlbumImage, { AlbumItem } from './components/AlbumImage';
import { selectAlbumsByAlphabet, SectionedId } from 'store/music/selectors';
import AlphabetScroller from 'components/AlphabetScroller';
import { EntityId } from '@reduxjs/toolkit';
import styled from 'styled-components/native';
import { colors } from 'components/Colors';
import useDefaultStyles from 'components/Colors';
interface VirtualizedItemInfo {
section: SectionedId,
@@ -51,19 +50,16 @@ const SectionText = styled.Text`
font-weight: bold;
`;
const sectionStyles = { ...colors.view, ...colors.border };
const SectionHeading = React.memo(function SectionHeading(props: { label: string }) {
const defaultStyles = useDefaultStyles();
const { label } = props;
class SectionHeading extends PureComponent<{ label: string }> {
render() {
const { label } = this.props;
return (
<SectionContainer style={sectionStyles}>
<SectionText style={colors.text}>{label}</SectionText>
</SectionContainer>
);
}
}
return (
<SectionContainer style={defaultStyles.sectionHeading}>
<SectionText style={defaultStyles.text}>{label}</SectionText>
</SectionContainer>
);
});
interface GeneratedAlbumItemProps {
id: ReactText;
@@ -77,21 +73,20 @@ const HalfOpacity = styled.Text`
opacity: 0.5;
`;
class GeneratedAlbumItem extends PureComponent<GeneratedAlbumItemProps> {
render() {
const { id, imageUrl, name, artist, onPress } = this.props;
const GeneratedAlbumItem = React.memo(function GeneratedAlbumItem(props: GeneratedAlbumItemProps) {
const defaultStyles = useDefaultStyles();
const { id, imageUrl, name, artist, onPress } = props;
return (
<TouchableHandler id={id as string} onPress={onPress}>
<AlbumItem>
<AlbumImage source={{ uri: imageUrl }} style={colors.imageBackground} />
<Text numberOfLines={1} style={colors.text}>{name}</Text>
<HalfOpacity style={colors.text} numberOfLines={1}>{artist}</HalfOpacity>
</AlbumItem>
</TouchableHandler>
);
}
}
return (
<TouchableHandler id={id as string} onPress={onPress}>
<AlbumItem>
<AlbumImage source={{ uri: imageUrl }} style={defaultStyles.imageBackground} />
<Text numberOfLines={1} style={defaultStyles.text}>{name}</Text>
<HalfOpacity style={defaultStyles.text} numberOfLines={1}>{artist}</HalfOpacity>
</AlbumItem>
</TouchableHandler>
);
});
const Albums: React.FC = () => {
// Retrieve data from store

View File

@@ -12,31 +12,36 @@ import AlbumImage, { AlbumItem } from './components/AlbumImage';
import { useRecentAlbums } from 'store/music/selectors';
import { Header } from 'components/Typography';
import ListButton from 'components/ListButton';
import { colors } from 'components/Colors';
import { t } from '@localisation';
import useDefaultStyles from 'components/Colors';
const styles = StyleSheet.create({
artist: {
...colors.text,
opacity: 0.5,
columnWrapper: {
paddingLeft: 10,
paddingRight: 10
}
});
const NavigationHeader: React.FC = () => {
const navigation = useNavigation();
const defaultStyles = useDefaultStyles();
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
const handleSearchClick = useCallback(() => { navigation.navigate('Search'); }, [navigation]);
return (
<ListContainer>
<>
<ListButton onPress={handleAllAlbumsClick}>{t('all-albums')}</ListButton>
<ListButton onPress={handleSearchClick}>{t('search')}</ListButton>
<Header style={colors.text}>{t('recent-albums')}</Header>
</ListContainer>
<ListContainer>
<Header style={defaultStyles.text}>{t('recent-albums')}</Header>
</ListContainer>
</>
);
};
const RecentAlbums: React.FC = () => {
const defaultStyles = useDefaultStyles();
// Retrieve data from store
const { entities: albums } = useTypedSelector((state) => state.music.albums);
const recentAlbums = useRecentAlbums(24);
@@ -56,25 +61,24 @@ const RecentAlbums: React.FC = () => {
return (
<SafeAreaView>
<ListContainer>
<FlatList
data={recentAlbums as string[]}
refreshing={isLoading}
onRefresh={retrieveData}
numColumns={2}
keyExtractor={d => d}
ListHeaderComponent={NavigationHeader}
renderItem={({ item }) => (
<TouchableHandler id={item} onPress={selectAlbum}>
<AlbumItem>
<AlbumImage source={{ uri: getImage(item) }} style={colors.imageBackground} />
<Text style={colors.text} numberOfLines={1}>{albums[item]?.Name}</Text>
<Text style={styles.artist} numberOfLines={1}>{albums[item]?.AlbumArtist}</Text>
</AlbumItem>
</TouchableHandler>
)}
/>
</ListContainer>
<FlatList
data={recentAlbums as string[]}
refreshing={isLoading}
onRefresh={retrieveData}
numColumns={2}
keyExtractor={d => d}
columnWrapperStyle={styles.columnWrapper}
ListHeaderComponent={NavigationHeader}
renderItem={({ item }) => (
<TouchableHandler id={item} onPress={selectAlbum}>
<AlbumItem>
<AlbumImage source={{ uri: getImage(item) }} style={defaultStyles.imageBackground} />
<Text style={defaultStyles.text} numberOfLines={1}>{albums[item]?.Name}</Text>
<Text style={defaultStyles.textHalfOpacity} numberOfLines={1}>{albums[item]?.AlbumArtist}</Text>
</AlbumItem>
</TouchableHandler>
)}
/>
</SafeAreaView>
);
};

View File

@@ -11,8 +11,8 @@ import { useNavigation } from '@react-navigation/native';
import { useGetImage } from 'utility/JellyfinApi';
import { NavigationProp } from '../types';
import FastImage from 'react-native-fast-image';
import { colors } from 'components/Colors';
import { t } from '@localisation';
import useDefaultStyles from 'components/Colors';
const Container = styled.View`
padding: 0 20px;
@@ -47,6 +47,8 @@ const fuseOptions = {
};
export default function Search() {
const defaultStyles = useDefaultStyles();
// Prepare state
const [searchTerm, setSearchTerm] = useState('');
const albums = useTypedSelector(state => state.music.albums.entities);
@@ -89,10 +91,10 @@ export default function Search() {
const HeaderComponent = React.useMemo(() => (
<Container>
<Input value={searchTerm} onChangeText={setSearchTerm} style={colors.input} placeholder={t('search') + '...'} />
{(searchTerm.length && !results.length) ? <Text>{t('no-results')}</Text> : null}
<Input value={searchTerm} onChangeText={setSearchTerm} style={defaultStyles.input} placeholder={t('search') + '...'} />
{(searchTerm.length && !results.length) ? <Text style={{ textAlign: 'center' }}>{t('no-results')}</Text> : null}
</Container>
), [searchTerm, results, setSearchTerm]);
), [searchTerm, results, setSearchTerm, defaultStyles]);
// GUARD: We cannot search for stuff unless Fuse is loaded with results.
// Therefore we delay rendering to when we are certain it's there.
@@ -105,13 +107,13 @@ export default function Search() {
data={results}
renderItem={({ item: { item: album } }) =>(
<TouchableHandler id={album.Id} onPress={selectAlbum}>
<SearchResult style={colors.border}>
<SearchResult style={defaultStyles.border}>
<AlbumImage source={{ uri: getImage(album.Id) }} />
<View>
<Text numberOfLines={1} ellipsizeMode="tail" style={colors.text}>
<Text numberOfLines={1} ellipsizeMode="tail" style={defaultStyles.text}>
{album.Name} - {album.AlbumArtist}
</Text>
<HalfOpacity style={colors.text}>{t('album')}</HalfOpacity>
<HalfOpacity style={defaultStyles.text}>{t('album')}</HalfOpacity>
</View>
</SearchResult>
</TouchableHandler>

View File

@@ -1,6 +1,6 @@
import React, { useState, useCallback, useEffect, useRef } from 'react';
import TrackPlayer, { usePlaybackState, STATE_PLAYING, STATE_PAUSED } from 'react-native-track-player';
import { TouchableOpacity } from 'react-native';
import { TouchableOpacity, useColorScheme } from 'react-native';
import styled from 'styled-components/native';
import { useHasQueue } from 'utility/useQueue';
import ForwardIcon from 'assets/forwards.svg';
@@ -9,7 +9,6 @@ import PlayIcon from 'assets/play.svg';
import PauseIcon from 'assets/pause.svg';
import RepeatIcon from 'assets/repeat.svg';
// import ShuffleIcon from 'assets/shuffle.svg';
import { useColorScheme } from 'react-native-appearance';
import { THEME_COLOR } from 'CONSTANTS';
const BUTTON_SIZE = 40;

View File

@@ -1,9 +1,10 @@
import React from 'react';
import { Text, Dimensions, View, StyleSheet } from 'react-native';
import { Dimensions, View, StyleSheet } from 'react-native';
import useCurrentTrack from 'utility/useCurrentTrack';
import styled from 'styled-components/native';
import FastImage from 'react-native-fast-image';
import { colors } from 'components/Colors';
import useDefaultStyles from 'components/Colors';
import Text from 'components/Text';
const Screen = Dimensions.get('screen');
@@ -16,13 +17,11 @@ const Artwork = styled(FastImage)`
const styles = StyleSheet.create({
artist: {
...colors.text,
fontWeight: 'bold',
fontSize: 24,
marginBottom: 12,
},
title: {
...colors.text,
fontSize: 18,
marginBottom: 12,
textAlign: 'center',
@@ -34,17 +33,18 @@ const styles = StyleSheet.create({
export default function NowPlaying() {
const track = useCurrentTrack();
const defaultStyles = useDefaultStyles();
return (
<View style={{ alignItems: 'center' }}>
<Artwork
style={colors.imageBackground}
style={defaultStyles.imageBackground}
source={{
uri: track?.artwork,
priority: FastImage.priority.high,
}}
/>
<Text style={styles.artist} >{track?.artist}</Text>
<Text style={styles.artist}>{track?.artist}</Text>
<Text style={styles.title}>{track?.title}</Text>
</View>
);

View File

@@ -4,7 +4,7 @@ import styled from 'styled-components/native';
import { Text, Platform } from 'react-native';
import Slider from '@react-native-community/slider';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
import { DefaultStylesProvider } from 'components/Colors';
const NumberBar = styled.View`
flex-direction: row;
@@ -65,24 +65,29 @@ export default class ProgressBar extends Component<{}, State> {
render() {
const { position, duration, gesture } = this.state;
return (
<>
<Slider
value={gesture || position}
minimumValue={0}
maximumValue={duration || 0}
onValueChange={this.handleGesture}
onSlidingComplete={this.handleEndOfGesture}
minimumTrackTintColor={THEME_COLOR}
thumbTintColor={Platform.OS === 'android' ? THEME_COLOR : undefined}
disabled={!duration}
/>
<NumberBar>
<Text style={colors.text}>{getMinutes(gesture || position)}:{getSeconds(gesture || position)}</Text>
<Text style={colors.text}>{getMinutes(duration)}:{getSeconds(duration)}</Text>
</NumberBar>
</>
<DefaultStylesProvider>
{defaultStyle => (
<>
<Slider
value={gesture || position}
minimumValue={0}
maximumValue={duration || 0}
onValueChange={this.handleGesture}
onSlidingComplete={this.handleEndOfGesture}
minimumTrackTintColor={THEME_COLOR}
thumbTintColor={Platform.OS === 'android' ? THEME_COLOR : undefined}
disabled={!duration}
/>
<NumberBar>
<Text style={defaultStyle.text}>{getMinutes(gesture || position)}:{getSeconds(gesture || position)}</Text>
<Text style={defaultStyle.text}>{getMinutes(duration)}:{getSeconds(duration)}</Text>
</NumberBar>
</>
)
}
</DefaultStylesProvider>
);
}
}

View File

@@ -1,13 +1,14 @@
import React, { useCallback } from 'react';
import useQueue from 'utility/useQueue';
import { View, Text, StyleSheet, Button } from 'react-native';
import { View, StyleSheet } from 'react-native';
import styled, { css } from 'styled-components/native';
import useCurrentTrack from 'utility/useCurrentTrack';
import TouchableHandler from 'components/TouchableHandler';
import TrackPlayer from 'react-native-track-player';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
import { t } from '@localisation';
import useDefaultStyles from 'components/Colors';
import Text from 'components/Text';
import Button from 'components/Button';
const QueueItem = styled.View<{ active?: boolean, alreadyPlayed?: boolean, isDark?: boolean }>`
padding: 10px;
@@ -29,17 +30,13 @@ const ClearQueue = styled.View`
`;
const styles = StyleSheet.create({
title: {
...colors.text,
marginBottom: 2,
},
artist: {
...colors.text,
opacity: 0.5,
trackTitle: {
marginBottom: 2
}
});
export default function Queue() {
const defaultStyles = useDefaultStyles();
const queue = useQueue();
const currentTrack = useCurrentTrack();
const currentIndex = queue.findIndex(d => d.id === currentTrack?.id);
@@ -60,18 +57,18 @@ export default function Queue() {
active={currentTrack?.id === track.id}
key={i}
alreadyPlayed={i < currentIndex}
style={{
...colors.border,
...currentTrack?.id === track.id ? colors.activeBackground : {},
}}
style={[
defaultStyles.border,
currentTrack?.id === track.id ? defaultStyles.activeBackground : {},
]}
>
<Text style={styles.title}>{track.title}</Text>
<Text style={styles.artist}>{track.artist}</Text>
<Text style={styles.trackTitle}>{track.title}</Text>
<Text style={defaultStyles.textHalfOpacity}>{track.artist}</Text>
</QueueItem>
</TouchableHandler>
))}
<ClearQueue>
<Button title={t('clear-queue')} color={THEME_COLOR} onPress={clearQueue} />
<Button title={t('clear-queue')} onPress={clearQueue} />
</ClearQueue>
</View>
);

View File

@@ -4,18 +4,19 @@ import MediaControls from './components/MediaControls';
import ProgressBar from './components/ProgressBar';
import NowPlaying from './components/NowPlaying';
import Queue from './components/Queue';
import { colors } from 'components/Colors';
import useDefaultStyles from 'components/Colors';
const styles = StyleSheet.create({
outer: colors.view,
inner: {
padding: 25,
}
});
export default function Player() {
const defaultStyles = useDefaultStyles();
return (
<ScrollView contentContainerStyle={styles.inner} style={styles.outer}>
<ScrollView contentContainerStyle={styles.inner} style={defaultStyles.view}>
<NowPlaying />
<MediaControls />
<ProgressBar />

View File

@@ -1,11 +1,16 @@
import React, { useCallback } from 'react';
import TrackPlayer from 'react-native-track-player';
import { SubHeader } from 'components/Typography';
import { Text, Button } from 'react-native';
import { THEME_COLOR } from 'CONSTANTS';
import { useDispatch } from 'react-redux';
import music from 'store/music';
import { t } from '@localisation';
import Button from 'components/Button';
import styled from 'styled-components/native';
import Text from 'components/Text';
const ClearCache = styled(Button)`
margin-top: 16px;
`;
export default function CacheSettings() {
const dispatch = useDispatch();
@@ -21,7 +26,7 @@ export default function CacheSettings() {
<>
<SubHeader>{t('setting-cache')}</SubHeader>
<Text>{t('setting-cache-description')}</Text>
<Button title={t('reset-cache')} onPress={handleClearCache} color={THEME_COLOR} />
<ClearCache title={t('reset-cache')} onPress={handleClearCache} />
</>
);
}

View File

@@ -1,13 +1,13 @@
import styled from 'styled-components/native';
import { useNavigation } from '@react-navigation/native';
import React, { useCallback } from 'react';
import { Text, Button } from 'react-native';
import { THEME_COLOR } from 'CONSTANTS';
import { SubHeader } from 'components/Typography';
import { colors } from 'components/Colors';
import useDefaultStyles from 'components/Colors';
import { NavigationProp } from '../..';
import { useTypedSelector } from 'store';
import { t } from '@localisation';
import Button from 'components/Button';
import Text from 'components/Text';
const InputContainer = styled.View`
margin: 10px 0;
@@ -20,6 +20,7 @@ const Input = styled.TextInput`
`;
export default function LibrarySettings() {
const defaultStyles = useDefaultStyles();
const { jellyfin } = useTypedSelector(state => state.settings);
const navigation = useNavigation<NavigationProp>();
const handleSetLibrary = useCallback(() => navigation.navigate('SetJellyfinServer'), [navigation]);
@@ -28,18 +29,18 @@ export default function LibrarySettings() {
<>
<SubHeader>{t('jellyfin-library')}</SubHeader>
<InputContainer>
<Text style={colors.text}>{t('jellyfin-server-url')}</Text>
<Input placeholder="https://jellyfin.yourserver.com/" value={jellyfin?.uri} editable={false} style={colors.input} />
<Text style={defaultStyles.text}>{t('jellyfin-server-url')}</Text>
<Input placeholder="https://jellyfin.yourserver.com/" value={jellyfin?.uri} editable={false} style={defaultStyles.input} />
</InputContainer>
<InputContainer>
<Text style={colors.text}>{t('jellyfin-access-token')}</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.access_token} editable={false} style={colors.input} />
<Text style={defaultStyles.text}>{t('jellyfin-access-token')}</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.access_token} editable={false} style={defaultStyles.input} />
</InputContainer>
<InputContainer>
<Text style={colors.text}>{t('jellyfin-user-id')}</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.user_id} editable={false} style={colors.input} />
<Text style={defaultStyles.text}>{t('jellyfin-user-id')}</Text>
<Input placeholder="deadbeefdeadbeefdeadbeef" value={jellyfin?.user_id} editable={false} style={defaultStyles.input} />
</InputContainer>
<Button title={t('set-jellyfin-server')} onPress={handleSetLibrary} color={THEME_COLOR} />
<Button title={t('set-jellyfin-server')} onPress={handleSetLibrary} />
</>
);
}

View File

@@ -1,17 +1,19 @@
import React from 'react';
import { View, SafeAreaView, ScrollView } from 'react-native';
import { Header } from 'components/Typography';
import { colors } from 'components/Colors';
import Library from './components/Library';
import Cache from './components/Cache';
import useDefaultStyles from 'components/Colors';
import { Header } from 'components/Typography';
import { t } from '@localisation';
export default function Settings() {
const defaultStyles = useDefaultStyles();
return (
<ScrollView>
<SafeAreaView>
<View style={{ padding: 20 }}>
<Header style={colors.text}>{t('settings')}</Header>
<Header style={defaultStyles.text}>{t('settings')}</Header>
<Library />
<Cache />
</View>

View File

@@ -93,6 +93,6 @@ export default function Routes() {
}
export type NavigationProp = CompositeNavigationProp<
StackNavigationProp<Routes>,
BottomTabNavigationProp<Screens>
StackNavigationProp<Routes>,
BottomTabNavigationProp<Screens>
>;

View File

@@ -1,5 +1,5 @@
import React, { useState, useCallback } from 'react';
import { Text, Button, View } from 'react-native';
import { Button, View } from 'react-native';
import Modal from 'components/Modal';
import Input from 'components/Input';
import { setJellyfinCredentials } from 'store/settings/actions';
@@ -7,10 +7,12 @@ import { useDispatch } from 'react-redux';
import { useNavigation, StackActions } from '@react-navigation/native';
import CredentialGenerator from './components/CredentialGenerator';
import { THEME_COLOR } from 'CONSTANTS';
import { colors } from 'components/Colors';
import { t } from '@localisation';
import useDefaultStyles from 'components/Colors';
import Text from 'components/Text';
export default function SetJellyfinServer() {
const defaultStyles = useDefaultStyles();
// State for first screen
const [serverUrl, setServerUrl] = useState<string>();
const [isLogginIn, setIsLogginIn] = useState<boolean>(false);
@@ -34,7 +36,7 @@ export default function SetJellyfinServer() {
/>
) : (
<View style={{ padding: 20, flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={colors.text}>
<Text>
{t('set-jellyfin-server-instruction')}
</Text>
<Input
@@ -44,7 +46,7 @@ export default function SetJellyfinServer() {
keyboardType="url"
autoCapitalize="none"
autoCorrect={false}
style={{ ...colors.input, width: '100%' }}
style={[ defaultStyles.input, { width: '100%' } ]}
/>
<Button
title={t('set-jellyfin-server')}

View File

@@ -1,14 +1,16 @@
import React, { useCallback } from 'react';
import Modal from 'components/Modal';
import { Text, Button } from 'react-native';
import { useNavigation, StackActions, useRoute, RouteProp } from '@react-navigation/native';
import { ModalStackParams } from 'screens/types';
import { useTypedSelector } from 'store';
import { THEME_COLOR } from 'CONSTANTS';
import { SubHeader } from 'components/Typography';
import styled from 'styled-components/native';
import usePlayTrack from 'utility/usePlayTrack';
import { t } from '@localisation';
import Button from 'components/Button';
import PlayIcon from 'assets/play.svg';
import QueueAppendIcon from 'assets/queue-append.svg';
import Text from 'components/Text';
type Route = RouteProp<ModalStackParams, 'TrackPopupMenu'>;
@@ -19,7 +21,11 @@ const Container = styled.View`
const Buttons = styled.View`
margin-top: 20px;
flex-direction: row;
justify-content: space-around;
/* justify-content: space-around; */
`;
const ButtonSpacing = styled.View`
width: 8px;
`;
function TrackPopupMenu() {
@@ -49,8 +55,9 @@ function TrackPopupMenu() {
<SubHeader>{track?.Name}</SubHeader>
<Text>{track?.Album} - {track?.AlbumArtist}</Text>
<Buttons>
<Button title={t('play-next')} color={THEME_COLOR} onPress={handlePlayNext} />
<Button title={t('add-to-queue')} color={THEME_COLOR} onPress={handleAddToQueue} />
<Button title={t('play-next')} icon={PlayIcon} onPress={handlePlayNext} />
<ButtonSpacing />
<Button title={t('add-to-queue')} icon={QueueAppendIcon} onPress={handleAddToQueue} />
</Buttons>
</Container>
</Modal>