update pause playback when timer completes
This commit is contained in:
committed by
Lei Nelissen
parent
9cbc5a26ba
commit
85383f2447
@@ -33,18 +33,18 @@ export function SettingsList() {
|
||||
const { sleepTime } = useTypedSelector(state => state.settings);
|
||||
|
||||
const getTime = () => {
|
||||
let hours = 0;
|
||||
let minutes = 0;
|
||||
if (!Number.isNaN(sleepTime)) {
|
||||
const hours = Math.round(sleepTime / 3600);
|
||||
hours = Math.round(sleepTime / 3600);
|
||||
const timeRemaining = sleepTime % 3600;
|
||||
let minutes = 0;
|
||||
|
||||
if (timeRemaining > 60) {
|
||||
if (timeRemaining >= 60) {
|
||||
minutes = Math.round(timeRemaining / 60);
|
||||
}
|
||||
return `${hours} hrs ${minutes} min`;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return `${hours} hrs ${minutes} min`;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Text } from '@/components/Typography';
|
||||
import { InputContainer } from '../../components/Input';
|
||||
import Input from '@/components/Input';
|
||||
import useDefaultStyles from '@/components/Colors';
|
||||
import { setSleepTime } from '@/store/settings/actions';
|
||||
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';
|
||||
@@ -16,12 +16,16 @@ 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';
|
||||
|
||||
function Timer() {
|
||||
const { sleepTime } = useTypedSelector(state => state.settings);
|
||||
const enabledSleeper = useTypedSelector((state) => state.settings.enabledSleeper);
|
||||
|
||||
const [minutes, setMinutes] = useState<number>();
|
||||
const [hours, setHours] = useState<number>();
|
||||
const [enableSleeper, setEnableSleeper] = useState<boolean>(enabledSleeper);
|
||||
|
||||
const timerStyles = generateTimerStyles();
|
||||
|
||||
@@ -37,51 +41,72 @@ function Timer() {
|
||||
}, [navigation, dispatch]);
|
||||
|
||||
const getTime = () => {
|
||||
let hours = 0;
|
||||
let minutes = 0;
|
||||
if (!Number.isNaN(sleepTime)) {
|
||||
const hours = Math.round(sleepTime / 3600);
|
||||
hours = Math.round(sleepTime / 3600);
|
||||
const timeRemaining = sleepTime % 3600;
|
||||
let minutes = 0;
|
||||
|
||||
if (timeRemaining > 60) {
|
||||
if (timeRemaining >= 60) {
|
||||
minutes = Math.round(timeRemaining / 60);
|
||||
}
|
||||
return `${hours} hrs ${minutes} min`;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return `${hours} hrs ${minutes} min`;
|
||||
}
|
||||
|
||||
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]);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<InputContainer>
|
||||
<Text>Set Sleep Timer. Time Set Previously: {getTime()}</Text>
|
||||
<View style={timerStyles.timer}>
|
||||
<View style={timerStyles.timeInput}>
|
||||
<Text>H:</Text>
|
||||
<Input
|
||||
placeholder='60'
|
||||
editable={true}
|
||||
style={timerStyles.input}
|
||||
keyboardType='phone-pad'
|
||||
onChangeText={(value: string) => {
|
||||
setSleeper(parseInt(value), 'Hours');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={timerStyles.timeInput}>
|
||||
<Text>M:</Text>
|
||||
<Input
|
||||
placeholder='60'
|
||||
editable={true}
|
||||
style={timerStyles.input}
|
||||
keyboardType='phone-pad'
|
||||
onChangeText={(value: string) => {
|
||||
setSleeper(parseInt(value), 'Minutes');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={timerStyles.checkbox}>
|
||||
<CheckBox
|
||||
value={enableSleeper}
|
||||
onValueChange={(value) => handleEnabledSleeper(value)}
|
||||
/>
|
||||
<Text> Enable Sleeper</Text>
|
||||
</View>
|
||||
<View style={enabledSleeper ? timerStyles.timerSetting : timerStyles.timerSettingsDisabled}>
|
||||
<View style={timerStyles.timer}>
|
||||
<View style={timerStyles.timeInput}>
|
||||
<Text>H:</Text>
|
||||
<Input
|
||||
placeholder='60'
|
||||
editable={enabledSleeper}
|
||||
style={timerStyles.input}
|
||||
keyboardType='phone-pad'
|
||||
onChangeText={(value: string) => {
|
||||
setSleeper(parseInt(value), 'Hours');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={timerStyles.timeInput}>
|
||||
<Text>M:</Text>
|
||||
<Input
|
||||
placeholder='60'
|
||||
editable={enabledSleeper}
|
||||
style={timerStyles.input}
|
||||
keyboardType='phone-pad'
|
||||
onChangeText={(value: string) => {
|
||||
setSleeper(parseInt(value), 'Minutes');
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<Text>Set this to automatically stop the audio when time runs out.</Text>
|
||||
</View>
|
||||
<Text>Set this to automatically stop the audio when time runs out.</Text>
|
||||
</InputContainer>
|
||||
</Container>
|
||||
);
|
||||
|
||||
@@ -16,6 +16,18 @@ export function generateTimerStyles() {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 3
|
||||
},
|
||||
checkbox: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
},
|
||||
timerSetting: {
|
||||
marginStart: 30
|
||||
},
|
||||
timerSettingsDisabled: {
|
||||
color: '#cbcbcb',
|
||||
marginStart: 30
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -63,7 +63,8 @@ const persistConfig: PersistConfig<Omit<AppState, '_persist'>> = {
|
||||
...state.settings,
|
||||
enableSleepTimer: false,
|
||||
sleepTime: 0,
|
||||
remainingSleepTime: 0
|
||||
remainingSleepTime: 0,
|
||||
enabledSleeper: false
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
@@ -10,3 +10,4 @@ export const setColorScheme = createAction<ColorScheme>('SET_COLOR_SCHEME');
|
||||
export const setSleepTime = createAction<number>('SET_SLEEP_TIME');
|
||||
export const setEnableSleepTimer = createAction<boolean>('SET_ENABLE_SLEEP_TIMER');
|
||||
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 { setReceivedErrorReportingAlert, setBitrate, setJellyfinCredentials, setOnboardingStatus, setEnablePlaybackReporting, setColorScheme, setSleepTime, setEnableSleepTimer, setRemainingSleepTime } from './actions';
|
||||
import { setReceivedErrorReportingAlert, setBitrate, setJellyfinCredentials, setOnboardingStatus, setEnablePlaybackReporting, setColorScheme, setSleepTime, setEnableSleepTimer, setRemainingSleepTime, setEnabledSleeper } from './actions';
|
||||
import { ColorScheme } from './types';
|
||||
|
||||
interface State {
|
||||
@@ -15,6 +15,7 @@ interface State {
|
||||
enablePlaybackReporting: boolean;
|
||||
colorScheme: ColorScheme;
|
||||
sleepTime: number;
|
||||
enabledSleeper: boolean
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
@@ -24,6 +25,7 @@ const initialState: State = {
|
||||
enablePlaybackReporting: true,
|
||||
colorScheme: ColorScheme.System,
|
||||
sleepTime: 60,
|
||||
enabledSleeper: false,
|
||||
};
|
||||
|
||||
const settings = createReducer(initialState, builder => {
|
||||
@@ -63,6 +65,10 @@ const settings = createReducer(initialState, builder => {
|
||||
...state,
|
||||
remainingSleepTime: action.payload,
|
||||
}));
|
||||
builder.addCase(setEnabledSleeper, (state, action) => ({
|
||||
...state,
|
||||
enabledSleeper: action.payload,
|
||||
}));
|
||||
});
|
||||
|
||||
export default settings;
|
||||
@@ -8,10 +8,15 @@
|
||||
*/
|
||||
|
||||
import TrackPlayer, { Event, State } from 'react-native-track-player';
|
||||
import store from '@/store';
|
||||
import store, { useTypedSelector } 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();
|
||||
});
|
||||
@@ -59,6 +64,11 @@ export default async function() {
|
||||
if (settings.enablePlaybackReporting) {
|
||||
sendPlaybackEvent('/Sessions/Playing/Progress', settings.jellyfin);
|
||||
}
|
||||
|
||||
// regularly check if sleeper is enabled, then disable the timer
|
||||
if (!settings.enabledSleeper) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
});
|
||||
|
||||
TrackPlayer.addEventListener(Event.PlaybackState, (event) => {
|
||||
@@ -72,6 +82,24 @@ 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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user