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 (
-
-
-
-
-
-
-
-
-
- item.toString()}
- horizontal
- bounces={false}
- onScroll={Animated.event(
- [{nativeEvent: {contentOffset: {x: scrollX}}}],
- { useNativeDriver: true}
- )}
- showsHorizontalScrollIndicator={false}
- onMomentumScrollEnd={ev => {
- const index = Math.round(ev.nativeEvent.contentOffset.x / ITEM_SIZE)
- setDuration(timers[index]);
- }}
- snapToInterval={ITEM_SIZE}
- decelerationRate={"fast"}
- style={{flexGrow: 0}}
- contentContainerStyle={{
- paddingHorizontal: ITEM_SPACING
- }}
- renderItem={({item, index}) => {
- const inputRange = [
- (index - 1) * ITEM_SIZE,
- index * ITEM_SIZE,
- (index + 1) * ITEM_SIZE,
- ]
- const opacity = scrollX.interpolate({
- inputRange,
- outputRange: [.4, 1, .4]
- })
- const scale = scrollX.interpolate({
- inputRange,
- outputRange: [.7, 1, .7]
- })
- return
- {
+ setContainerHeight(event.nativeEvent.layout.height);
+ }}>
+
+
+
+
+
+
+
+
+ item.toString()}
+ horizontal
+ bounces={false}
+ onScroll={Animated.event(
+ [{nativeEvent: {contentOffset: {x: scrollX}}}],
+ { useNativeDriver: true}
+ )}
+ showsHorizontalScrollIndicator={false}
+ onMomentumScrollEnd={ev => {
+ const index = Math.round(ev.nativeEvent.contentOffset.x / ITEM_SIZE)
+ setDuration(timers[index]);
+ }}
+ snapToInterval={ITEM_SIZE}
+ decelerationRate={"fast"}
+ style={{flexGrow: 0}}
+ contentContainerStyle={{
+ paddingHorizontal: ITEM_SPACING
+ }}
+ renderItem={({item, index}) => {
+ const inputRange = [
+ (index - 1) * ITEM_SIZE,
+ index * ITEM_SIZE,
+ (index + 1) * ITEM_SIZE,
+ ]
- }]}>
- {item}
-
-
- }
+ const normalOpacity = scrollX.interpolate({
+ inputRange,
+ outputRange: [.4, 1, .4]
+ })
+ const selectedOpacity = scrollX.interpolate({
+ inputRange,
+ outputRange: [0, 1, 0],
+ extrapolate: 'clamp'
+ })
+ const opacity = Animated.add(
+ Animated.multiply(normalOpacity, inactiveTimerNumberOpacity),
+ Animated.multiply(selectedOpacity, buttonAnimation)
+ )
+ const scale = scrollX.interpolate({
+ inputRange,
+ outputRange: [.7, 1, .7]
+ })
+ return
+
+ {item}
+
+
}
- />
-
+ }
+ />
+
+
+ {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
+});