gitshark

Clone repository

git clone https://git.vilip.de/git/vilip/taskflow.git
git clone git@git.vilip.de:vilip/taskflow.git

← Commits

๐Ÿ› Fix duplicate Task bugs

a5882d724d4cab7cb3dd4a32aab176f18199e369 ยท vvilip ยท 2025-11-04T16:07:04Z

Changes

6 files changed, +58 -16

MODIFY app/(tabs)/index.tsx +6 -4
diff --git "a/app/\050tabs\051/index.tsx" "b/app/\050tabs\051/index.tsx"
index 29f0f1c..04884fd 100644
--- "a/app/\050tabs\051/index.tsx"
+++ "b/app/\050tabs\051/index.tsx"
@@ -1,6 +1,6 @@
1 1 import React, { useEffect, useState } from 'react';
2 2 import { StyleSheet, SafeAreaView, Alert } from 'react-native';
3 -import { router } from 'expo-router';
3 +import { router, useFocusEffect } from 'expo-router';
4 4 import { ThemedView } from '@/components/themed-view';
5 5 import { ThemedText } from '@/components/themed-text';
6 6 import { TaskList } from '@/components/task-list';
@@ -12,9 +12,11 @@
12 12 const [tasks, setTasks] = useState<Task[]>([]);
13 13 const [loading, setLoading] = useState(true);
14 14
15 - useEffect(() => {
16 - loadTasks();
17 - }, []);
15 + useFocusEffect(
16 + React.useCallback(() => {
17 + loadTasks();
18 + }, [])
19 + );
18 20
19 21 const loadTasks = async () => {
20 22 try {
MODIFY app/(tabs)/projects.tsx +6 -4
diff --git "a/app/\050tabs\051/projects.tsx" "b/app/\050tabs\051/projects.tsx"
index 14496ab..ee8a626 100644
--- "a/app/\050tabs\051/projects.tsx"
+++ "b/app/\050tabs\051/projects.tsx"
@@ -1,6 +1,6 @@
1 1 import React, { useEffect, useState } from 'react';
2 2 import { StyleSheet, SafeAreaView, Alert, TouchableOpacity, FlatList, View } from 'react-native';
3 -import { router } from 'expo-router';
3 +import { router, useFocusEffect } from 'expo-router';
4 4 import { ThemedView } from '@/components/themed-view';
5 5 import { ThemedText } from '@/components/themed-text';
6 6 import { FabButton } from '@/components/fab-button';
@@ -12,9 +12,11 @@
12 12 const [taskCounts, setTaskCounts] = useState<Record<string, number>>({});
13 13 const [loading, setLoading] = useState(true);
14 14
15 - useEffect(() => {
16 - loadProjects();
17 - }, []);
15 + useFocusEffect(
16 + React.useCallback(() => {
17 + loadProjects();
18 + }, [])
19 + );
18 20
19 21 const loadProjects = async () => {
20 22 try {
MODIFY app/(tabs)/today.tsx +9 -4
diff --git "a/app/\050tabs\051/today.tsx" "b/app/\050tabs\051/today.tsx"
index fb49fa0..b546224 100644
--- "a/app/\050tabs\051/today.tsx"
+++ "b/app/\050tabs\051/today.tsx"
@@ -1,6 +1,6 @@
1 1 import React, { useEffect, useState } from 'react';
2 2 import { StyleSheet, SafeAreaView, Alert, ScrollView } from 'react-native';
3 -import { router } from 'expo-router';
3 +import { router, useFocusEffect } from 'expo-router';
4 4 import { ThemedView } from '@/components/themed-view';
5 5 import { ThemedText } from '@/components/themed-text';
6 6 import { TaskList } from '@/components/task-list';
@@ -14,9 +14,11 @@
14 14 const [overdueTasks, setOverdueTasks] = useState<Task[]>([]);
15 15 const [loading, setLoading] = useState(true);
16 16
17 - useEffect(() => {
18 - loadTasks();
19 - }, []);
17 + useFocusEffect(
18 + React.useCallback(() => {
19 + loadTasks();
20 + }, [])
21 + );
20 22
21 23 const loadTasks = async () => {
22 24 try {
@@ -83,6 +85,7 @@
83 85 tasks={overdueTasks}
84 86 onTaskPress={handleTaskPress}
85 87 onToggleComplete={handleToggleComplete}
88 + scrollable={false}
86 89 />
87 90 </ThemedView>
88 91 )}
@@ -94,6 +97,7 @@
94 97 tasks={todayTasks}
95 98 onTaskPress={handleTaskPress}
96 99 onToggleComplete={handleToggleComplete}
100 + scrollable={false}
97 101 />
98 102 </ThemedView>
99 103 )}
@@ -105,6 +109,7 @@
105 109 tasks={tomorrowTasks}
106 110 onTaskPress={handleTaskPress}
107 111 onToggleComplete={handleToggleComplete}
112 + scrollable={false}
108 113 />
109 114 </ThemedView>
110 115 )}
MODIFY app/project/[id].tsx +1 -0
diff --git "a/app/project/\133id\135.tsx" "b/app/project/\133id\135.tsx"
index d1be58f..2994421 100644
--- "a/app/project/\133id\135.tsx"
+++ "b/app/project/\133id\135.tsx"
@@ -270,6 +270,7 @@
270 270 onTaskPress={handleTaskPress}
271 271 onToggleComplete={handleToggleComplete}
272 272 emptyMessage="No tasks in this project yet"
273 + scrollable={false}
273 274 />
274 275 </ThemedView>
275 276 </>
MODIFY components/task-list.tsx +19 -1
diff --git a/components/task-list.tsx b/components/task-list.tsx
index 3c3f499..f55c18e 100644
--- a/components/task-list.tsx
+++ b/components/task-list.tsx
@@ -10,9 +10,10 @@
10 10 onTaskPress: (task: Task) => void;
11 11 onToggleComplete: (taskId: string) => void;
12 12 emptyMessage?: string;
13 + scrollable?: boolean;
13 14 }
14 15
15 -export function TaskList({ tasks, onTaskPress, onToggleComplete, emptyMessage }: TaskListProps) {
16 +export function TaskList({ tasks, onTaskPress, onToggleComplete, emptyMessage, scrollable = true }: TaskListProps) {
16 17 if (tasks.length === 0) {
17 18 return (
18 19 <ThemedView style={styles.emptyContainer}>
@@ -23,6 +24,23 @@
23 24 );
24 25 }
25 26
27 + if (!scrollable) {
28 + return (
29 + <ThemedView style={styles.list}>
30 + {tasks.map((item, index) => (
31 + <React.Fragment key={item.id}>
32 + <TaskItem
33 + task={item}
34 + onPress={() => onTaskPress(item)}
35 + onToggleComplete={() => onToggleComplete(item.id)}
36 + />
37 + {index < tasks.length - 1 && <View style={styles.separator} />}
38 + </React.Fragment>
39 + ))}
40 + </ThemedView>
41 + );
42 + }
43 +
26 44 return (
27 45 <FlatList
28 46 data={tasks}
MODIFY services/task.service.ts +17 -3
diff --git a/services/task.service.ts b/services/task.service.ts
index ccf0113..b673242 100644
--- a/services/task.service.ts
+++ b/services/task.service.ts
@@ -25,10 +25,16 @@
25 25 }
26 26
27 27 /**
28 - * Get inbox tasks
28 + * Get inbox tasks (only tasks without due date and in inbox status)
29 29 */
30 30 async getInboxTasks(): Promise<Task[]> {
31 - return this.getTasksByStatus('inbox');
31 + const tasks = await this.getAllTasks();
32 + return tasks.filter(task =>
33 + task.status === 'inbox' &&
34 + !task.completed &&
35 + !task.dueDate &&
36 + !task.projectId
37 + );
32 38 }
33 39
34 40 /**
@@ -147,13 +153,21 @@
147 153 throw new Error('Task not found');
148 154 }
149 155
156 + const currentTask = data.tasks[taskIndex];
150 157 const updatedTask = {
151 - ...data.tasks[taskIndex],
158 + ...currentTask,
152 159 ...updates,
153 160 id: taskId,
154 161 updatedAt: Date.now(),
155 162 };
156 163
164 + // Auto-move out of inbox when task gets processed
165 + if (currentTask.status === 'inbox') {
166 + if (updates.dueDate || updates.projectId || (updates.status && updates.status !== 'inbox')) {
167 + updatedTask.status = updates.status || 'next';
168 + }
169 + }
170 +
157 171 data.tasks[taskIndex] = updatedTask;
158 172 await storageService.saveData(data);
159 173

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog