Update with requirements: set date to trigger
This commit is contained in:
committed by
Lei Nelissen
parent
439235e6f8
commit
3d481a8f18
70
package-lock.json
generated
70
package-lock.json
generated
@@ -11,7 +11,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-async-storage/async-storage": "^1.17.11",
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
||||||
"@react-native-community/blur": "^4.3.0",
|
"@react-native-community/blur": "^4.3.0",
|
||||||
"@react-native-community/checkbox": "^0.5.13",
|
"@react-native-community/datetimepicker": "^7.4.1",
|
||||||
"@react-native-community/netinfo": "^9.3.6",
|
"@react-native-community/netinfo": "^9.3.6",
|
||||||
"@react-navigation/bottom-tabs": "^6.4.0",
|
"@react-navigation/bottom-tabs": "^6.4.0",
|
||||||
"@react-navigation/elements": "^1.3.17",
|
"@react-navigation/elements": "^1.3.17",
|
||||||
@@ -40,10 +40,10 @@
|
|||||||
"react-native-fs": "^2.20.0",
|
"react-native-fs": "^2.20.0",
|
||||||
"react-native-gesture-handler": "^2.9.0",
|
"react-native-gesture-handler": "^2.9.0",
|
||||||
"react-native-localize": "^2.2.4",
|
"react-native-localize": "^2.2.4",
|
||||||
|
"react-native-modal-datetime-picker": "^17.0.0",
|
||||||
"react-native-reanimated": "^3.6.2",
|
"react-native-reanimated": "^3.6.2",
|
||||||
"react-native-safe-area-context": "^4.4.1",
|
"react-native-safe-area-context": "^4.4.1",
|
||||||
"react-native-screens": "^3.18.2",
|
"react-native-screens": "^3.18.2",
|
||||||
"react-native-select-dropdown": "^3.3.4",
|
|
||||||
"react-native-shadow-2": "^7.0.6",
|
"react-native-shadow-2": "^7.0.6",
|
||||||
"react-native-skia": "^0.0.1",
|
"react-native-skia": "^0.0.1",
|
||||||
"react-native-svg": "^13.5.0",
|
"react-native-svg": "^13.5.0",
|
||||||
@@ -2678,21 +2678,6 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-community/checkbox": {
|
|
||||||
"version": "0.5.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/checkbox/-/checkbox-0.5.16.tgz",
|
|
||||||
"integrity": "sha512-j4fmWe77EAayGnKJ52BljlN8apLT3xjxG/pJOA6HZ4ew63FiXmnY7VtxTzmvDKgSPrETdQc2lmx5mdXTAufJnw==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "*",
|
|
||||||
"react-native": ">= 0.62",
|
|
||||||
"react-native-windows": ">=0.62"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"react-native-windows": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@react-native-community/cli": {
|
"node_modules/@react-native-community/cli": {
|
||||||
"version": "10.2.6",
|
"version": "10.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
|
||||||
@@ -2981,6 +2966,14 @@
|
|||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@react-native-community/datetimepicker": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-S7KdiWt0VgL93vy8sAlxPtyq8yNTRCNvoVJPkPlKzwuDY1Q5f+E0rsnNvfP0Y/UMhXAUnUo/THGR2qfrsJ9vNg==",
|
||||||
|
"dependencies": {
|
||||||
|
"invariant": "^2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@react-native-community/eslint-config": {
|
"node_modules/@react-native-community/eslint-config": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz",
|
||||||
@@ -13737,6 +13730,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-native-modal-datetime-picker": {
|
||||||
|
"version": "17.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-modal-datetime-picker/-/react-native-modal-datetime-picker-17.0.0.tgz",
|
||||||
|
"integrity": "sha512-/NFZMlugmd4WnKfNHjWQ5vz7PWfL2ECg8+hH0i661EqunT3+Oulp8a/0BCjNfCy2YEHargeII4T0ztLEe5MsfA==",
|
||||||
|
"dependencies": {
|
||||||
|
"prop-types": "^15.7.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@react-native-community/datetimepicker": ">=6.7.0",
|
||||||
|
"react-native": ">=0.65.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-native-reanimated": {
|
"node_modules/react-native-reanimated": {
|
||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
|
||||||
@@ -13785,11 +13790,6 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-native-select-dropdown": {
|
|
||||||
"version": "3.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-native-select-dropdown/-/react-native-select-dropdown-3.3.4.tgz",
|
|
||||||
"integrity": "sha512-Ld6BGGgCnbiv7uORAP+KnvDQiqeuqdlasKk9woJH9XtFMD44rwjKwelGzsDxFUM9hIAwZdac4UAFmOmXRaMeRg=="
|
|
||||||
},
|
|
||||||
"node_modules/react-native-shadow-2": {
|
"node_modules/react-native-shadow-2": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-shadow-2/-/react-native-shadow-2-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-shadow-2/-/react-native-shadow-2-7.0.6.tgz",
|
||||||
@@ -18185,11 +18185,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@react-native-community/blur/-/blur-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/blur/-/blur-4.3.0.tgz",
|
||||||
"integrity": "sha512-d6phh39kKcbZ4IluDftiVWqfeFOgjl1AbQWzN47x+hLKQ5GvQJ6QhRvgAuDZ+xbJksrbXgNpMjVYkjsbcVehxg=="
|
"integrity": "sha512-d6phh39kKcbZ4IluDftiVWqfeFOgjl1AbQWzN47x+hLKQ5GvQJ6QhRvgAuDZ+xbJksrbXgNpMjVYkjsbcVehxg=="
|
||||||
},
|
},
|
||||||
"@react-native-community/checkbox": {
|
|
||||||
"version": "0.5.16",
|
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/checkbox/-/checkbox-0.5.16.tgz",
|
|
||||||
"integrity": "sha512-j4fmWe77EAayGnKJ52BljlN8apLT3xjxG/pJOA6HZ4ew63FiXmnY7VtxTzmvDKgSPrETdQc2lmx5mdXTAufJnw=="
|
|
||||||
},
|
|
||||||
"@react-native-community/cli": {
|
"@react-native-community/cli": {
|
||||||
"version": "10.2.6",
|
"version": "10.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
|
||||||
@@ -18438,6 +18433,14 @@
|
|||||||
"joi": "^17.2.1"
|
"joi": "^17.2.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@react-native-community/datetimepicker": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-S7KdiWt0VgL93vy8sAlxPtyq8yNTRCNvoVJPkPlKzwuDY1Q5f+E0rsnNvfP0Y/UMhXAUnUo/THGR2qfrsJ9vNg==",
|
||||||
|
"requires": {
|
||||||
|
"invariant": "^2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@react-native-community/eslint-config": {
|
"@react-native-community/eslint-config": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-3.2.0.tgz",
|
||||||
@@ -26673,6 +26676,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-native-localize/-/react-native-localize-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-localize/-/react-native-localize-2.2.4.tgz",
|
||||||
"integrity": "sha512-gVmbyAEQQnBQ8vKlAQchFfIISeId3qT6Lc7LHmKF39nsYWX9KN4PHuG6Hk+7gduMI6IHKeZGKcLsOdh6wvN6cg=="
|
"integrity": "sha512-gVmbyAEQQnBQ8vKlAQchFfIISeId3qT6Lc7LHmKF39nsYWX9KN4PHuG6Hk+7gduMI6IHKeZGKcLsOdh6wvN6cg=="
|
||||||
},
|
},
|
||||||
|
"react-native-modal-datetime-picker": {
|
||||||
|
"version": "17.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-modal-datetime-picker/-/react-native-modal-datetime-picker-17.0.0.tgz",
|
||||||
|
"integrity": "sha512-/NFZMlugmd4WnKfNHjWQ5vz7PWfL2ECg8+hH0i661EqunT3+Oulp8a/0BCjNfCy2YEHargeII4T0ztLEe5MsfA==",
|
||||||
|
"requires": {
|
||||||
|
"prop-types": "^15.7.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-native-reanimated": {
|
"react-native-reanimated": {
|
||||||
"version": "3.6.2",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
|
||||||
@@ -26705,11 +26716,6 @@
|
|||||||
"warn-once": "^0.1.0"
|
"warn-once": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-native-select-dropdown": {
|
|
||||||
"version": "3.3.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-native-select-dropdown/-/react-native-select-dropdown-3.3.4.tgz",
|
|
||||||
"integrity": "sha512-Ld6BGGgCnbiv7uORAP+KnvDQiqeuqdlasKk9woJH9XtFMD44rwjKwelGzsDxFUM9hIAwZdac4UAFmOmXRaMeRg=="
|
|
||||||
},
|
|
||||||
"react-native-shadow-2": {
|
"react-native-shadow-2": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-shadow-2/-/react-native-shadow-2-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-shadow-2/-/react-native-shadow-2-7.0.6.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-async-storage/async-storage": "^1.17.11",
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
||||||
"@react-native-community/blur": "^4.3.0",
|
"@react-native-community/blur": "^4.3.0",
|
||||||
|
"@react-native-community/datetimepicker": "^7.4.1",
|
||||||
"@react-native-community/netinfo": "^9.3.6",
|
"@react-native-community/netinfo": "^9.3.6",
|
||||||
"@react-navigation/bottom-tabs": "^6.4.0",
|
"@react-navigation/bottom-tabs": "^6.4.0",
|
||||||
"@react-navigation/elements": "^1.3.17",
|
"@react-navigation/elements": "^1.3.17",
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
"react-native-gesture-handler": "^2.9.0",
|
"react-native-gesture-handler": "^2.9.0",
|
||||||
"react-native-localize": "^2.2.4",
|
"react-native-localize": "^2.2.4",
|
||||||
"react-native-reanimated": "^3.6.2",
|
"react-native-reanimated": "^3.6.2",
|
||||||
|
"react-native-modal-datetime-picker": "^17.0.0",
|
||||||
"react-native-safe-area-context": "^4.4.1",
|
"react-native-safe-area-context": "^4.4.1",
|
||||||
"react-native-screens": "^3.18.2",
|
"react-native-screens": "^3.18.2",
|
||||||
"react-native-shadow-2": "^7.0.6",
|
"react-native-shadow-2": "^7.0.6",
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export default function Settings() {
|
|||||||
}}>
|
}}>
|
||||||
<Stack.Screen name="SettingList" component={SettingsList} options={{ headerTitle: t('settings') }} />
|
<Stack.Screen name="SettingList" component={SettingsList} options={{ headerTitle: t('settings') }} />
|
||||||
<Stack.Screen name="Library" component={Library} options={{ headerTitle: t('jellyfin-library') }} />
|
<Stack.Screen name="Library" component={Library} options={{ headerTitle: t('jellyfin-library') }} />
|
||||||
<Stack.Screen name="Timer" component={Timer} options={{ headerTitle: "Set Sleep Timer" }} />
|
<Stack.Screen name="Timer" component={Timer} options={{ headerTitle: 'Set Sleep Timer' }} />
|
||||||
<Stack.Screen name="Cache" component={Cache} options={{ headerTitle: t('setting-cache') }} />
|
<Stack.Screen name="Cache" component={Cache} options={{ headerTitle: t('setting-cache') }} />
|
||||||
<Stack.Screen name="Sentry" component={Sentry} options={{ headerTitle: t('error-reporting') }} />
|
<Stack.Screen name="Sentry" component={Sentry} options={{ headerTitle: t('error-reporting') }} />
|
||||||
<Stack.Screen name="Playback Reporting" component={PlaybackReporting} options={{ headerTitle: t('playback-reporting')}} />
|
<Stack.Screen name="Playback Reporting" component={PlaybackReporting} options={{ headerTitle: t('playback-reporting')}} />
|
||||||
|
|||||||
@@ -2,114 +2,72 @@ import React, { useCallback, useState } from 'react';
|
|||||||
import Container from '../../components/Container';
|
import Container from '../../components/Container';
|
||||||
import { Text } from '@/components/Typography';
|
import { Text } from '@/components/Typography';
|
||||||
import { InputContainer } from '../../components/Input';
|
import { InputContainer } from '../../components/Input';
|
||||||
import Input from '@/components/Input';
|
import { useTimeStyles } from './styles';
|
||||||
import useDefaultStyles from '@/components/Colors';
|
|
||||||
import { setEnabledSleeper, setSleepTime } from '@/store/settings/actions';
|
|
||||||
import { useNavigation } from '@react-navigation/native';
|
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { ScrollView, ToastAndroid, View } from 'react-native';
|
|
||||||
import { generateTimerStyles } from './styles';
|
|
||||||
import { useTypedSelector } from '@/store';
|
|
||||||
import SelectableFilter from '@/screens/Search/stacks/Search/components/SelectableFilter';
|
|
||||||
import MicrophoneIcon from '@/assets/icons/microphone.svg';
|
|
||||||
import AlbumIcon from '@/assets/icons/collection.svg';
|
|
||||||
import TrackIcon from '@/assets/icons/note.svg';
|
|
||||||
import SelectDropdown from 'react-native-select-dropdown';
|
|
||||||
import { time } from 'console';
|
|
||||||
import CheckBox from '@react-native-community/checkbox';
|
|
||||||
import TrackPlayer from 'react-native-track-player';
|
|
||||||
import { Switch } from 'react-native-gesture-handler';
|
import { Switch } from 'react-native-gesture-handler';
|
||||||
import { SwitchContainer, SwitchLabel } from '../../components/Switch';
|
import { SwitchContainer, SwitchLabel } from '../../components/Switch';
|
||||||
import { t } from '@/localisation';
|
import Button from '@/components/Button';
|
||||||
|
import { View } from 'react-native';
|
||||||
|
import DateTimePickerModal from 'react-native-modal-datetime-picker';
|
||||||
|
import { useTypedSelector } from '@/store';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import { setDateTime, setEnableSleepTime } from '@/store/settings/actions';
|
||||||
|
|
||||||
function Timer() {
|
function Timer() {
|
||||||
const { sleepTime } = useTypedSelector(state => state.settings);
|
const [show, setShow] = useState<boolean>(false);
|
||||||
const enabledSleeper = useTypedSelector((state) => state.settings.enabledSleeper);
|
const { dateTime } = useTypedSelector(state => state.settings);
|
||||||
|
const [date, setDate] = useState<string>(dateTime === undefined ? 'Set Time' : dateTime.toString());
|
||||||
|
|
||||||
const [minutes, setMinutes] = useState<number>();
|
const timerStyles = useTimeStyles();
|
||||||
const [hours, setHours] = useState<number>();
|
const { enableSleepTime } = useTypedSelector(state => state.settings);
|
||||||
const [enableSleeper, setEnableSleeper] = useState<boolean>(enabledSleeper);
|
|
||||||
|
|
||||||
const timerStyles = generateTimerStyles();
|
|
||||||
|
|
||||||
const navigation = useNavigation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const setSleeper = useCallback((value: number, timeType: string) => {
|
const handleEnabledSleeper = useCallback((value: boolean) => {
|
||||||
if (timeType == 'Hours' && value > 0) {
|
dispatch(setEnableSleepTime(value));
|
||||||
dispatch(setSleepTime(value * 3600));
|
}, [dispatch]);
|
||||||
} else if (timeType == 'Minutes' && value > 0) {
|
|
||||||
dispatch(setSleepTime(value * 60));
|
|
||||||
}
|
|
||||||
}, [navigation, dispatch]);
|
|
||||||
|
|
||||||
const getTime = () => {
|
const handleConfirm = (date: Date) => {
|
||||||
let hours = 0;
|
setShow(false);
|
||||||
let minutes = 0;
|
setDate(date.toString());
|
||||||
if (!Number.isNaN(sleepTime)) {
|
dispatch(setDateTime(date));
|
||||||
hours = Math.round(sleepTime / 3600);
|
|
||||||
const timeRemaining = sleepTime % 3600;
|
|
||||||
|
|
||||||
if (timeRemaining >= 60) {
|
|
||||||
minutes = Math.round(timeRemaining / 60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${hours} hrs ${minutes} min`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEnabledSleeper = useCallback((value: boolean) => {
|
const showDateTimePicker = () => {
|
||||||
dispatch(setEnabledSleeper(value));
|
setShow(!show);
|
||||||
setEnableSleeper(value);
|
};
|
||||||
|
|
||||||
// If value is true sleeper has been enabled, pause then play tack
|
const handleCancelDatePicker = () => {
|
||||||
// to trigger play state and start sleeper timer
|
setShow(false);
|
||||||
if (value) {
|
};
|
||||||
TrackPlayer.pause();
|
|
||||||
TrackPlayer.play();
|
|
||||||
}
|
|
||||||
}, [dispatch]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<InputContainer>
|
<InputContainer>
|
||||||
<Text>Set Sleep Timer. Time Set Previously: {getTime()}</Text>
|
<Text>{'Set Sleep Time.'}</Text>
|
||||||
<SwitchContainer style={timerStyles.checkbox}>
|
<SwitchContainer style={timerStyles.checkbox}>
|
||||||
<Switch
|
<Switch
|
||||||
value={enableSleeper}
|
value={enableSleepTime}
|
||||||
onValueChange={(value) => handleEnabledSleeper(value)}
|
onValueChange={(value) => handleEnabledSleeper(value)}
|
||||||
/>
|
/>
|
||||||
<SwitchLabel>Enable Sleeper</SwitchLabel>
|
<SwitchLabel>{'Enable Timer'}</SwitchLabel>
|
||||||
</SwitchContainer>
|
</SwitchContainer>
|
||||||
<View style={enabledSleeper ? timerStyles.timerSetting : timerStyles.timerSettingsDisabled}>
|
<View style={enableSleepTime ? timerStyles.timerSetting : timerStyles.timerSettingsDisabled}>
|
||||||
<View style={timerStyles.timer}>
|
|
||||||
<View style={timerStyles.timeInput}>
|
<View style={timerStyles.timeInput}>
|
||||||
<Text>H:</Text>
|
<Text>{'Set Time'}</Text>
|
||||||
<Input
|
<Button
|
||||||
placeholder='60'
|
title={date}
|
||||||
editable={enabledSleeper}
|
onPress={showDateTimePicker}
|
||||||
style={timerStyles.input}
|
|
||||||
keyboardType='phone-pad'
|
|
||||||
onChangeText={(value: string) => {
|
|
||||||
setSleeper(parseInt(value), 'Hours');
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={timerStyles.timeInput}>
|
<Text>{'Set this to automatically stop the audio when time runs out.'}</Text>
|
||||||
<Text>M:</Text>
|
</View>
|
||||||
<Input
|
<DateTimePickerModal
|
||||||
placeholder='60'
|
isVisible={show}
|
||||||
editable={enabledSleeper}
|
mode='datetime'
|
||||||
style={timerStyles.input}
|
is24Hour={true}
|
||||||
keyboardType='phone-pad'
|
onConfirm={handleConfirm}
|
||||||
onChangeText={(value: string) => {
|
onCancel={handleCancelDatePicker}
|
||||||
setSleeper(parseInt(value), 'Minutes');
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<Text>Set this to automatically stop the audio when time runs out.</Text>
|
|
||||||
</View>
|
|
||||||
</InputContainer>
|
</InputContainer>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import useDefaultStyles from "@/components/Colors";
|
import useDefaultStyles from '@/components/Colors';
|
||||||
import { ColorScheme } from "@/store/settings/types";
|
import { StyleSheet } from 'react-native';
|
||||||
import { StyleSheet } from "react-native";
|
|
||||||
|
|
||||||
export function generateTimerStyles() {
|
export function useTimeStyles() {
|
||||||
const styles = useDefaultStyles();
|
const styles = useDefaultStyles();
|
||||||
|
|
||||||
return StyleSheet.create({
|
return StyleSheet.create({
|
||||||
@@ -23,11 +22,17 @@ export function generateTimerStyles() {
|
|||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
},
|
},
|
||||||
timerSetting: {
|
timerSetting: {
|
||||||
marginStart: 30
|
marginStart: 10
|
||||||
},
|
},
|
||||||
timerSettingsDisabled: {
|
timerSettingsDisabled: {
|
||||||
color: '#cbcbcb',
|
color: '#cbcbcb',
|
||||||
marginStart: 30
|
marginStart: 10
|
||||||
|
},
|
||||||
|
showDateTime: {
|
||||||
|
display: 'flex'
|
||||||
|
},
|
||||||
|
hideDateTime: {
|
||||||
|
display: 'none'
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
@@ -61,10 +61,8 @@ const persistConfig: PersistConfig<Omit<AppState, '_persist'>> = {
|
|||||||
...state,
|
...state,
|
||||||
settings: {
|
settings: {
|
||||||
...state.settings,
|
...state.settings,
|
||||||
enableSleepTimer: false,
|
enableSleepTime: false,
|
||||||
sleepTime: 0,
|
dateTime: Date
|
||||||
remainingSleepTime: 0,
|
|
||||||
enabledSleeper: false
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ export const setOnboardingStatus = createAction<boolean>('SET_ONBOARDING_STATUS'
|
|||||||
export const setReceivedErrorReportingAlert = createAction<void>('SET_RECEIVED_ERROR_REPORTING_ALERT');
|
export const setReceivedErrorReportingAlert = createAction<void>('SET_RECEIVED_ERROR_REPORTING_ALERT');
|
||||||
export const setEnablePlaybackReporting = createAction<boolean>('SET_ENABLE_PLAYBACK_REPORTING');
|
export const setEnablePlaybackReporting = createAction<boolean>('SET_ENABLE_PLAYBACK_REPORTING');
|
||||||
export const setColorScheme = createAction<ColorScheme>('SET_COLOR_SCHEME');
|
export const setColorScheme = createAction<ColorScheme>('SET_COLOR_SCHEME');
|
||||||
export const setSleepTime = createAction<number>('SET_SLEEP_TIME');
|
export const setDateTime = createAction<Date>('SET_DATE_TIME');
|
||||||
export const setEnableSleepTimer = createAction<boolean>('SET_ENABLE_SLEEP_TIMER');
|
export const setEnableSleepTime = createAction<boolean>('SET_ENABLE_SLEEP_TIME');
|
||||||
export const setRemainingSleepTime = createAction<number>('SET_REMAINING_SLEEP_TIME');
|
export const setRemainingSleepTime = createAction<number>('SET_REMAINING_SLEEP_TIME');
|
||||||
export const setEnabledSleeper = createAction<boolean>('SET_ENABLE_SLEEPER');
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { createReducer } from '@reduxjs/toolkit';
|
import { createReducer } from '@reduxjs/toolkit';
|
||||||
import { setReceivedErrorReportingAlert, setBitrate, setJellyfinCredentials, setOnboardingStatus, setEnablePlaybackReporting, setColorScheme, setSleepTime, setEnableSleepTimer, setRemainingSleepTime, setEnabledSleeper } from './actions';
|
import { setReceivedErrorReportingAlert, setBitrate, setJellyfinCredentials, setOnboardingStatus, setEnablePlaybackReporting, setColorScheme, setDateTime, setEnableSleepTime, setRemainingSleepTime } from './actions';
|
||||||
import { ColorScheme } from './types';
|
import { ColorScheme } from './types';
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@@ -14,8 +14,8 @@ interface State {
|
|||||||
hasReceivedErrorReportingAlert: boolean;
|
hasReceivedErrorReportingAlert: boolean;
|
||||||
enablePlaybackReporting: boolean;
|
enablePlaybackReporting: boolean;
|
||||||
colorScheme: ColorScheme;
|
colorScheme: ColorScheme;
|
||||||
sleepTime: number;
|
dateTime?: Date;
|
||||||
enabledSleeper: boolean
|
enableSleepTime: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: State = {
|
const initialState: State = {
|
||||||
@@ -24,8 +24,8 @@ const initialState: State = {
|
|||||||
hasReceivedErrorReportingAlert: false,
|
hasReceivedErrorReportingAlert: false,
|
||||||
enablePlaybackReporting: true,
|
enablePlaybackReporting: true,
|
||||||
colorScheme: ColorScheme.System,
|
colorScheme: ColorScheme.System,
|
||||||
sleepTime: 60,
|
dateTime: new Date(),
|
||||||
enabledSleeper: false,
|
enableSleepTime: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const settings = createReducer(initialState, builder => {
|
const settings = createReducer(initialState, builder => {
|
||||||
@@ -53,22 +53,18 @@ const settings = createReducer(initialState, builder => {
|
|||||||
...state,
|
...state,
|
||||||
colorScheme: action.payload,
|
colorScheme: action.payload,
|
||||||
}));
|
}));
|
||||||
builder.addCase(setSleepTime, (state, action) => ({
|
builder.addCase(setDateTime, (state, action) => ({
|
||||||
...state,
|
...state,
|
||||||
sleepTime: action.payload,
|
dateTime: action.payload,
|
||||||
}));
|
}));
|
||||||
builder.addCase(setEnableSleepTimer, (state, action) => ({
|
builder.addCase(setEnableSleepTime, (state, action) => ({
|
||||||
...state,
|
...state,
|
||||||
enableSleepTimer: action.payload,
|
enableSleepTime: action.payload,
|
||||||
}));
|
}));
|
||||||
builder.addCase(setRemainingSleepTime, (state, action) => ({
|
builder.addCase(setRemainingSleepTime, (state, action) => ({
|
||||||
...state,
|
...state,
|
||||||
remainingSleepTime: action.payload,
|
remainingSleepTime: action.payload,
|
||||||
}));
|
}));
|
||||||
builder.addCase(setEnabledSleeper, (state, action) => ({
|
|
||||||
...state,
|
|
||||||
enabledSleeper: action.payload,
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default settings;
|
export default settings;
|
||||||
@@ -8,14 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import TrackPlayer, { Event, State } from 'react-native-track-player';
|
import TrackPlayer, { Event, State } from 'react-native-track-player';
|
||||||
import store, { useTypedSelector } from '@/store';
|
import store from '@/store';
|
||||||
import { sendPlaybackEvent } from './JellyfinApi';
|
import { sendPlaybackEvent } from './JellyfinApi';
|
||||||
import { useDispatch } from 'react-redux';
|
|
||||||
import { setSleepTime } from '@/store/settings/actions';
|
|
||||||
import internal from 'stream';
|
|
||||||
|
|
||||||
export default async function() {
|
export default async function() {
|
||||||
let interval = setInterval(() => {}, 0);
|
|
||||||
|
|
||||||
TrackPlayer.addEventListener(Event.RemotePlay, () => {
|
TrackPlayer.addEventListener(Event.RemotePlay, () => {
|
||||||
TrackPlayer.play();
|
TrackPlayer.play();
|
||||||
@@ -65,9 +61,18 @@ export default async function() {
|
|||||||
sendPlaybackEvent('/Sessions/Playing/Progress', settings.jellyfin);
|
sendPlaybackEvent('/Sessions/Playing/Progress', settings.jellyfin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// regularly check if sleeper is enabled, then disable the timer
|
// regularly check if sleeper is enabled, pause the audio after 30 minutes.
|
||||||
if (!settings.enabledSleeper) {
|
if (settings.enableSleepTime && settings.dateTime !== undefined) {
|
||||||
clearInterval(interval);
|
const dateSet = new Date(settings.dateTime.toString());
|
||||||
|
const dateNow = new Date(Date.now());
|
||||||
|
const diff = Math.abs(dateSet.getMinutes() - dateNow.getMinutes());
|
||||||
|
|
||||||
|
console.log(`Difference: ${diff}`);
|
||||||
|
|
||||||
|
if (diff >= 30 && dateNow >= dateSet) {
|
||||||
|
console.log('Music Paused');
|
||||||
|
TrackPlayer.pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,24 +87,6 @@ export default async function() {
|
|||||||
sendPlaybackEvent('/Sessions/Playing/Stopped', settings.jellyfin);
|
sendPlaybackEvent('/Sessions/Playing/Stopped', settings.jellyfin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle is playback state is playing
|
|
||||||
if (event.state === State.Playing) {
|
|
||||||
const settings = store.getState().settings;
|
|
||||||
|
|
||||||
// Start timer is sleeper is enabled
|
|
||||||
if (settings.enabledSleeper) {
|
|
||||||
let time = settings.sleepTime;
|
|
||||||
interval = setInterval(() => {
|
|
||||||
if (time > 0) {
|
|
||||||
time -= 1;
|
|
||||||
} else {
|
|
||||||
TrackPlayer.pause();
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user