mirror of
https://github.com/jellyfin/jellyfin-expo.git
synced 2024-11-23 05:59:39 +00:00
Remove old settings screen
This commit is contained in:
parent
1958194e5e
commit
d3d4036296
@ -16,7 +16,6 @@ import Colors from '../constants/Colors';
|
||||
import AddServerScreen from '../screens/AddServerScreen';
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import SettingsScreen from '../screens/SettingsScreen';
|
||||
import NewSettingsScreen from '../screens/NewSettingsScreen';
|
||||
|
||||
// Customize theme for navigator
|
||||
const theme = {
|
||||
@ -58,7 +57,7 @@ function Main() {
|
||||
}}
|
||||
>
|
||||
<Tab.Screen name='Home' component={HomeScreen} />
|
||||
<Tab.Screen name='Settings' component={NewSettingsScreen} />
|
||||
<Tab.Screen name='Settings' component={SettingsScreen} />
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
@ -1,168 +0,0 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
import React, { useEffect } from 'react';
|
||||
import { Alert, AsyncStorage, Platform, SectionList, StyleSheet } from 'react-native';
|
||||
import { colors, Text } from 'react-native-elements';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import AppInfoFooter from '../components/AppInfoFooter';
|
||||
import BrowserListItem from '../components/BrowserListItem';
|
||||
import ButtonListItem from '../components/ButtonListItem';
|
||||
import ServerListItem from '../components/ServerListItem';
|
||||
import Colors from '../constants/Colors';
|
||||
import Links from '../constants/Links';
|
||||
import { useStores } from '../hooks/useStores';
|
||||
|
||||
const NewSettingsScreen = observer(() => {
|
||||
const { rootStore } = useStores();
|
||||
const navigation = useNavigation();
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch server info
|
||||
rootStore.serverStore.fetchInfo();
|
||||
}, []);
|
||||
|
||||
const onAddServer = () => {
|
||||
navigation.navigate('AddServer');
|
||||
};
|
||||
|
||||
const onDeleteServer = index => {
|
||||
Alert.alert(
|
||||
'Delete Server',
|
||||
'Are you sure you want to delete this server?',
|
||||
[
|
||||
{ text: 'Cancel' },
|
||||
{
|
||||
text: 'Delete',
|
||||
onPress: () => {
|
||||
// Remove server and update active server
|
||||
rootStore.serverStore.removeServer(index);
|
||||
rootStore.settingStore.activeServer = 0;
|
||||
|
||||
if (rootStore.serverStore.servers.length > 0) {
|
||||
// More servers exist, navigate home
|
||||
navigation.navigate('Home');
|
||||
} else {
|
||||
// No servers are present, navigate to add server screen
|
||||
navigation.replace('AddServer');
|
||||
}
|
||||
},
|
||||
style: 'destructive'
|
||||
}
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
const onSelectServer = index => {
|
||||
rootStore.settingStore.activeServer = index;
|
||||
navigation.navigate('Home');
|
||||
};
|
||||
|
||||
const onResetApplication = () => {
|
||||
Alert.alert(
|
||||
'Reset Application',
|
||||
'Are you sure you want to reset all settings?',
|
||||
[
|
||||
{ text: 'Cancel' },
|
||||
{
|
||||
text: 'Reset',
|
||||
onPress: () => {
|
||||
// Reset data in stores
|
||||
rootStore.reset();
|
||||
AsyncStorage.clear();
|
||||
// Navigate to the loading screen
|
||||
navigation.replace('AddServer');
|
||||
},
|
||||
style: 'destructive'
|
||||
}
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
const AugmentedServerListItem = (props) => (
|
||||
<ServerListItem
|
||||
{...props}
|
||||
activeServer={rootStore.settingStore.activeServer}
|
||||
onDelete={onDeleteServer}
|
||||
onPress={onSelectServer}
|
||||
/>
|
||||
);
|
||||
|
||||
const getSections = () => {
|
||||
return [
|
||||
{
|
||||
title: 'Servers',
|
||||
data: rootStore.serverStore.servers.slice(),
|
||||
keyExtractor: (item, index) => `server-${index}`,
|
||||
renderItem: AugmentedServerListItem
|
||||
},
|
||||
{
|
||||
title: 'Add Server',
|
||||
hideHeader: true,
|
||||
data: [{
|
||||
key: 'add-server-button',
|
||||
title: 'Add Server',
|
||||
onPress: onAddServer
|
||||
}],
|
||||
renderItem: ButtonListItem
|
||||
},
|
||||
{
|
||||
title: 'Links',
|
||||
data: Links,
|
||||
renderItem: BrowserListItem
|
||||
},
|
||||
{
|
||||
title: 'Reset Application',
|
||||
hideHeader: true,
|
||||
data: [{
|
||||
key: 'reset-app-button',
|
||||
title: 'Reset Application',
|
||||
buttonStyle: {
|
||||
backgroundColor: Platform.OS === 'ios' ? colors.platform.ios.error : colors.platform.android.error
|
||||
},
|
||||
onPress: onResetApplication
|
||||
}],
|
||||
renderItem: ButtonListItem
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{...styles.container, paddingTop: 0}} >
|
||||
<SectionList
|
||||
sections={getSections()}
|
||||
extraData={{
|
||||
activeServer: rootStore.settingStore.activeServer,
|
||||
isFetching: rootStore.serverStore.fetchInfo.pending
|
||||
}}
|
||||
renderItem={({ item }) => <Text>{JSON.stringify(item)}</Text>}
|
||||
renderSectionHeader={({ section: { title, hideHeader } }) => hideHeader ? null : <Text style={styles.header}>{title}</Text>}
|
||||
ListFooterComponent={AppInfoFooter}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.backgroundColor
|
||||
},
|
||||
header: {
|
||||
backgroundColor: Colors.backgroundColor,
|
||||
color: colors.grey4,
|
||||
fontSize: 17,
|
||||
fontWeight: '600',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 15,
|
||||
marginBottom: 1
|
||||
}
|
||||
});
|
||||
|
||||
export default NewSettingsScreen;
|
@ -3,283 +3,166 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
FlatList,
|
||||
Platform,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { Button, colors, ListItem, Text, Icon } from 'react-native-elements';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Alert, AsyncStorage, Platform, SectionList, StyleSheet } from 'react-native';
|
||||
import { colors, Text } from 'react-native-elements';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { observer } from 'mobx-react';
|
||||
import Constants from 'expo-constants';
|
||||
import Url from 'url';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useStores } from '../hooks/useStores';
|
||||
import SettingsSection from '../components/SettingsSection';
|
||||
import AppInfoFooter from '../components/AppInfoFooter';
|
||||
import BrowserListItem from '../components/BrowserListItem';
|
||||
import ButtonListItem from '../components/ButtonListItem';
|
||||
import ServerListItem from '../components/ServerListItem';
|
||||
import Colors from '../constants/Colors';
|
||||
import Links from '../constants/Links';
|
||||
import JellyfinValidator from '../utils/JellyfinValidator';
|
||||
import { getAppName } from '../utils/Device';
|
||||
import { openBrowser } from '../utils/WebBrowser';
|
||||
import { useStores } from '../hooks/useStores';
|
||||
|
||||
@observer
|
||||
class SettingsScreen extends React.Component {
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object.isRequired,
|
||||
rootStore: PropTypes.object.isRequired
|
||||
}
|
||||
const SettingsScreen = observer(() => {
|
||||
const { rootStore } = useStores();
|
||||
const navigation = useNavigation();
|
||||
|
||||
state = {
|
||||
servers: null
|
||||
useEffect(() => {
|
||||
// Fetch server info
|
||||
rootStore.serverStore.fetchInfo();
|
||||
}, []);
|
||||
|
||||
const onAddServer = () => {
|
||||
navigation.navigate('AddServer');
|
||||
};
|
||||
|
||||
_keyExtractor = (item, index) => `${item.name}-${index}`;
|
||||
|
||||
_renderLink = ({ item, index }) => {
|
||||
console.log('renderLink', item);
|
||||
return (
|
||||
<ListItem
|
||||
title={item.name}
|
||||
leftIcon={item.icon}
|
||||
topDivider={index === 0}
|
||||
bottomDivider
|
||||
chevron
|
||||
onPress={() => {
|
||||
openBrowser(item.url);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
_renderServer = ({ item, index }) => {
|
||||
const { info, serverUrl, online = false } = item;
|
||||
console.log('renderServer', info, serverUrl, online);
|
||||
|
||||
let title;
|
||||
let subtitle;
|
||||
if (info) {
|
||||
title = info.ServerName;
|
||||
subtitle = `Version: ${info.Version}\n${serverUrl}`;
|
||||
} else {
|
||||
title = Url.parse(serverUrl).host;
|
||||
subtitle = `Version: unknown\n${serverUrl}`;
|
||||
}
|
||||
|
||||
return (<ListItem
|
||||
title={title}
|
||||
titleStyle={{
|
||||
marginBottom: 2
|
||||
}}
|
||||
subtitle={subtitle}
|
||||
leftElement={(
|
||||
index === this.props.rootStore.settingStore.activeServer ? (
|
||||
<Icon
|
||||
name={(Platform.OS === 'ios' ? 'ios-checkmark' : 'md-checkmark')}
|
||||
type='ionicon'
|
||||
size={24}
|
||||
containerStyle={{ width: 12 }}
|
||||
/>
|
||||
) : (
|
||||
<View style={{ width: 12 }} />
|
||||
)
|
||||
)}
|
||||
rightElement={(
|
||||
<Button
|
||||
type='clear'
|
||||
icon={{
|
||||
name: Platform.OS === 'ios' ? 'ios-trash' : 'md-trash',
|
||||
type: 'ionicon',
|
||||
iconStyle: {
|
||||
color: Platform.OS === 'ios' ? colors.platform.ios.error : colors.platform.android.error
|
||||
}
|
||||
}}
|
||||
onPress={() => this.onDeleteServer(index)}
|
||||
/>
|
||||
)}
|
||||
topDivider={index === 0}
|
||||
bottomDivider
|
||||
onPress={async () => {
|
||||
this.props.rootStore.settingStore.activeServer = index;
|
||||
this.props.navigation.navigate('Home', { activeServer: index });
|
||||
}}
|
||||
/>);
|
||||
};
|
||||
|
||||
async bootstrapAsync() {
|
||||
let { servers } = this.props.rootStore.serverStore;
|
||||
|
||||
servers = servers.map(async (server) => {
|
||||
let serverUrl;
|
||||
try {
|
||||
serverUrl = JellyfinValidator.getServerUrl(server);
|
||||
} catch (err) {
|
||||
serverUrl = '';
|
||||
}
|
||||
// Try to fetch the server's public info
|
||||
try {
|
||||
const serverInfo = await JellyfinValidator.fetchServerInfo(server);
|
||||
return Object.assign(
|
||||
{},
|
||||
server,
|
||||
{
|
||||
info: serverInfo,
|
||||
serverUrl,
|
||||
online: true
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
return Object.assign(
|
||||
{},
|
||||
server,
|
||||
{
|
||||
serverUrl,
|
||||
online: false
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
servers = await Promise.all(servers);
|
||||
|
||||
console.log('bootstrapAsync', servers);
|
||||
|
||||
this.setState({
|
||||
servers
|
||||
});
|
||||
}
|
||||
|
||||
async deleteServer(index) {
|
||||
// Remove server and update active server
|
||||
this.props.rootStore.serverStore.removeServer(index);
|
||||
this.props.rootStore.settingStore.activeServer = 0;
|
||||
|
||||
if (this.props.rootStore.serverStore.servers.length > 0) {
|
||||
// More servers exist, update state and navigate home
|
||||
this.bootstrapAsync();
|
||||
this.props.navigation.navigate('Home', { activeServer: 0 });
|
||||
} else {
|
||||
// No servers are present, navigate to add server screen
|
||||
this.props.navigation.replace('AddServer');
|
||||
}
|
||||
}
|
||||
|
||||
async resetApplication() {
|
||||
// Reset data in stores
|
||||
this.props.rootStore.serverStore.servers = [];
|
||||
this.props.rootStore.settingStore.activeServer = 0;
|
||||
// Navigate to the loading screen
|
||||
this.props.navigation.replace('AddServer');
|
||||
}
|
||||
|
||||
onDeleteServer(index) {
|
||||
const onDeleteServer = index => {
|
||||
Alert.alert(
|
||||
'Delete Server',
|
||||
'Are you sure you want to delete this server?',
|
||||
[
|
||||
{ text: 'Cancel' },
|
||||
{ text: 'Delete', onPress: () => this.deleteServer(index), style: 'destructive' }
|
||||
{
|
||||
text: 'Delete',
|
||||
onPress: () => {
|
||||
// Remove server and update active server
|
||||
rootStore.serverStore.removeServer(index);
|
||||
rootStore.settingStore.activeServer = 0;
|
||||
|
||||
if (rootStore.serverStore.servers.length > 0) {
|
||||
// More servers exist, navigate home
|
||||
navigation.navigate('Home');
|
||||
} else {
|
||||
// No servers are present, navigate to add server screen
|
||||
navigation.replace('AddServer');
|
||||
}
|
||||
},
|
||||
style: 'destructive'
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onResetApplication() {
|
||||
const onSelectServer = index => {
|
||||
rootStore.settingStore.activeServer = index;
|
||||
navigation.navigate('Home');
|
||||
};
|
||||
|
||||
const onResetApplication = () => {
|
||||
Alert.alert(
|
||||
'Reset Application',
|
||||
'Are you sure you want to reset all settings?',
|
||||
[
|
||||
{ text: 'Cancel' },
|
||||
{ text: 'Reset', onPress: () => this.resetApplication(), style: 'destructive' }
|
||||
{
|
||||
text: 'Reset',
|
||||
onPress: () => {
|
||||
// Reset data in stores
|
||||
rootStore.reset();
|
||||
AsyncStorage.clear();
|
||||
// Navigate to the loading screen
|
||||
navigation.replace('AddServer');
|
||||
},
|
||||
style: 'destructive'
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.bootstrapAsync();
|
||||
}
|
||||
const AugmentedServerListItem = (props) => (
|
||||
<ServerListItem
|
||||
{...props}
|
||||
activeServer={rootStore.settingStore.activeServer}
|
||||
onDelete={onDeleteServer}
|
||||
onPress={onSelectServer}
|
||||
/>
|
||||
);
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SafeAreaView style={{...styles.container, paddingTop: 0}} >
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<SettingsSection heading='Servers'>
|
||||
{
|
||||
this.state.servers ? (
|
||||
<FlatList
|
||||
keyExtractor={this._keyExtractor}
|
||||
data={this.state.servers}
|
||||
renderItem={this._renderServer}
|
||||
scrollEnabled={false}
|
||||
extraData={this.props.rootStore.settingStore.activeServer}
|
||||
/>
|
||||
) : (
|
||||
<ActivityIndicator />
|
||||
)
|
||||
}
|
||||
</SettingsSection>
|
||||
const getSections = () => {
|
||||
return [
|
||||
{
|
||||
title: 'Servers',
|
||||
data: rootStore.serverStore.servers.slice(),
|
||||
keyExtractor: (item, index) => `server-${index}`,
|
||||
renderItem: AugmentedServerListItem
|
||||
},
|
||||
{
|
||||
title: 'Add Server',
|
||||
hideHeader: true,
|
||||
data: [{
|
||||
key: 'add-server-button',
|
||||
title: 'Add Server',
|
||||
onPress: onAddServer
|
||||
}],
|
||||
renderItem: ButtonListItem
|
||||
},
|
||||
{
|
||||
title: 'Links',
|
||||
data: Links,
|
||||
renderItem: BrowserListItem
|
||||
},
|
||||
{
|
||||
title: 'Reset Application',
|
||||
hideHeader: true,
|
||||
data: [{
|
||||
key: 'reset-app-button',
|
||||
title: 'Reset Application',
|
||||
buttonStyle: {
|
||||
backgroundColor: Platform.OS === 'ios' ? colors.platform.ios.error : colors.platform.android.error
|
||||
},
|
||||
onPress: onResetApplication
|
||||
}],
|
||||
renderItem: ButtonListItem
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
<Button
|
||||
buttonStyle={{ margin: 15 }}
|
||||
title='Add Server'
|
||||
onPress={() => this.props.navigation.navigate('AddServer')}
|
||||
/>
|
||||
|
||||
<SettingsSection heading='Links'>
|
||||
<FlatList
|
||||
keyExtractor={this._keyExtractor}
|
||||
data={Links}
|
||||
renderItem={this._renderLink}
|
||||
scrollEnabled={false}
|
||||
/>
|
||||
</SettingsSection>
|
||||
|
||||
<Button
|
||||
buttonStyle={{
|
||||
backgroundColor: Platform.OS === 'ios' ? colors.platform.ios.error : colors.platform.android.error,
|
||||
margin: 15
|
||||
}}
|
||||
title='Reset Application'
|
||||
onPress={() => this.onResetApplication()}
|
||||
/>
|
||||
|
||||
<View style={styles.infoContainer}>
|
||||
<Text style={styles.infoText}>{`${getAppName()}`}</Text>
|
||||
<Text style={styles.infoText}>{`${Constants.nativeAppVersion} (${Constants.nativeBuildVersion})`}</Text>
|
||||
<Text style={styles.infoText}>{`Expo Version: ${Constants.expoVersion}`}</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<SafeAreaView style={{...styles.container, paddingTop: 0}} >
|
||||
<SectionList
|
||||
sections={getSections()}
|
||||
extraData={{
|
||||
activeServer: rootStore.settingStore.activeServer,
|
||||
isFetching: rootStore.serverStore.fetchInfo.pending
|
||||
}}
|
||||
renderItem={({ item }) => <Text>{JSON.stringify(item)}</Text>}
|
||||
renderSectionHeader={({ section: { title, hideHeader } }) => hideHeader ? null : <Text style={styles.header}>{title}</Text>}
|
||||
ListFooterComponent={AppInfoFooter}
|
||||
showsVerticalScrollIndicator={false}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: Colors.backgroundColor
|
||||
},
|
||||
infoContainer: {
|
||||
margin: 15
|
||||
},
|
||||
infoText: {
|
||||
header: {
|
||||
backgroundColor: Colors.backgroundColor,
|
||||
color: colors.grey4,
|
||||
fontSize: 15
|
||||
fontSize: 17,
|
||||
fontWeight: '600',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 15,
|
||||
marginBottom: 1
|
||||
}
|
||||
});
|
||||
|
||||
// Inject the Navigation Hook as a prop to mimic the legacy behavior
|
||||
const SettingsScreenWithNavigation = observer((props) => {
|
||||
const stores = useStores();
|
||||
return <SettingsScreen {...props} navigation={useNavigation()} {...stores} />;
|
||||
});
|
||||
|
||||
export default SettingsScreenWithNavigation;
|
||||
export default SettingsScreen;
|
||||
|
Loading…
Reference in New Issue
Block a user