taskeep-app/app/widgets/hello.tsx
2025-07-30 16:03:14 +02:00

149 lines
7.1 KiB
TypeScript

import React from 'react';
import { useTranslation } from 'react-i18next';
import { ColorProp, FlexWidget, IconWidget, ListWidget, SvgWidget, TextWidget, } from 'react-native-android-widget';
import { getClockProgressSVG } from '../../components/clockProgress';
import { Category } from '../../models/category';
import { Task } from '../../models/task';
import { GetTaskColor } from '../../utils/colors';
const adaptDaysToGoToUnit = (t: Task) => {
const timeLeft = t.lastDone! + (t.daysToRedo! * 24 * 60 * 60 * 1000) - Date.now();
if (timeLeft < 0) return 0; // Task is overdue
else if (timeLeft < 3 * 60 * 60 * 1000) return Math.ceil(timeLeft / (60 * 1000)) + " minutes";
else if (timeLeft < 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (3600 * 1000)) + " hours";
else if (timeLeft < 7 * 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (24 * 3600 * 1000)) + " days";
else if (timeLeft < 30 * 24 * 60 * 60 * 1000) return Math.ceil(timeLeft / (7 * 24 * 3600 * 1000)) + " weeks";
else return Math.ceil(timeLeft / (30 * 24 * 3600 * 1000)) + " months";
};
export function HelloWidget({ tasks, categories }: { tasks: Task[], categories?: Category[] }) {
const { t } = useTranslation();
const demoTasks: Task[] = [
new Task('Task 1', 1, 1, new Date().getTime() - 1000 * 60 * 60 * 24 * 0, 5), // 2 days ago
new Task('Task 2', 2, 1, new Date().getTime() - 1000 * 60 * 60 * 24), // 1 day ago
new Task('Task 3', 3, 1, new Date().getTime() - 1000 * 60 * 60 * 24 * 2), // 2 days ago
new Task('Task 4', 4, 1, new Date().getTime() - 1000 * 60 * 60 * 24 * 3), // 3 days ago
new Task('Task 5', 5, 1, new Date().getTime() - 1000 * 60 * 60 * 24 * 4), // 4 days ago
new Task('Task 6', 6, 1, new Date().getTime() - 1000 * 60 * 60 * 24 * 10), // 4 days ago
];
tasks = (tasks ?? demoTasks)?.sort((a, b) => {
const aExpiration = (Date.now() - a.lastDone!) / (a.daysToRedo! * 24 * 60 * 60 * 1000);
const bExpiration = (Date.now() - b.lastDone!) / (b.daysToRedo! * 24 * 60 * 60 * 1000);
return aExpiration - bExpiration;
}).reverse();
return (
<FlexWidget
style={{
height: 'match_parent',
width: 'match_parent',
backgroundColor: '#121212',
borderRadius: 16,
padding: 24
}}
>
<FlexWidget style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginBottom: 16,
width: 'match_parent',
}}>
<TextWidget
text={t('hello_tasks')}
style={{
color: '#ffffff',
fontSize: 24,
fontWeight: 'bold',
}}
/>
<IconWidget font="material" icon="refresh" size={32} style={{
color: '#ffffff',
}} clickAction='REFRESH' />
</FlexWidget>
<ListWidget
style={{
width: 'match_parent',
height: 'match_parent',
}}
>
{tasks.map((task, index) => {
const category = categories?.find(c => c.id === task.category);
const timeLeft = adaptDaysToGoToUnit(task)
const circleDegree = parseInt(timeLeft.toString()) > 0 ? ((task.daysToRedo! - (((Date.now() - task.lastDone!) / (24 * 3600 * 1000)))) / task.daysToRedo!) * 360 : 0;
return (
<FlexWidget
key={Date.now() + "-" + Math.random() + "-" + index + "-" + task.id}
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: 'match_parent',
paddingVertical: 8
}}>
<FlexWidget
style={{
width: 'match_parent',
borderLeftWidth: 20,
borderLeftColor: GetTaskColor(task) as ColorProp,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 16,
paddingHorizontal: 16,
borderRadius: 8,
backgroundColor: '#333333',
}}
>
<FlexWidget
style={{
flexDirection: 'column'
}}>
<TextWidget
text={task.title}
style={{
color: '#ffffff',
fontSize: 20,
fontWeight: 'bold',
}}
/>
<TextWidget
text={`${category ? (category.icon + " " + category.title) : t('default_category_name')}`}
style={{
color: '#ffffff',
fontSize: 12,
}}
/>
<TextWidget
text={parseInt(timeLeft.toString()) > 0 ? timeLeft + " " + t('left') : t('overdue')}
style={{
color: '#ffffff',
fontSize: 16,
}}
/>
</FlexWidget>
<SvgWidget svg={getClockProgressSVG(
circleDegree,
100,
100,
GetTaskColor(task) as ColorProp
)} clickAction='UPDATE_TASK' clickActionData={{
id: task.id
}} />
</FlexWidget>
</FlexWidget>
)
})}
{(tasks && tasks.length === 0) &&
<TextWidget text={t('no_tasks_created')} style={{
color: '#ffffff'
}}>
</TextWidget>}
</ListWidget>
</FlexWidget>
);
}