diff --git a/app/index.js b/app/index.js
index c9ff78dcc..468cb1b82 100644
--- a/app/index.js
+++ b/app/index.js
@@ -224,6 +224,9 @@ const SettingsStack = createStackNavigator({
},
DefaultBrowserView: {
getScreen: () => require('./views/DefaultBrowserView').default
+ },
+ ScreenLockConfigView: {
+ getScreen: () => require('./views/ScreenLockConfigView').default
}
}, {
defaultNavigationOptions: defaultHeader,
diff --git a/app/lib/database/model/Server.js b/app/lib/database/model/Server.js
index 8a82cc07c..568fd2ad4 100644
--- a/app/lib/database/model/Server.js
+++ b/app/lib/database/model/Server.js
@@ -19,4 +19,8 @@ export default class Server extends Model {
@field('version') version;
@date('last_local_authenticated_session') lastLocalAuthenticatedSession;
+
+ @field('auto_lock') autoLock;
+
+ @field('auto_lock_time') autoLockTime;
}
diff --git a/app/lib/database/model/serversMigrations.js b/app/lib/database/model/serversMigrations.js
index 4ccde6180..68c36e96d 100644
--- a/app/lib/database/model/serversMigrations.js
+++ b/app/lib/database/model/serversMigrations.js
@@ -19,7 +19,9 @@ export default schemaMigrations({
addColumns({
table: 'servers',
columns: [
- { name: 'last_local_authenticated_session', type: 'number', isOptional: true }
+ { name: 'last_local_authenticated_session', type: 'number', isOptional: true },
+ { name: 'auto_lock', type: 'boolean', isOptional: true },
+ { name: 'auto_lock_time', type: 'number', isOptional: true }
]
})
]
diff --git a/app/lib/database/schema/servers.js b/app/lib/database/schema/servers.js
index b843dfde9..e5506fe04 100644
--- a/app/lib/database/schema/servers.js
+++ b/app/lib/database/schema/servers.js
@@ -25,7 +25,9 @@ export default appSchema({
{ name: 'file_upload_max_file_size', type: 'number', isOptional: true },
{ name: 'rooms_updated_at', type: 'number', isOptional: true },
{ name: 'version', type: 'string', isOptional: true },
- { name: 'last_local_authenticated_session', type: 'number', isOptional: true }
+ { name: 'last_local_authenticated_session', type: 'number', isOptional: true },
+ { name: 'auto_lock', type: 'boolean', isOptional: true },
+ { name: 'auto_lock_time', type: 'number', isOptional: true }
]
})
]
diff --git a/app/utils/localAuthentication.js b/app/utils/localAuthentication.js
index 8f3150ed3..82c3f42e6 100644
--- a/app/utils/localAuthentication.js
+++ b/app/utils/localAuthentication.js
@@ -34,14 +34,16 @@ export const localAuthenticate = async(server) => {
const diffToLastSession = moment().diff(serverRecord?.lastLocalAuthenticatedSession, 'seconds');
console.log('localAuthenticate -> diffToLastSession', diffToLastSession);
- if (diffToLastSession >= 5) {
- const authResult = await LocalAuthentication.authenticateAsync();
- if (authResult?.success) {
- await saveLastLocalAuthenticationSession(server);
- }
- return Promise.resolve(authResult?.success);
- } else {
- await saveLastLocalAuthenticationSession(server);
- }
+ // if (diffToLastSession >= 5) {
+ // const supported = await LocalAuthentication.supportedAuthenticationTypesAsync()
+ // console.log('localAuthenticate -> supported', supported);
+ // const authResult = await LocalAuthentication.authenticateAsync();
+ // if (authResult?.success) {
+ // await saveLastLocalAuthenticationSession(server);
+ // }
+ // return Promise.resolve(authResult?.success);
+ // } else {
+ // await saveLastLocalAuthenticationSession(server);
+ // }
return Promise.resolve(true);
};
diff --git a/app/views/ScreenLockConfigView.js b/app/views/ScreenLockConfigView.js
new file mode 100644
index 000000000..019af19c2
--- /dev/null
+++ b/app/views/ScreenLockConfigView.js
@@ -0,0 +1,218 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {
+ StyleSheet, FlatList, View, Text, Linking, Switch, ScrollView
+} from 'react-native';
+import { SafeAreaView } from 'react-navigation';
+
+import I18n from '../i18n';
+import { themedHeader } from '../utils/navigation';
+import { withTheme } from '../theme';
+import { themes, SWITCH_TRACK_COLOR } from '../constants/colors';
+import sharedStyles from './Styles';
+import StatusBar from '../containers/StatusBar';
+import Separator from '../containers/Separator';
+import ListItem from '../containers/ListItem';
+import { CustomIcon } from '../lib/Icons';
+import database from '../lib/database';
+import { connect } from 'react-redux';
+
+const DEFAULT_AUTO_LOCK = [
+ {
+ title: 'After 1 minute',
+ value: 60
+ },
+ {
+ title: 'After 5 minutes',
+ value: 300
+ },
+ {
+ title: 'After 15 minutes',
+ value: 900
+ },
+ {
+ title: 'After 30 minutes',
+ value: 1800
+ },
+ {
+ title: 'After 1 hour',
+ value: 3600
+ }
+];
+
+const styles = StyleSheet.create({
+ listPadding: {
+ paddingVertical: 36
+ },
+ info: {
+ paddingTop: 25,
+ paddingBottom: 18,
+ paddingHorizontal: 16
+ },
+ infoText: {
+ fontSize: 16,
+ ...sharedStyles.textRegular
+ },
+ sectionSeparatorBorder: {
+ ...sharedStyles.separatorVertical,
+ height: 36
+ },
+});
+
+const SectionSeparator = React.memo(({ theme }) => (
+
+));
+SectionSeparator.propTypes = {
+ theme: PropTypes.string
+};
+
+class ScreenLockConfigView extends React.Component {
+ static navigationOptions = ({ screenProps }) => ({
+ title: I18n.t('Screen_lock'),
+ ...themedHeader(screenProps.theme)
+ })
+
+ static propTypes = {
+ theme: PropTypes.string
+ }
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ autoLock: false,
+ autoLockTime: null,
+ supported: []
+ };
+ this.init();
+ }
+
+ init = async() => {
+ const { server } = this.props;
+ const serversDB = database.servers;
+ const serversCollection = serversDB.collections.get('servers');
+ try {
+ this.serverRecord = await serversCollection.find(server);
+ this.setState({ autoLock: this.serverRecord?.autoLock, autoLockTime: this.serverRecord?.autoLockTime });
+ } catch (error) {
+ // TODO: raise error in case server wasn't found and pop?
+ }
+ }
+
+ save = async() => {
+ const { autoLock, autoLockTime } = this.state;
+ const serversDB = database.servers;
+ await serversDB.action(async() => {
+ await this.serverRecord?.update((record) => {
+ record.autoLock = autoLock;
+ record.autoLockTime = autoLockTime;
+ });
+ });
+ }
+
+ autoLock = () => {
+ this.setState(({ autoLock }) => ({ autoLock: !autoLock }), () => this.save());
+ }
+
+ isSelected = (value) => {
+ const { autoLockTime } = this.state;
+ return autoLockTime === value;
+ }
+
+ changeAutoLockTime = (autoLockTime) => {
+ this.setState({ autoLockTime }, () => this.save());
+ }
+
+ renderSeparator = () => {
+ const { theme } = this.props;
+ return ;
+ }
+
+ renderIcon = () => {
+ const { theme } = this.props;
+ return ;
+ }
+
+ renderItem = ({ item }) => {
+ const { theme } = this.props;
+ const { title, value } = item;
+ return (
+ <>
+ this.changeAutoLockTime(value)}
+ right={this.isSelected(value) ? this.renderIcon : null}
+ theme={theme}
+ />
+
+ >
+ );
+ }
+
+ renderSwitch = () => {
+ // const { allowCrashReport } = this.props;
+ const { autoLock } = this.state;
+ return (
+
+ );
+ }
+
+ renderAutoLockItems = () => {
+ const { autoLock, supported } = this.state;
+ const { theme } = this.props;
+ if (!autoLock) {
+ return null;
+ }
+ return (
+ <>
+
+
+ {autoLock ? DEFAULT_AUTO_LOCK.concat(supported).map(item => this.renderItem({ item })) : null}
+ >
+ );
+ }
+
+ render() {
+ const { autoLock, supported } = this.state;
+ const { theme } = this.props;
+ return (
+
+
+ item.value}
+ contentContainerStyle={styles.listPadding}
+ >
+
+ this.renderSwitch()}
+ theme={theme}
+ />
+
+ {this.renderAutoLockItems()}
+
+
+ );
+ }
+}
+
+const mapStateToProps = state => ({
+ server: state.server.server
+});
+
+export default connect(mapStateToProps)(withTheme(ScreenLockConfigView));
diff --git a/app/views/SettingsView/index.js b/app/views/SettingsView/index.js
index 5df529332..b1bdf8659 100644
--- a/app/views/SettingsView/index.js
+++ b/app/views/SettingsView/index.js
@@ -273,6 +273,15 @@ class SettingsView extends React.Component {
right={this.renderDisclosure}
theme={theme}
/>
+
+ this.navigateToScreen('ScreenLockConfigView')}
+ // testID='settings-view-theme'
+ right={this.renderDisclosure}
+ theme={theme}
+ />