mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2025-12-12 11:36:20 +00:00
394 lines
12 KiB
JavaScript
394 lines
12 KiB
JavaScript
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)
|
|
},
|
|
})
|