diff --git a/package-lock.json b/package-lock.json
index 8b219fa..6276c59 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.11",
"@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-navigation/bottom-tabs": "^6.4.0",
"@react-navigation/elements": "^1.3.17",
@@ -40,10 +40,10 @@
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "^2.9.0",
"react-native-localize": "^2.2.4",
+ "react-native-modal-datetime-picker": "^17.0.0",
"react-native-reanimated": "^3.6.2",
"react-native-safe-area-context": "^4.4.1",
"react-native-screens": "^3.18.2",
- "react-native-select-dropdown": "^3.3.4",
"react-native-shadow-2": "^7.0.6",
"react-native-skia": "^0.0.1",
"react-native-svg": "^13.5.0",
@@ -2678,21 +2678,6 @@
"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": {
"version": "10.2.6",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
@@ -2981,6 +2966,14 @@
"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": {
"version": "3.2.0",
"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": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
@@ -13785,11 +13790,6 @@
"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": {
"version": "7.0.6",
"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",
"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": {
"version": "10.2.6",
"resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.2.6.tgz",
@@ -18438,6 +18433,14 @@
"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": {
"version": "3.2.0",
"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",
"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": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.6.2.tgz",
@@ -26705,11 +26716,6 @@
"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": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/react-native-shadow-2/-/react-native-shadow-2-7.0.6.tgz",
diff --git a/package.json b/package.json
index 2e0eed1..be84c11 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"dependencies": {
"@react-native-async-storage/async-storage": "^1.17.11",
"@react-native-community/blur": "^4.3.0",
+ "@react-native-community/datetimepicker": "^7.4.1",
"@react-native-community/netinfo": "^9.3.6",
"@react-navigation/bottom-tabs": "^6.4.0",
"@react-navigation/elements": "^1.3.17",
@@ -44,6 +45,7 @@
"react-native-gesture-handler": "^2.9.0",
"react-native-localize": "^2.2.4",
"react-native-reanimated": "^3.6.2",
+ "react-native-modal-datetime-picker": "^17.0.0",
"react-native-safe-area-context": "^4.4.1",
"react-native-screens": "^3.18.2",
"react-native-shadow-2": "^7.0.6",
diff --git a/src/screens/Settings/index.tsx b/src/screens/Settings/index.tsx
index 0385548..ac789b5 100644
--- a/src/screens/Settings/index.tsx
+++ b/src/screens/Settings/index.tsx
@@ -55,7 +55,7 @@ export default function Settings() {
}}>
-
+
diff --git a/src/screens/Settings/stacks/timer/Timer.tsx b/src/screens/Settings/stacks/timer/Timer.tsx
index 8696f52..12326ec 100644
--- a/src/screens/Settings/stacks/timer/Timer.tsx
+++ b/src/screens/Settings/stacks/timer/Timer.tsx
@@ -2,114 +2,72 @@ import React, { useCallback, useState } from 'react';
import Container from '../../components/Container';
import { Text } from '@/components/Typography';
import { InputContainer } from '../../components/Input';
-import Input from '@/components/Input';
-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 { useTimeStyles } from './styles';
import { Switch } from 'react-native-gesture-handler';
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() {
- const { sleepTime } = useTypedSelector(state => state.settings);
- const enabledSleeper = useTypedSelector((state) => state.settings.enabledSleeper);
+ const [show, setShow] = useState(false);
+ const { dateTime } = useTypedSelector(state => state.settings);
+ const [date, setDate] = useState(dateTime === undefined ? 'Set Time' : dateTime.toString());
- const [minutes, setMinutes] = useState();
- const [hours, setHours] = useState();
- const [enableSleeper, setEnableSleeper] = useState(enabledSleeper);
+ const timerStyles = useTimeStyles();
+ const { enableSleepTime } = useTypedSelector(state => state.settings);
- const timerStyles = generateTimerStyles();
-
- const navigation = useNavigation();
const dispatch = useDispatch();
- const setSleeper = useCallback((value: number, timeType: string) => {
- if (timeType == 'Hours' && value > 0) {
- dispatch(setSleepTime(value * 3600));
- } else if (timeType == 'Minutes' && value > 0) {
- dispatch(setSleepTime(value * 60));
- }
- }, [navigation, dispatch]);
-
- const getTime = () => {
- let hours = 0;
- let minutes = 0;
- if (!Number.isNaN(sleepTime)) {
- 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) => {
+ dispatch(setEnableSleepTime(value));
+ }, [dispatch]);
+
+ const handleConfirm = (date: Date) => {
+ setShow(false);
+ setDate(date.toString());
+ dispatch(setDateTime(date));
};
- const handleEnabledSleeper = useCallback((value: boolean) => {
- dispatch(setEnabledSleeper(value));
- setEnableSleeper(value);
-
- // If value is true sleeper has been enabled, pause then play tack
- // to trigger play state and start sleeper timer
- if (value) {
- TrackPlayer.pause();
- TrackPlayer.play();
- }
- }, [dispatch]);
+ const showDateTimePicker = () => {
+ setShow(!show);
+ };
+ const handleCancelDatePicker = () => {
+ setShow(false);
+ };
+
return (
- Set Sleep Timer. Time Set Previously: {getTime()}
+ {'Set Sleep Time.'}
handleEnabledSleeper(value)}
/>
- Enable Sleeper
+ {'Enable Timer'}
-
-
-
- H:
- {
- setSleeper(parseInt(value), 'Hours');
- }}
- />
-
-
- M:
- {
- setSleeper(parseInt(value), 'Minutes');
- }}
- />
-
+
+
+ {'Set Time'}
+
- Set this to automatically stop the audio when time runs out.
+ {'Set this to automatically stop the audio when time runs out.'}
+
);
diff --git a/src/screens/Settings/stacks/timer/styles.tsx b/src/screens/Settings/stacks/timer/styles.tsx
index d1f93b7..df93286 100644
--- a/src/screens/Settings/stacks/timer/styles.tsx
+++ b/src/screens/Settings/stacks/timer/styles.tsx
@@ -1,8 +1,7 @@
-import useDefaultStyles from "@/components/Colors";
-import { ColorScheme } from "@/store/settings/types";
-import { StyleSheet } from "react-native";
+import useDefaultStyles from '@/components/Colors';
+import { StyleSheet } from 'react-native';
-export function generateTimerStyles() {
+export function useTimeStyles() {
const styles = useDefaultStyles();
return StyleSheet.create({
@@ -23,11 +22,17 @@ export function generateTimerStyles() {
alignItems: 'center'
},
timerSetting: {
- marginStart: 30
+ marginStart: 10
},
timerSettingsDisabled: {
color: '#cbcbcb',
- marginStart: 30
+ marginStart: 10
+ },
+ showDateTime: {
+ display: 'flex'
+ },
+ hideDateTime: {
+ display: 'none'
}
- })
+ });
}
\ No newline at end of file
diff --git a/src/store/index.ts b/src/store/index.ts
index 71e8134..1ae9d93 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -61,10 +61,8 @@ const persistConfig: PersistConfig> = {
...state,
settings: {
...state.settings,
- enableSleepTimer: false,
- sleepTime: 0,
- remainingSleepTime: 0,
- enabledSleeper: false
+ enableSleepTime: false,
+ dateTime: Date
}
};
},
diff --git a/src/store/settings/actions.ts b/src/store/settings/actions.ts
index 97ea6a1..0e3ea26 100644
--- a/src/store/settings/actions.ts
+++ b/src/store/settings/actions.ts
@@ -7,7 +7,6 @@ export const setOnboardingStatus = createAction('SET_ONBOARDING_STATUS'
export const setReceivedErrorReportingAlert = createAction('SET_RECEIVED_ERROR_REPORTING_ALERT');
export const setEnablePlaybackReporting = createAction('SET_ENABLE_PLAYBACK_REPORTING');
export const setColorScheme = createAction('SET_COLOR_SCHEME');
-export const setSleepTime = createAction('SET_SLEEP_TIME');
-export const setEnableSleepTimer = createAction('SET_ENABLE_SLEEP_TIMER');
+export const setDateTime = createAction('SET_DATE_TIME');
+export const setEnableSleepTime = createAction('SET_ENABLE_SLEEP_TIME');
export const setRemainingSleepTime = createAction('SET_REMAINING_SLEEP_TIME');
-export const setEnabledSleeper = createAction('SET_ENABLE_SLEEPER');
diff --git a/src/store/settings/index.ts b/src/store/settings/index.ts
index 7248d44..bd44216 100644
--- a/src/store/settings/index.ts
+++ b/src/store/settings/index.ts
@@ -1,5 +1,5 @@
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';
interface State {
@@ -14,8 +14,8 @@ interface State {
hasReceivedErrorReportingAlert: boolean;
enablePlaybackReporting: boolean;
colorScheme: ColorScheme;
- sleepTime: number;
- enabledSleeper: boolean
+ dateTime?: Date;
+ enableSleepTime: boolean
}
const initialState: State = {
@@ -24,8 +24,8 @@ const initialState: State = {
hasReceivedErrorReportingAlert: false,
enablePlaybackReporting: true,
colorScheme: ColorScheme.System,
- sleepTime: 60,
- enabledSleeper: false,
+ dateTime: new Date(),
+ enableSleepTime: false
};
const settings = createReducer(initialState, builder => {
@@ -53,22 +53,18 @@ const settings = createReducer(initialState, builder => {
...state,
colorScheme: action.payload,
}));
- builder.addCase(setSleepTime, (state, action) => ({
+ builder.addCase(setDateTime, (state, action) => ({
...state,
- sleepTime: action.payload,
+ dateTime: action.payload,
}));
- builder.addCase(setEnableSleepTimer, (state, action) => ({
+ builder.addCase(setEnableSleepTime, (state, action) => ({
...state,
- enableSleepTimer: action.payload,
+ enableSleepTime: action.payload,
}));
builder.addCase(setRemainingSleepTime, (state, action) => ({
...state,
remainingSleepTime: action.payload,
}));
- builder.addCase(setEnabledSleeper, (state, action) => ({
- ...state,
- enabledSleeper: action.payload,
- }));
});
export default settings;
\ No newline at end of file
diff --git a/src/utility/PlaybackService.ts b/src/utility/PlaybackService.ts
index a170543..609e4ac 100644
--- a/src/utility/PlaybackService.ts
+++ b/src/utility/PlaybackService.ts
@@ -8,14 +8,10 @@
*/
import TrackPlayer, { Event, State } from 'react-native-track-player';
-import store, { useTypedSelector } from '@/store';
+import store from '@/store';
import { sendPlaybackEvent } from './JellyfinApi';
-import { useDispatch } from 'react-redux';
-import { setSleepTime } from '@/store/settings/actions';
-import internal from 'stream';
export default async function() {
- let interval = setInterval(() => {}, 0);
TrackPlayer.addEventListener(Event.RemotePlay, () => {
TrackPlayer.play();
@@ -65,9 +61,18 @@ export default async function() {
sendPlaybackEvent('/Sessions/Playing/Progress', settings.jellyfin);
}
- // regularly check if sleeper is enabled, then disable the timer
- if (!settings.enabledSleeper) {
- clearInterval(interval);
+ // regularly check if sleeper is enabled, pause the audio after 30 minutes.
+ if (settings.enableSleepTime && settings.dateTime !== undefined) {
+ 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);
}
}
-
- // 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);
- }
- }
});
}
\ No newline at end of file