From b7d62637e638954e2730ecb48fcf87490ee306c8 Mon Sep 17 00:00:00 2001 From: Chris Sanden Date: Wed, 22 Apr 2026 19:12:34 +0200 Subject: [PATCH] Fixed bug where timer would count space below nav bar as 'usable' space --- app/(tabs)/timer.tsx | 329 ++++++++++++++++++++++++++++--------------- 1 file changed, 215 insertions(+), 114 deletions(-) diff --git a/app/(tabs)/timer.tsx b/app/(tabs)/timer.tsx index eacca7d..20d94f1 100644 --- a/app/(tabs)/timer.tsx +++ b/app/(tabs)/timer.tsx @@ -4,6 +4,7 @@ import { Dimensions, StatusBar, StyleSheet, + Text, TouchableOpacity, View } from 'react-native'; @@ -18,6 +19,10 @@ const colors = { const timers = [...Array(13).keys()].map((i) => (i === 0 ? 1 : i * 5)); const ITEM_SIZE = width * 0.38; const ITEM_SPACING = (width - ITEM_SIZE) / 2; +const placeholderTask = { + name: 'Read chapter 4', + description: 'Focus on the summary questions and write down anything unclear.', +}; /* Har bare skrevet timeren som en egen tab til å begynne med. @@ -26,136 +31,212 @@ som viser TaskName og Description der tallene står nå Kanskje en animert figur hvis vi får tid */ export default function App() { - const scrollX = React.useRef(new Animated.Value(0)).current; - const [duration, setDuration] = React.useState(timers[0]) - const timerAnimation = React.useRef(new Animated.Value(height)).current - const buttonAnimation = React.useRef(new Animated.Value(0)).current - const animation = React.useCallback(() => { - Animated.sequence([ + const [containerHeight, setContainerHeight] = React.useState(0) + const scrollX = React.useRef(new Animated.Value(0)).current; + const [duration, setDuration] = React.useState(timers[0]) + const [isRunning, setIsRunning] = React.useState(false) + const timerAnimation = React.useRef(new Animated.Value(0)).current + const buttonAnimation = React.useRef(new Animated.Value(0)).current + const taskDetailsAnimation = React.useRef(new Animated.Value(0)).current + const animation = React.useCallback(() => { + if (isRunning) { + return; + } + + setIsRunning(true); + taskDetailsAnimation.setValue(0); + + Animated.sequence([ + Animated.parallel([ Animated.timing(buttonAnimation, { toValue: 1, duration: 300, useNativeDriver: true }), - Animated.timing(timerAnimation, { - toValue: 0, - duration: 300, + Animated.timing(taskDetailsAnimation, { + toValue: 1, + duration: 500, useNativeDriver: true }), - Animated.timing(timerAnimation, { - toValue: height, - duration: duration * 1000, - useNativeDriver: true - }), - ]) .start(() => { + ]), + Animated.timing(timerAnimation, { + toValue: 0, + duration: 300, + useNativeDriver: true + }), + Animated.timing(timerAnimation, { + toValue: containerHeight, + duration: duration * 1000, + useNativeDriver: true + }), + ]) .start(({ finished }) => { + if (!finished) { + setIsRunning(false); + return; + } + + Animated.parallel([ Animated.timing(buttonAnimation, { toValue: 0, duration: 300, useNativeDriver: true - }).start() + }), + Animated.timing(taskDetailsAnimation, { + toValue: 0, + duration: 300, + useNativeDriver: true + }), + ]).start(() => { + setIsRunning(false); }) - }, [duration]) - - const opacity = buttonAnimation.interpolate({ - inputRange: [0, 1], - outputRange: [1, 0] }) - const translateY = buttonAnimation.interpolate({ - inputRange: [0, 1], - outputRange: [0, 200] + }, [buttonAnimation, duration, isRunning, taskDetailsAnimation, timerAnimation]) + + React.useEffect(() => { + if (containerHeight > 0) { + timerAnimation.setValue(containerHeight); + } }) - - return ( - - + + {placeholderTask.name} + {placeholderTask.description} + ); } @@ -176,5 +257,25 @@ const styles = StyleSheet.create({ fontFamily: 'Menlo', color: colors.text, fontWeight: '900', + }, + taskDetails: { + position: 'absolute', + top: height * 0.56, + left: 32, + right: 32, + alignItems: 'center', + }, + taskName: { + color: colors.text, + fontSize: 24, + fontWeight: '800', + textAlign: 'center', + }, + taskDescription: { + color: colors.text, + fontSize: 16, + lineHeight: 22, + marginTop: 10, + textAlign: 'center', } -}); \ No newline at end of file +});