0% found this document useful (0 votes)
23 views8 pages

Blackbox Output Code UVHX4VYUQS

This document outlines a React Native application that functions as an interval timer, allowing users to manage work and rest intervals. It includes features for saving presets, toggling dark mode, and playing notification sounds. The app utilizes various components for displaying timers, editing intervals, and managing settings, while also incorporating async storage for data persistence.

Uploaded by

tarzenwoods
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views8 pages

Blackbox Output Code UVHX4VYUQS

This document outlines a React Native application that functions as an interval timer, allowing users to manage work and rest intervals. It includes features for saving presets, toggling dark mode, and playing notification sounds. The app utilizes various components for displaying timers, editing intervals, and managing settings, while also incorporating async storage for data persistence.

Uploaded by

tarzenwoods
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import React, { useState, useEffect, useRef } from 'react';

import {
StyleSheet,
View,
Text,
TouchableOpacity,
ScrollView,
Modal,
Switch,
Alert,
Platform,
Vibration
} from 'react-native';
import { Audio } from 'expo-av';
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
import AsyncStorage from '@react-native-async-storage/async-storage';

// Components
import TimerDisplay from './components/TimerDisplay';
import IntervalList from './components/IntervalList';
import PresetManager from './components/PresetManager';
import SettingsModal from './components/SettingsModal';
import IntervalEditor from './components/IntervalEditor';

const App = () => {


const [timerState, setTimerState] = useState('idle'); // idle, running, paused
const [currentInterval, setCurrentInterval] = useState(0);
const [timeLeft, setTimeLeft] = useState(0);
const [intervals, setIntervals] = useState([
{ id: 1, duration: 300, label: 'Work', color: '#34C759', sound: 'beep' },
{ id: 2, duration: 60, label: 'Rest', color: '#FF3B30', sound: 'beep' }
]);
const [presets, setPresets] = useState([]);
const [selectedPreset, setSelectedPreset] = useState(null);
const [isDarkMode, setIsDarkMode] = useState(false);
const [showSettings, setShowSettings] = useState(false);
const [showEditor, setShowEditor] = useState(false);
const [editingInterval, setEditingInterval] = useState(null);

const timerRef = useRef(null);


const soundRef = useRef(null);

const colors = {
light: {
background: '#FFFFFF',
card: '#F2F2F7',
text: '#000000',
primary: '#007AFF',
secondary: '#8E8E93'
},
dark: {
background: '#000000',
card: '#1C1C1E',
text: '#FFFFFF',
primary: '#0A84FF',
secondary: '#8E8E93'
}
};
const theme = isDarkMode ? [Link] : [Link];

useEffect(() => {
loadPresets();
loadSettings();
if ([Link] > 0) {
setTimeLeft(intervals[0].duration);
}
}, []);

useEffect(() => {
return () => {
if ([Link]) clearInterval([Link]);
if ([Link]) [Link]();
};
}, []);

const loadPresets = async () => {


try {
const savedPresets = await [Link]('timerPresets');
if (savedPresets) {
setPresets([Link](savedPresets));
}
} catch (error) {
[Link]('Error loading presets:', error);
}
};

const loadSettings = async () => {


try {
const settings = await [Link]('appSettings');
if (settings) {
const { darkMode } = [Link](settings);
setIsDarkMode(darkMode || false);
}
} catch (error) {
[Link]('Error loading settings:', error);
}
};

const saveSettings = async () => {


try {
await [Link]('appSettings', [Link]({
darkMode: isDarkMode
}));
} catch (error) {
[Link]('Error saving settings:', error);
}
};

const startTimer = () => {


if (timerState === 'running') return;

setTimerState('running');
[Link] = setInterval(() => {
setTimeLeft(prev => {
if (prev <= 1) {
nextInterval();
return 0;
}
return prev - 1;
});
}, 1000);
};

const pauseTimer = () => {


if ([Link]) {
clearInterval([Link]);
}
setTimerState('paused');
};

const resetTimer = () => {


if ([Link]) {
clearInterval([Link]);
}
setTimerState('idle');
setCurrentInterval(0);
setTimeLeft(intervals[0]?.duration || 0);
};

const nextInterval = async () => {


if (currentInterval < [Link] - 1) {
const nextIndex = currentInterval + 1;
setCurrentInterval(nextIndex);
setTimeLeft(intervals[nextIndex].duration);

// Play sound and/or vibrate


await playNotification(intervals[nextIndex].sound);
} else {
// End of all intervals
clearInterval([Link]);
setTimerState('completed');
[Link]('Complete!', 'All intervals completed!');
}
};

const prevInterval = () => {


if (currentInterval > 0) {
const prevIndex = currentInterval - 1;
setCurrentInterval(prevIndex);
setTimeLeft(intervals[prevIndex].duration);
}
};

const playNotification = async (soundType) => {


if (soundType === 'vibrate') {
[Link](500);
} else if (soundType === 'beep') {
try {
const { sound } = await [Link](
require('./assets/beep.mp3')
);
[Link] = sound;
await [Link]();
} catch (error) {
[Link]('Error playing sound:', error);
[Link](500);
}
}
};

const formatTime = (seconds) => {


const mins = [Link](seconds / 60);
const secs = seconds % 60;
return `${[Link]().padStart(2, '0')}:${[Link]().padStart(2,
'0')}`;
};

const addInterval = (interval) => {


const newInterval = {
...interval,
id: [Link]()
};
setIntervals(prev => [...prev, newInterval]);
};

const updateInterval = (updatedInterval) => {


setIntervals(prev => [Link](i =>
[Link] === [Link] ? updatedInterval : i
));
};

const deleteInterval = (id) => {


setIntervals(prev => [Link](i => [Link] !== id));
};

const savePreset = async (name) => {


const newPreset = {
id: [Link](),
name,
intervals: [...intervals],
createdAt: new Date().toISOString()
};

const updatedPresets = [...presets, newPreset];


setPresets(updatedPresets);

try {
await [Link]('timerPresets', [Link](updatedPresets));
} catch (error) {
[Link]('Error saving preset:', error);
}
};

const loadPreset = (preset) => {


setIntervals([...[Link]]);
setSelectedPreset([Link]);
resetTimer();
};

const deletePreset = async (id) => {


const updatedPresets = [Link](p => [Link] !== id);
setPresets(updatedPresets);

try {
await [Link]('timerPresets', [Link](updatedPresets));
} catch (error) {
[Link]('Error deleting preset:', error);
}
};

const exportPresets = async () => {


try {
const jsonString = [Link](presets, null, 2);
const fileUri = [Link] + 'interval_timer_presets.json';
await [Link](fileUri, jsonString);

if ([Link] === 'ios') {


await [Link](fileUri);
} else {
await [Link](fileUri, {
mimeType: 'application/json',
dialogTitle: 'Export Timer Presets'
});
}
} catch (error) {
[Link]('Error exporting presets:', error);
[Link]('Error', 'Failed to export presets');
}
};

const importPresets = async (jsonData) => {


try {
const parsedData = [Link](jsonData);
if ([Link](parsedData)) {
setPresets(parsedData);
await [Link]('timerPresets', [Link](parsedData));
[Link]('Success', 'Presets imported successfully');
} else {
throw new Error('Invalid format');
}
} catch (error) {
[Link]('Error importing presets:', error);
[Link]('Error', 'Failed to import presets. Invalid format.');
}
};

return (
<View style={[[Link], { backgroundColor: [Link] }]}>
<View style={[[Link], { backgroundColor: [Link] }]}>
<Text style={[[Link], { color: [Link] }]}>INTVL
Timer</Text>
<TouchableOpacity
onPress={() => setShowSettings(true)}
style={[Link]}
>
<Text style={[[Link], { color: [Link] }]}>⚙️</Text>
</TouchableOpacity>
</View>

<ScrollView style={[Link]}>
<TimerDisplay
timeLeft={formatTime(timeLeft)}
currentInterval={intervals[currentInterval]}
theme={theme}
isDarkMode={isDarkMode}
/>

<View style={[[Link], { backgroundColor: [Link] }]}>


<TouchableOpacity
style={[[Link], { backgroundColor: [Link] }]}
onPress={prevInterval}
disabled={currentInterval === 0}
>
<Text style={[Link]}>⏮</Text>
</TouchableOpacity>

{timerState === 'running' ? (


<TouchableOpacity
style={[[Link], [Link], { backgroundColor:
'#FF9500' }]}
onPress={pauseTimer}
>
<Text style={[Link]}>⏸</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={[[Link], [Link], { backgroundColor:
[Link] }]}
onPress={startTimer}
>
<Text style={[Link]}>▶️</Text>
</TouchableOpacity>
)}

<TouchableOpacity
style={[[Link], { backgroundColor: [Link] }]}
onPress={nextInterval}
disabled={currentInterval === [Link] - 1}
>
<Text style={[Link]}>⏭</Text>
</TouchableOpacity>

<TouchableOpacity
style={[[Link], { backgroundColor: '#FF3B30' }]}
onPress={resetTimer}
>
<Text style={[Link]}>⏹</Text>
</TouchableOpacity>
</View>

<IntervalList
intervals={intervals}
currentInterval={currentInterval}
onEdit={setEditingInterval}
onAdd={() => setEditingInterval({})}
onDelete={deleteInterval}
theme={theme}
/>

<PresetManager
presets={presets}
selectedPreset={selectedPreset}
onSelect={loadPreset}
onSave={savePreset}
onDelete={deletePreset}
onExport={exportPresets}
onImport={importPresets}
theme={theme}
/>
</ScrollView>

<SettingsModal
visible={showSettings}
onClose={() => setShowSettings(false)}
isDarkMode={isDarkMode}
onDarkModeToggle={(value) => {
setIsDarkMode(value);
saveSettings();
}}
theme={theme}
/>

<IntervalEditor
visible={showEditor}
onClose={() => setShowEditor(false)}
interval={editingInterval}
onSave={(interval) => {
if ([Link]) {
updateInterval(interval);
} else {
addInterval(interval);
}
setShowEditor(false);
}}
theme={theme}
/>
</View>
);
};

const styles = [Link]({


container: {
flex: 1,
paddingTop: [Link] === 'ios' ? 50 : 30,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 20,
borderBottomLeftRadius: 20,
borderBottomRightRadius: 20,
elevation: 4,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
},
headerTitle: {
fontSize: 24,
fontWeight: 'bold',
},
settingsButton: {
padding: 8,
},
settingsText: {
fontSize: 20,
},
content: {
flex: 1,
padding: 20,
},
controls: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
padding: 20,
borderRadius: 20,
marginVertical: 20,
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
controlButton: {
width: 60,
height: 60,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
},
startButton: {
width: 70,
height: 70,
borderRadius: 35,
},
pauseButton: {
width: 70,
height: 70,
borderRadius: 35,
},
controlText: {
color: '#FFFFFF',
fontSize: 20,
fontWeight: 'bold',
},
});

export default App;

You might also like