This repository has been archived by the owner on Jan 20, 2024. It is now read-only.
/
tasks.ts
106 lines (102 loc) · 3.34 KB
/
tasks.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { Task, TaskRecord } from "../typings/tasks";
/**
* Converts a JSON object received from the server to a task record.
* @param task Task record taken from the server output.
*/
export const taskFromRecord = (task: TaskRecord): Task => {
const newTask = new Task();
newTask.ID = task.id as number;
newTask.PID = "parent_id" in task ? (task.parent_id as number) : 0;
newTask.Text = "text" in task ? (task.text as string) : "";
newTask.Completed = task.status !== 0;
newTask.LastMod = task.last_mod as number;
newTask.Deadline = "deadline" in task ? (task.deadline as number) : 0;
newTask.Reminder = "reminder" in task ? (task.reminder as number) : 0;
return newTask;
};
/**
* Exports a task record to a JSON object that can be pushed to the
* server in a POST / PATCH request.
* @param task Task record
*/
export const taskToRecord = (task: Task): TaskRecord => {
const record = {
parent_id: task.PID,
text: task.Text,
status: task.Completed ? 1 : 0,
deadline: task.Deadline,
reminder: task.Reminder,
} as TaskRecord;
return record;
};
export interface TaskMergeResult {
result: Task[];
toDelete: Task[];
toUpdate: Task[];
toSync: Task[];
}
/**
* Merges two task lists based on their modtimes. Prefers remote tasks on
* matching modtimes. Returns the four lists: the merged task list, the list
* of tasks to be sent for deletion, and the list of tasks to be pushed to the
* server as well as the list of tasks to be updated remotely.
* @param remote Task list received from remote server
* @param local Task list version stored locally
*/
export const mergeTasks = (
remoteTasks: Task[],
localTasks: Task[]
): TaskMergeResult => {
const result: Task[] = [],
toDelete: Task[] = [],
toSync: Task[] = [],
toUpdate: Task[] = [];
// first passthrough
remoteTasks.forEach((remote) => {
// prettier-ignore
const local = localTasks.find((val) => val.ID === remote.ID);
if (local) {
// matching local task found, comparing modtimes
if (local.LastMod > remote.LastMod) {
result.push(local);
toUpdate.push(local);
} else {
result.push(remote);
}
if (local.ToRemove) {
toDelete.push(local);
}
} else {
// matching local task not found, adding a new task to the store
result.push(remote);
}
});
// second passthrough
localTasks.forEach((local) => {
// check whether we haven't already pushed this task
if (!result.find((task) => task.ID === local.ID)) {
// prettier-ignore
const remote = remoteTasks.find((val) => val.ID === local.ID);
if (remote) {
if (local.LastMod >= remote.LastMod) {
result.push(local);
toUpdate.push(local);
} else {
result.push(remote);
}
if (local.ToRemove) {
toDelete.push(local);
}
} else if (local.ToSync) {
result.push(local);
toSync.push(local);
}
}
});
return {
result,
toDelete,
toSync,
toUpdate,
};
};