const {Gio, Gdk, Gtk} = imports.gi import {App, Widget, Utils} from "../imports.js" const {Box, CenterBox, Label, Button} = Widget import {MaterialIcon} from "./lib/materialicon.js" import {getCalendarLayout} from "../scripts/calendarlayout.js" import Todo from "../scripts/todo.js" import {setupCursorHover} from "./lib/cursorhover.js" import {NavigationIndicator} from "./lib/navigationindicator.js" let calendarJson = getCalendarLayout(undefined, true) let monthshift = 0 function fileExists(filePath) { let file = Gio.File.new_for_path(filePath) return file.query_exists(null) } function getDateInXMonthsTime(x) { var currentDate = new Date() // Get the current date var targetMonth = currentDate.getMonth() + x // Calculate the target month var targetYear = currentDate.getFullYear() // Get the current year // Adjust the year and month if necessary targetYear += Math.floor(targetMonth / 12) targetMonth = ((targetMonth % 12) + 12) % 12 // Create a new date object with the target year and month var targetDate = new Date(targetYear, targetMonth, 1) // Set the day to the last day of the month to get the desired date // targetDate.setDate(0); return targetDate } const weekDays = [ // stupid stupid stupid!! how tf is Sunday the first day of the week?? {day: "Su", today: 0}, {day: "Mo", today: 0}, {day: "Tu", today: 0}, {day: "We", today: 0}, {day: "Th", today: 0}, {day: "Fr", today: 0}, {day: "Sa", today: 0}, ] const CalendarDay = (day, today) => Widget.Button({ className: `sidebar-calendar-btn ${ today == 1 ? "sidebar-calendar-btn-today" : today == -1 ? "sidebar-calendar-btn-othermonth" : "" }`, child: Widget.Overlay({ child: Box({}), overlays: [ Label({ halign: "center", className: "txt-smallie txt-semibold sidebar-calendar-btn-txt", label: String(day), }), ], }), }) const CalendarWidget = () => { const calendarMonthYear = Widget.Button({ className: "txt txt-large sidebar-calendar-monthyear-btn", onClicked: () => shiftCalendarXMonths(0), setup: button => { button.label = `${new Date().toLocaleString("default", {month: "long"})} ${new Date().getFullYear()}` setupCursorHover(button) }, }) const addCalendarChildren = (box, calendarJson) => { box.children = calendarJson.map((row, i) => Widget.Box({ // homogeneous: true, className: "spacing-h-5", children: row.map((day, i) => CalendarDay(day.day, day.today)), }), ) } function shiftCalendarXMonths(x) { if (x == 0) monthshift = 0 else monthshift += x var newDate = undefined if (monthshift == 0) newDate = new Date() else newDate = getDateInXMonthsTime(monthshift) calendarJson = getCalendarLayout(newDate, monthshift == 0) calendarMonthYear.label = `${monthshift == 0 ? "" : "• "}${newDate.toLocaleString("default", { month: "long", })} ${newDate.getFullYear()}` addCalendarChildren(calendarDays, calendarJson) } const calendarHeader = Widget.Box({ className: "spacing-h-5 sidebar-calendar-header", setup: box => { box.pack_start(calendarMonthYear, false, false, 0) box.pack_end( Widget.Box({ className: "spacing-h-5", children: [ Button({ className: "sidebar-calendar-monthshift-btn", onClicked: () => shiftCalendarXMonths(-1), child: MaterialIcon("chevron_left", "norm"), setup: button => setupCursorHover(button), }), Button({ className: "sidebar-calendar-monthshift-btn", onClicked: () => shiftCalendarXMonths(1), child: MaterialIcon("chevron_right", "norm"), setup: button => setupCursorHover(button), }), ], }), false, false, 0, ) }, }) const calendarDays = Widget.Box({ hexpand: true, vertical: true, className: "spacing-v-5", setup: box => { addCalendarChildren(box, calendarJson) }, }) return Widget.EventBox({ onScrollUp: () => shiftCalendarXMonths(-1), onScrollDown: () => shiftCalendarXMonths(1), child: Widget.Box({ halign: "center", children: [ Widget.Box({ hexpand: true, vertical: true, className: "spacing-v-5", children: [ calendarHeader, Widget.Box({ homogeneous: true, className: "spacing-h-5", children: weekDays.map((day, i) => CalendarDay(day.day, day.today)), }), calendarDays, ], }), ], }), }) } const defaultTodoSelected = "undone" const todoItems = isDone => Widget.Scrollable({ child: Widget.Box({ vertical: true, connections: [ [ Todo, self => { self.children = Todo.todo_json.map((task, i) => { if (task.done != isDone) return null return Widget.Box({ className: "spacing-h-5", children: [ Widget.Label({ className: "txt txt-small", label: "•", }), Widget.Label({ hexpand: true, xalign: 0, wrap: true, className: "txt txt-small sidebar-todo-txt", label: task.content, }), Widget.Button({ valign: "center", className: "txt sidebar-todo-item-action", child: MaterialIcon(`${isDone ? "remove_done" : "check"}`, "norm", {valign: "center"}), onClicked: () => { if (isDone) Todo.uncheck(i) else Todo.check(i) }, setup: button => setupCursorHover(button), }), Widget.Button({ valign: "center", className: "txt sidebar-todo-item-action", child: MaterialIcon("delete_forever", "norm", {valign: "center"}), onClicked: () => { Todo.remove(i) }, setup: button => setupCursorHover(button), }), ], }) }) if (self.children.length == 0) { self.homogeneous = true self.children = [ Widget.Box({ hexpand: true, vertical: true, valign: "center", className: "txt", children: [ MaterialIcon(`${isDone ? "checklist" : "check_circle"}`, "badonkers"), Label({label: `${isDone ? "Finished tasks will go here" : "Nothing here!"}`}), ], }), ] } else self.homogeneous = false }, "updated", ], ], }), }) const todoItemsBox = Widget.Stack({ valign: "fill", transition: "slide_left_right", items: [ ["undone", todoItems(false)], ["done", todoItems(true)], ], }) const TodoWidget = () => { const TodoTabButton = (isDone, navIndex) => Widget.Button({ hexpand: true, className: "sidebar-todo-selector-tab", onClicked: button => { todoItemsBox.shown = `${isDone ? "done" : "undone"}` const kids = button.get_parent().get_children() for (let i = 0; i < kids.length; i++) { if (kids[i] != button) kids[i].toggleClassName("sidebar-todo-selector-tab-active", false) else button.toggleClassName("sidebar-todo-selector-tab-active", true) } // Fancy highlighter line width const buttonWidth = button.get_allocated_width() const highlightWidth = button.get_children()[0].get_allocated_width() navIndicator.style = ` font-size: ${navIndex}px; padding: 0px ${(buttonWidth - highlightWidth) / 2}px; ` }, child: Box({ halign: "center", className: "spacing-h-5", children: [ MaterialIcon(`${isDone ? "task_alt" : "format_list_bulleted"}`, "larger"), Label({ className: "txt txt-smallie", label: `${isDone ? "Done" : "Unfinished"}`, }), ], }), setup: button => { button.toggleClassName( "sidebar-todo-selector-tab-active", defaultTodoSelected === `${isDone ? "done" : "undone"}`, ) setupCursorHover(button) }, }) const undoneButton = TodoTabButton(false, 0) const doneButton = TodoTabButton(true, 1) const navIndicator = NavigationIndicator(2, false, { className: "sidebar-todo-selector-highlight", style: "font-size: 0px;", setup: self => { // Fancy highlighter line width const buttonWidth = undoneButton.get_allocated_width() const highlightWidth = undoneButton.get_children()[0].get_allocated_width() navIndicator.style = ` font-size: ${navIndex}px; padding: 0px ${(buttonWidth - highlightWidth) / 2}px; ` }, }) return Widget.Box({ hexpand: true, vertical: true, className: "spacing-v-10", setup: box => { // undone/done selector rail box.pack_start( Widget.Box({ vertical: true, children: [ Widget.Box({ className: "sidebar-todo-selectors spacing-h-5", homogeneous: true, setup: box => { box.pack_start(undoneButton, false, true, 0) box.pack_start(doneButton, false, true, 0) }, }), Widget.Box({ className: "sidebar-todo-selector-highlight-offset", homogeneous: true, children: [navIndicator], }), ], }), false, false, 0, ) box.pack_end(todoItemsBox, true, true, 0) }, }) } const defaultShown = "calendar" const contentStack = Widget.Stack({ hexpand: true, items: [ ["calendar", CalendarWidget()], ["todo", TodoWidget()], // ['stars', Widget.Label({ label: 'GitHub feed will be here' })], ], transition: "slide_up_down", transitionDuration: 180, setup: stack => { stack.shown = defaultShown }, }) const StackButton = (stackItemName, icon, name) => Widget.Button({ className: "button-minsize sidebar-navrail-btn sidebar-button-alone txt-small spacing-h-5", onClicked: button => { contentStack.shown = stackItemName const kids = button.get_parent().get_children() for (let i = 0; i < kids.length; i++) { if (kids[i] != button) kids[i].toggleClassName("sidebar-navrail-btn-active", false) else button.toggleClassName("sidebar-navrail-btn-active", true) } }, child: Box({ className: "spacing-v-5", vertical: true, children: [ Label({ className: `txt icon-material txt-hugeass`, label: icon, }), Label({ label: name, className: "txt txt-smallie", }), ], }), setup: button => { button.toggleClassName("sidebar-navrail-btn-active", defaultShown === stackItemName) setupCursorHover(button) }, }) export const ModuleCalendar = () => Box({ className: "sidebar-group spacing-h-5", setup: box => { box.pack_start( Box({ valign: "center", homogeneous: true, vertical: true, className: "sidebar-navrail spacing-v-10", children: [ StackButton("calendar", "calendar_month", "Calendar"), StackButton("todo", "checklist", "To Do"), // StackButton(box, 'stars', 'star', 'GitHub'), ], }), false, false, 0, ) // ags.Widget({ // TDOO: replace this sad default calendar with a custom one // type: imports.gi.Gtk.Calendar, // }), box.pack_end(contentStack, false, false, 0) }, })