This commit is contained in:
86
src/screens/FocusScreen.js
Normal file
86
src/screens/FocusScreen.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import React from 'react';
|
||||
import { StatusBar, Text, TouchableOpacity, View } from 'react-native';
|
||||
import CountdownRow from '../components/CountdownRow';
|
||||
|
||||
export default function FocusScreen({
|
||||
styles,
|
||||
theme,
|
||||
screen,
|
||||
pinkMode,
|
||||
tuIsOver,
|
||||
tuCountdown,
|
||||
targetTime,
|
||||
timerDone,
|
||||
timerHr,
|
||||
timerMin,
|
||||
timerSec,
|
||||
onShowUI,
|
||||
}) {
|
||||
const pinkOutlineText = pinkMode
|
||||
? {
|
||||
borderColor: theme.pink,
|
||||
borderWidth: 2,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 8,
|
||||
}
|
||||
: {};
|
||||
|
||||
let focusContent = null;
|
||||
|
||||
if (screen === 'timeuntil') {
|
||||
focusContent = tuIsOver ? (
|
||||
<Text style={[styles.overText, styles.focusOverText, { color: pinkMode ? theme.pink : theme.danger }, pinkOutlineText]}>
|
||||
Time's Up!
|
||||
</Text>
|
||||
) : tuCountdown ? (
|
||||
<View style={styles.focusCountdown}>
|
||||
<Text style={[styles.focusLabel, { color: theme.subText }]}>
|
||||
until {targetTime?.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
||||
</Text>
|
||||
<CountdownRow
|
||||
styles={styles}
|
||||
cd={tuCountdown}
|
||||
accent={theme.accent}
|
||||
subText={theme.subText}
|
||||
pinkMode={pinkMode}
|
||||
numStyle={styles.focusNum}
|
||||
sepStyle={styles.focusSep}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={[styles.placeholder, { color: theme.subText }]}>No timer set</Text>
|
||||
);
|
||||
}
|
||||
|
||||
if (screen === 'timer') {
|
||||
focusContent = timerDone ? (
|
||||
<Text style={[styles.overText, styles.focusOverText, { color: pinkMode ? theme.pink : theme.danger }, pinkOutlineText]}>
|
||||
Done!
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.focusCountdown}>
|
||||
<Text style={[styles.focusLabel, { color: theme.subText }]}>TIMER</Text>
|
||||
<CountdownRow
|
||||
styles={styles}
|
||||
cd={{ hours: timerHr, minutes: timerMin, seconds: timerSec }}
|
||||
accent={theme.accent}
|
||||
subText={theme.subText}
|
||||
pinkMode={pinkMode}
|
||||
numStyle={styles.focusNum}
|
||||
sepStyle={styles.focusSep}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.root, styles.focusRoot, { backgroundColor: theme.bg }]}>
|
||||
<StatusBar hidden />
|
||||
{focusContent}
|
||||
<TouchableOpacity style={[styles.focusExitBtn, { borderColor: theme.accent }]} onPress={onShowUI}>
|
||||
<Text style={[styles.focusExitText, { color: theme.accent }]}>Show UI</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
87
src/screens/HomeScreen.js
Normal file
87
src/screens/HomeScreen.js
Normal file
@@ -0,0 +1,87 @@
|
||||
import React from 'react';
|
||||
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
||||
import TopControls from '../components/TopControls';
|
||||
|
||||
export default function HomeScreen({
|
||||
styles,
|
||||
theme,
|
||||
now,
|
||||
pinkMode,
|
||||
darkMode,
|
||||
isFullscreen,
|
||||
onToggleDark,
|
||||
onTogglePink,
|
||||
onToggleFullscreen,
|
||||
onSelectTimeUntil,
|
||||
onSelectTimer,
|
||||
}) {
|
||||
return (
|
||||
<View style={[styles.root, { backgroundColor: theme.bg }]}>
|
||||
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
|
||||
<Text
|
||||
style={[
|
||||
styles.title,
|
||||
{ color: theme.accent },
|
||||
pinkMode && {
|
||||
borderColor: theme.accent,
|
||||
borderWidth: 2,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Time Until
|
||||
</Text>
|
||||
|
||||
<TopControls
|
||||
styles={styles}
|
||||
accent={theme.accent}
|
||||
pink={theme.pink}
|
||||
darkMode={darkMode}
|
||||
pinkMode={pinkMode}
|
||||
isFullscreen={isFullscreen}
|
||||
showBackToMenu={false}
|
||||
showFocus={false}
|
||||
onBackToMenu={() => {}}
|
||||
onToggleDark={onToggleDark}
|
||||
onTogglePink={onTogglePink}
|
||||
onToggleFullscreen={onToggleFullscreen}
|
||||
onFocus={() => {}}
|
||||
/>
|
||||
|
||||
<Text style={[styles.modeSelectLabel, { color: theme.subText }]}>SELECT MODE</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.modeCard, { backgroundColor: theme.cardBg, borderColor: theme.accent }]}
|
||||
onPress={onSelectTimeUntil}
|
||||
activeOpacity={0.75}
|
||||
>
|
||||
<Text style={[styles.modeTitle, { color: theme.accent }]}>Mode 1: Time Until</Text>
|
||||
<Text style={[styles.modeDesc, { color: theme.subText }]}>
|
||||
Set a target clock time and count down to it
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.modeCard, { backgroundColor: theme.cardBg, borderColor: theme.border }]}
|
||||
onPress={onSelectTimer}
|
||||
activeOpacity={0.75}
|
||||
>
|
||||
<Text style={[styles.modeTitle, { color: theme.accent }]}>Mode 2: Timer</Text>
|
||||
<Text style={[styles.modeDesc, { color: theme.subText }]}>
|
||||
Set duration in hours, minutes, and seconds
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={[styles.clock, { color: theme.subText, marginTop: 32 }]}>
|
||||
{now.toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
})}
|
||||
</Text>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
173
src/screens/TimeUntilScreen.js
Normal file
173
src/screens/TimeUntilScreen.js
Normal file
@@ -0,0 +1,173 @@
|
||||
import React from 'react';
|
||||
import { ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import CountdownRow from '../components/CountdownRow';
|
||||
import TopControls from '../components/TopControls';
|
||||
|
||||
export default function TimeUntilScreen({
|
||||
styles,
|
||||
theme,
|
||||
now,
|
||||
darkMode,
|
||||
pinkMode,
|
||||
isFullscreen,
|
||||
targetTime,
|
||||
tuHour,
|
||||
tuMinute,
|
||||
tuIsOver,
|
||||
tuCountdown,
|
||||
onChangeHour,
|
||||
onChangeMinute,
|
||||
onSetTimer,
|
||||
onResetTimer,
|
||||
onBackToMenu,
|
||||
onToggleDark,
|
||||
onTogglePink,
|
||||
onToggleFullscreen,
|
||||
onFocus,
|
||||
}) {
|
||||
const isCountingDown = Boolean(tuCountdown) && !tuIsOver;
|
||||
|
||||
const pinkOutlineText = pinkMode
|
||||
? {
|
||||
borderColor: theme.pink,
|
||||
borderWidth: 2,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 8,
|
||||
}
|
||||
: {};
|
||||
|
||||
return (
|
||||
<View style={[styles.root, { backgroundColor: theme.bg }]}>
|
||||
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
|
||||
<Text
|
||||
style={[
|
||||
styles.title,
|
||||
{ color: theme.accent },
|
||||
pinkMode && {
|
||||
borderColor: theme.accent,
|
||||
borderWidth: 2,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Time Until
|
||||
</Text>
|
||||
|
||||
<TopControls
|
||||
styles={styles}
|
||||
accent={theme.accent}
|
||||
pink={theme.pink}
|
||||
darkMode={darkMode}
|
||||
pinkMode={pinkMode}
|
||||
isFullscreen={isFullscreen}
|
||||
showBackToMenu
|
||||
showFocus={targetTime !== null || tuIsOver}
|
||||
onBackToMenu={onBackToMenu}
|
||||
onToggleDark={onToggleDark}
|
||||
onTogglePink={onTogglePink}
|
||||
onToggleFullscreen={onToggleFullscreen}
|
||||
onFocus={onFocus}
|
||||
/>
|
||||
|
||||
<View style={[styles.card, { backgroundColor: theme.cardBg, borderColor: theme.border }]}>
|
||||
{!isCountingDown && (
|
||||
<>
|
||||
<Text style={[styles.inputLabel, { color: theme.subText }]}>Set target time (24h)</Text>
|
||||
<View style={styles.inputRow}>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.timeInput,
|
||||
{ color: theme.text, borderColor: theme.accent, backgroundColor: theme.inputBg },
|
||||
]}
|
||||
placeholder="HH"
|
||||
placeholderTextColor={darkMode ? '#5a6886' : '#98a1ba'}
|
||||
value={tuHour}
|
||||
onChangeText={onChangeHour}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
/>
|
||||
<Text style={[styles.colon, { color: theme.accent }]}>:</Text>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.timeInput,
|
||||
{ color: theme.text, borderColor: theme.accent, backgroundColor: theme.inputBg },
|
||||
]}
|
||||
placeholder="MM"
|
||||
placeholderTextColor={darkMode ? '#5a6886' : '#98a1ba'}
|
||||
value={tuMinute}
|
||||
onChangeText={onChangeMinute}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.btnRow}>
|
||||
<TouchableOpacity style={[styles.setBtn, { backgroundColor: theme.accent }]} onPress={onSetTimer}>
|
||||
<Text style={styles.setBtnText}>Set Timer</Text>
|
||||
</TouchableOpacity>
|
||||
{targetTime && (
|
||||
<TouchableOpacity
|
||||
style={[styles.resetBtn, { borderColor: theme.accent }]}
|
||||
onPress={onResetTimer}
|
||||
>
|
||||
<Text style={[styles.resetBtnText, { color: theme.accent }]}>Reset</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isCountingDown && targetTime && (
|
||||
<View style={styles.btnRow}>
|
||||
<TouchableOpacity
|
||||
style={[styles.resetBtn, { borderColor: theme.accent }]}
|
||||
onPress={onResetTimer}
|
||||
>
|
||||
<Text style={[styles.resetBtnText, { color: theme.accent }]}>Reset</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{tuIsOver ? (
|
||||
<View style={styles.overContainer}>
|
||||
<Text style={[styles.overText, { color: pinkMode ? theme.pink : theme.danger }, pinkOutlineText]}>
|
||||
Time's Up!
|
||||
</Text>
|
||||
<Text style={[styles.overSub, { color: theme.subText }]}>
|
||||
{targetTime?.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} has been reached
|
||||
</Text>
|
||||
</View>
|
||||
) : tuCountdown ? (
|
||||
<View style={styles.countdownContainer}>
|
||||
<Text style={[styles.countdownLabel, { color: theme.subText }]}>
|
||||
until {targetTime?.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
|
||||
</Text>
|
||||
<CountdownRow
|
||||
styles={styles}
|
||||
cd={tuCountdown}
|
||||
accent={theme.accent}
|
||||
subText={theme.subText}
|
||||
pinkMode={pinkMode}
|
||||
numStyle={styles.countdownNum}
|
||||
sepStyle={styles.sep}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Text style={[styles.placeholder, { color: theme.subText }]}>Enter a time above to start counting down</Text>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Text style={[styles.clock, { color: theme.subText }]}>
|
||||
{now.toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
})}
|
||||
</Text>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
195
src/screens/TimerScreen.js
Normal file
195
src/screens/TimerScreen.js
Normal file
@@ -0,0 +1,195 @@
|
||||
import React from 'react';
|
||||
import { ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import CountdownRow from '../components/CountdownRow';
|
||||
import TopControls from '../components/TopControls';
|
||||
|
||||
export default function TimerScreen({
|
||||
styles,
|
||||
theme,
|
||||
now,
|
||||
darkMode,
|
||||
pinkMode,
|
||||
isFullscreen,
|
||||
timerRunning,
|
||||
timerDone,
|
||||
timerRemaining,
|
||||
timerHInput,
|
||||
timerMInput,
|
||||
timerSInput,
|
||||
timerHr,
|
||||
timerMin,
|
||||
timerSec,
|
||||
onChangeH,
|
||||
onChangeM,
|
||||
onChangeS,
|
||||
onStart,
|
||||
onPause,
|
||||
onResume,
|
||||
onReset,
|
||||
onBackToMenu,
|
||||
onToggleDark,
|
||||
onTogglePink,
|
||||
onToggleFullscreen,
|
||||
onFocus,
|
||||
}) {
|
||||
const timerActive = timerRunning || timerRemaining > 0 || timerDone;
|
||||
const isCountingDown = timerRemaining > 0;
|
||||
const pinkOutlineText = pinkMode
|
||||
? {
|
||||
borderColor: theme.pink,
|
||||
borderWidth: 2,
|
||||
borderRadius: 12,
|
||||
paddingHorizontal: 20,
|
||||
paddingVertical: 8,
|
||||
}
|
||||
: {};
|
||||
|
||||
return (
|
||||
<View style={[styles.root, { backgroundColor: theme.bg }]}>
|
||||
<ScrollView contentContainerStyle={styles.scroll} keyboardShouldPersistTaps="handled">
|
||||
<Text
|
||||
style={[
|
||||
styles.title,
|
||||
{ color: theme.accent },
|
||||
pinkMode && {
|
||||
borderColor: theme.accent,
|
||||
borderWidth: 2,
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 4,
|
||||
},
|
||||
]}
|
||||
>
|
||||
Timer
|
||||
</Text>
|
||||
|
||||
<TopControls
|
||||
styles={styles}
|
||||
accent={theme.accent}
|
||||
pink={theme.pink}
|
||||
darkMode={darkMode}
|
||||
pinkMode={pinkMode}
|
||||
isFullscreen={isFullscreen}
|
||||
showBackToMenu
|
||||
showFocus={timerActive}
|
||||
onBackToMenu={onBackToMenu}
|
||||
onToggleDark={onToggleDark}
|
||||
onTogglePink={onTogglePink}
|
||||
onToggleFullscreen={onToggleFullscreen}
|
||||
onFocus={onFocus}
|
||||
/>
|
||||
|
||||
<View style={[styles.card, { backgroundColor: theme.cardBg, borderColor: theme.border }]}>
|
||||
{!isCountingDown && !timerDone ? (
|
||||
<>
|
||||
<Text style={[styles.inputLabel, { color: theme.subText }]}>Set duration</Text>
|
||||
<View style={styles.inputRow}>
|
||||
<View style={styles.timerInputGroup}>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.timeInput,
|
||||
{ color: theme.text, borderColor: theme.accent, backgroundColor: theme.inputBg },
|
||||
]}
|
||||
placeholder="00"
|
||||
placeholderTextColor={darkMode ? '#5a6886' : '#98a1ba'}
|
||||
value={timerHInput}
|
||||
onChangeText={onChangeH}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
/>
|
||||
<Text style={[styles.inputUnit, { color: theme.subText }]}>HRS</Text>
|
||||
</View>
|
||||
<Text style={[styles.colon, { color: theme.accent }]}>:</Text>
|
||||
<View style={styles.timerInputGroup}>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.timeInput,
|
||||
{ color: theme.text, borderColor: theme.accent, backgroundColor: theme.inputBg },
|
||||
]}
|
||||
placeholder="00"
|
||||
placeholderTextColor={darkMode ? '#5a6886' : '#98a1ba'}
|
||||
value={timerMInput}
|
||||
onChangeText={onChangeM}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
/>
|
||||
<Text style={[styles.inputUnit, { color: theme.subText }]}>MIN</Text>
|
||||
</View>
|
||||
<Text style={[styles.colon, { color: theme.accent }]}>:</Text>
|
||||
<View style={styles.timerInputGroup}>
|
||||
<TextInput
|
||||
style={[
|
||||
styles.timeInput,
|
||||
{ color: theme.text, borderColor: theme.accent, backgroundColor: theme.inputBg },
|
||||
]}
|
||||
placeholder="00"
|
||||
placeholderTextColor={darkMode ? '#5a6886' : '#98a1ba'}
|
||||
value={timerSInput}
|
||||
onChangeText={onChangeS}
|
||||
keyboardType="numeric"
|
||||
maxLength={2}
|
||||
/>
|
||||
<Text style={[styles.inputUnit, { color: theme.subText }]}>SEC</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity style={[styles.setBtn, { backgroundColor: theme.accent }]} onPress={onStart}>
|
||||
<Text style={styles.setBtnText}>Start</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
) : timerDone ? (
|
||||
<View style={styles.overContainer}>
|
||||
<Text style={[styles.overText, { color: pinkMode ? theme.pink : theme.danger }, pinkOutlineText]}>
|
||||
Done!
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={[styles.setBtn, { backgroundColor: theme.accent, marginTop: 20 }]}
|
||||
onPress={onReset}
|
||||
>
|
||||
<Text style={styles.setBtnText}>New Timer</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.countdownContainer}>
|
||||
<View>
|
||||
<CountdownRow
|
||||
styles={styles}
|
||||
cd={{ hours: timerHr, minutes: timerMin, seconds: timerSec }}
|
||||
accent={theme.accent}
|
||||
subText={theme.subText}
|
||||
pinkMode={pinkMode}
|
||||
numStyle={styles.countdownNum}
|
||||
sepStyle={styles.sep}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.btnRow}>
|
||||
{timerRunning ? (
|
||||
<TouchableOpacity style={[styles.resetBtn, { borderColor: theme.accent }]} onPress={onPause}>
|
||||
<Text style={[styles.resetBtnText, { color: theme.accent }]}>Pause</Text>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<TouchableOpacity style={[styles.setBtn, { backgroundColor: theme.accent }]} onPress={onResume}>
|
||||
<Text style={styles.setBtnText}>Resume</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
<TouchableOpacity style={[styles.resetBtn, { borderColor: theme.danger }]} onPress={onReset}>
|
||||
<Text style={[styles.resetBtnText, { color: theme.danger }]}>Reset</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Text style={[styles.clock, { color: theme.subText }]}>
|
||||
{now.toLocaleTimeString([], {
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit',
|
||||
})}
|
||||
</Text>
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user