225 lines
8.0 KiB
JavaScript
225 lines
8.0 KiB
JavaScript
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
const { Box, Button, Label, Revealer } = Widget;
|
|
import { MaterialIcon } from '../.commonwidgets/materialicon.js';
|
|
import { TabContainer } from '../.commonwidgets/tabcontainer.js';
|
|
import Todo from "../../services/todo.js";
|
|
import { setupCursorHover } from '../.widgetutils/cursorhover.js';
|
|
|
|
const TodoListItem = (task, id, isDone, isEven = false) => {
|
|
const taskName = Widget.Label({
|
|
hexpand: true,
|
|
xalign: 0,
|
|
wrap: true,
|
|
className: 'txt txt-small sidebar-todo-txt',
|
|
label: task.content,
|
|
selectable: true,
|
|
});
|
|
const actions = Box({
|
|
hpack: 'end',
|
|
className: 'spacing-h-5 sidebar-todo-actions',
|
|
children: [
|
|
Widget.Button({ // Check/Uncheck
|
|
vpack: 'center',
|
|
className: 'txt sidebar-todo-item-action',
|
|
child: MaterialIcon(`${isDone ? 'remove_done' : 'check'}`, 'norm', { vpack: 'center' }),
|
|
onClicked: (self) => {
|
|
const contentWidth = todoContent.get_allocated_width();
|
|
crosser.toggleClassName('sidebar-todo-crosser-crossed', true);
|
|
crosser.css = `margin-left: -${contentWidth}px;`;
|
|
Utils.timeout(200, () => {
|
|
widgetRevealer.revealChild = false;
|
|
})
|
|
Utils.timeout(350, () => {
|
|
if (isDone)
|
|
Todo.uncheck(id);
|
|
else
|
|
Todo.check(id);
|
|
})
|
|
},
|
|
setup: setupCursorHover,
|
|
}),
|
|
Widget.Button({ // Remove
|
|
vpack: 'center',
|
|
className: 'txt sidebar-todo-item-action',
|
|
child: MaterialIcon('delete_forever', 'norm', { vpack: 'center' }),
|
|
onClicked: () => {
|
|
const contentWidth = todoContent.get_allocated_width();
|
|
crosser.toggleClassName('sidebar-todo-crosser-removed', true);
|
|
crosser.css = `margin-left: -${contentWidth}px;`;
|
|
Utils.timeout(200, () => {
|
|
widgetRevealer.revealChild = false;
|
|
})
|
|
Utils.timeout(350, () => {
|
|
Todo.remove(id);
|
|
})
|
|
},
|
|
setup: setupCursorHover,
|
|
}),
|
|
]
|
|
})
|
|
const crosser = Widget.Box({
|
|
className: 'sidebar-todo-crosser',
|
|
});
|
|
const todoContent = Widget.Box({
|
|
className: 'sidebar-todo-item spacing-h-5',
|
|
children: [
|
|
Widget.Box({
|
|
vertical: true,
|
|
children: [
|
|
taskName,
|
|
actions,
|
|
]
|
|
}),
|
|
crosser,
|
|
]
|
|
});
|
|
const widgetRevealer = Widget.Revealer({
|
|
revealChild: true,
|
|
transition: 'slide_down',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
child: todoContent,
|
|
})
|
|
return Box({
|
|
homogeneous: true,
|
|
children: [widgetRevealer]
|
|
});
|
|
}
|
|
|
|
const todoItems = (isDone) => Widget.Scrollable({
|
|
hscroll: 'never',
|
|
vscroll: 'automatic',
|
|
child: Widget.Box({
|
|
vertical: true,
|
|
className: 'spacing-v-5',
|
|
setup: (self) => self
|
|
.hook(Todo, (self) => {
|
|
self.children = Todo.todo_json.map((task, i) => {
|
|
if (task.done != isDone) return null;
|
|
return TodoListItem(task, i, isDone);
|
|
})
|
|
if (self.children.length == 0) {
|
|
self.homogeneous = true;
|
|
self.children = [
|
|
Widget.Box({
|
|
hexpand: true,
|
|
vertical: true,
|
|
vpack: 'center',
|
|
className: 'txt txt-subtext',
|
|
children: [
|
|
MaterialIcon(`${isDone ? 'checklist' : 'check_circle'}`, 'gigantic'),
|
|
Label({ label: `${isDone ? 'Finished tasks will go here' : 'Nothing here!'}` })
|
|
]
|
|
})
|
|
]
|
|
}
|
|
else self.homogeneous = false;
|
|
}, 'updated')
|
|
,
|
|
}),
|
|
setup: (listContents) => {
|
|
const vScrollbar = listContents.get_vscrollbar();
|
|
vScrollbar.get_style_context().add_class('sidebar-scrollbar');
|
|
}
|
|
});
|
|
|
|
const UndoneTodoList = () => {
|
|
const newTaskButton = Revealer({
|
|
transition: 'slide_left',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
revealChild: true,
|
|
child: Button({
|
|
className: 'txt-small sidebar-todo-new',
|
|
halign: 'end',
|
|
vpack: 'center',
|
|
label: '+ New task',
|
|
setup: setupCursorHover,
|
|
onClicked: (self) => {
|
|
newTaskButton.revealChild = false;
|
|
newTaskEntryRevealer.revealChild = true;
|
|
confirmAddTask.revealChild = true;
|
|
cancelAddTask.revealChild = true;
|
|
newTaskEntry.grab_focus();
|
|
}
|
|
})
|
|
});
|
|
const cancelAddTask = Revealer({
|
|
transition: 'slide_right',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
revealChild: false,
|
|
child: Button({
|
|
className: 'txt-norm icon-material sidebar-todo-add',
|
|
halign: 'end',
|
|
vpack: 'center',
|
|
label: 'close',
|
|
setup: setupCursorHover,
|
|
onClicked: (self) => {
|
|
newTaskEntryRevealer.revealChild = false;
|
|
confirmAddTask.revealChild = false;
|
|
cancelAddTask.revealChild = false;
|
|
newTaskButton.revealChild = true;
|
|
newTaskEntry.text = '';
|
|
}
|
|
})
|
|
});
|
|
const newTaskEntry = Widget.Entry({
|
|
// hexpand: true,
|
|
vpack: 'center',
|
|
className: 'txt-small sidebar-todo-entry',
|
|
placeholderText: 'Add a task...',
|
|
onAccept: ({ text }) => {
|
|
if (text == '') return;
|
|
Todo.add(text)
|
|
newTaskEntry.text = '';
|
|
},
|
|
onChange: ({ text }) => confirmAddTask.child.toggleClassName('sidebar-todo-add-available', text != ''),
|
|
});
|
|
const newTaskEntryRevealer = Revealer({
|
|
transition: 'slide_right',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
revealChild: false,
|
|
child: newTaskEntry,
|
|
});
|
|
const confirmAddTask = Revealer({
|
|
transition: 'slide_right',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
revealChild: false,
|
|
child: Button({
|
|
className: 'txt-norm icon-material sidebar-todo-add',
|
|
halign: 'end',
|
|
vpack: 'center',
|
|
label: 'arrow_upward',
|
|
setup: setupCursorHover,
|
|
onClicked: (self) => {
|
|
if (newTaskEntry.text == '') return;
|
|
Todo.add(newTaskEntry.text);
|
|
newTaskEntry.text = '';
|
|
}
|
|
})
|
|
});
|
|
return Box({ // The list, with a New button
|
|
vertical: true,
|
|
className: 'spacing-v-5',
|
|
setup: (box) => {
|
|
box.pack_start(todoItems(false), true, true, 0);
|
|
box.pack_start(Box({
|
|
setup: (self) => {
|
|
self.pack_start(cancelAddTask, false, false, 0);
|
|
self.pack_start(newTaskEntryRevealer, true, true, 0);
|
|
self.pack_start(confirmAddTask, false, false, 0);
|
|
self.pack_start(newTaskButton, false, false, 0);
|
|
}
|
|
}), false, false, 0);
|
|
},
|
|
});
|
|
}
|
|
|
|
export const TodoWidget = () => TabContainer({
|
|
icons: ['format_list_bulleted', 'task_alt'],
|
|
names: ['Unfinished', 'Done'],
|
|
children: [
|
|
UndoneTodoList(),
|
|
todoItems(true),
|
|
]
|
|
})
|