All checks were successful
Build & Release APK / build (push) Successful in 1m53s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { useRouter } from "expo-router";
|
|
import { Pressable, StyleSheet, Text, View } from "react-native";
|
|
import Animated, { FadeIn } from "react-native-reanimated";
|
|
import { haptic } from "../lib/haptics";
|
|
import { formatEstimate, PRIORITY_COLOR } from "../lib/priority";
|
|
import { updateTask } from "../lib/store";
|
|
import { C } from "../lib/theme";
|
|
import type { Task, TaskStatus } from "../lib/types";
|
|
|
|
export default function TaskRow({
|
|
task,
|
|
uncheckTo = "next",
|
|
showStatus,
|
|
}: {
|
|
task: Task;
|
|
/** Status to revert to when un-checking a done task. */
|
|
uncheckTo?: TaskStatus;
|
|
showStatus?: boolean;
|
|
}) {
|
|
const router = useRouter();
|
|
const meta = [
|
|
showStatus ? task.status : null,
|
|
task.context,
|
|
task.waiting_for && `→ ${task.waiting_for}`,
|
|
formatEstimate(task.estimate_min),
|
|
task.due_date && `due ${task.due_date}`,
|
|
]
|
|
.filter(Boolean)
|
|
.join(" · ");
|
|
|
|
const toggle = () => {
|
|
const done = task.status !== "done";
|
|
if (done) haptic.success();
|
|
else haptic.tap();
|
|
updateTask(task.id, { status: done ? "done" : uncheckTo });
|
|
};
|
|
|
|
return (
|
|
<Animated.View entering={FadeIn.duration(150)}>
|
|
<Pressable style={s.row} onPress={() => router.push(`/task/${task.id}`)}>
|
|
<Pressable
|
|
style={[s.checkbox, { borderColor: PRIORITY_COLOR[task.priority] }]}
|
|
hitSlop={10}
|
|
onPress={toggle}
|
|
>
|
|
{task.status === "done" && <View style={s.checkboxFill} />}
|
|
</Pressable>
|
|
<View style={{ flex: 1 }}>
|
|
<Text style={s.title} numberOfLines={2}>
|
|
{task.title}
|
|
</Text>
|
|
{!!meta && <Text style={s.meta}>{meta}</Text>}
|
|
</View>
|
|
</Pressable>
|
|
</Animated.View>
|
|
);
|
|
}
|
|
|
|
const s = StyleSheet.create({
|
|
row: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
gap: 12,
|
|
paddingVertical: 14,
|
|
paddingHorizontal: 16,
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
borderBottomColor: C.border,
|
|
},
|
|
checkbox: {
|
|
width: 22,
|
|
height: 22,
|
|
borderRadius: 11,
|
|
borderWidth: 2,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
},
|
|
checkboxFill: { width: 12, height: 12, borderRadius: 6, backgroundColor: C.done },
|
|
title: { color: C.text, fontSize: 16 },
|
|
meta: { color: C.muted, fontSize: 13, marginTop: 2 },
|
|
});
|