diff --git a/.gitignore b/.gitignore index d7d899ab3e..330c0c29d7 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,6 @@ Secrets*.toml restate-data .windsurfrules -.turbo \ No newline at end of file +.turbo + +CLAUDE.md \ No newline at end of file diff --git a/apps/desktop/src/components/command-palette.tsx b/apps/desktop/src/components/command-palette.tsx index 2896f24179..3eaf11bec0 100644 --- a/apps/desktop/src/components/command-palette.tsx +++ b/apps/desktop/src/components/command-palette.tsx @@ -23,6 +23,7 @@ import { useEffect, useRef, useState } from "react"; import { useHypr } from "@/contexts/hypr"; import { type SearchMatch } from "@/stores/search"; import { commands as dbCommands } from "@hypr/plugin-db"; +import { commands as windowsCommands } from "@hypr/plugin-windows"; interface CommandPaletteProps { open: boolean; @@ -281,10 +282,22 @@ export function CommandPalette({ open, onOpenChange }: CommandPaletteProps) { navigate({ to: "/app/new", search: { calendarEventId: match.item.id } }); break; case "human": - navigate({ to: "/app/human/$id", params: { id: match.item.id } }); + // Open finder window and navigate to contact view with person selected + windowsCommands.windowShow({ type: "finder" }).then(() => { + windowsCommands.windowNavigate( + { type: "finder" }, + `/app/finder?view=contact&personId=${match.item.id}`, + ); + }); break; case "organization": - navigate({ to: "/app/organization/$id", params: { id: match.item.id } }); + // Open finder window and navigate to contact view with organization selected + windowsCommands.windowShow({ type: "finder" }).then(() => { + windowsCommands.windowNavigate( + { type: "finder" }, + `/app/finder?view=contact&orgId=${match.item.id}`, + ); + }); break; } onOpenChange(false); diff --git a/apps/desktop/src/components/finder/index.ts b/apps/desktop/src/components/finder/index.ts new file mode 100644 index 0000000000..fb30574fd5 --- /dev/null +++ b/apps/desktop/src/components/finder/index.ts @@ -0,0 +1,4 @@ +export { ViewSelector } from "./view-selector"; +export { CalendarView } from "./views/calendar-view"; +export { FolderView } from "./views/folder-view"; +export { TableView } from "./views/table-view"; diff --git a/apps/desktop/src/components/finder/view-selector.tsx b/apps/desktop/src/components/finder/view-selector.tsx new file mode 100644 index 0000000000..e74881c2c9 --- /dev/null +++ b/apps/desktop/src/components/finder/view-selector.tsx @@ -0,0 +1,68 @@ +import { Button } from "@hypr/ui/components/ui/button"; +import { cn } from "@hypr/ui/lib/utils"; +import { Calendar, Folder, Table, Users } from "lucide-react"; + +type ViewType = "folder" | "calendar" | "table" | "contact"; + +interface ViewSelectorProps { + currentView: ViewType; + onViewChange: (view: ViewType) => void; +} + +export function ViewSelector({ currentView, onViewChange }: ViewSelectorProps) { + return ( +
+ + + + + + )} +
+ )} + + + ); +} diff --git a/apps/desktop/src/components/left-sidebar/events-list.tsx b/apps/desktop/src/components/left-sidebar/events-list.tsx index b578cce354..d1463c8c42 100644 --- a/apps/desktop/src/components/left-sidebar/events-list.tsx +++ b/apps/desktop/src/components/left-sidebar/events-list.tsx @@ -1,6 +1,6 @@ import { Trans } from "@lingui/react/macro"; import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { LinkProps, useNavigate } from "@tanstack/react-router"; +import { useNavigate } from "@tanstack/react-router"; import { clsx } from "clsx"; import { format } from "date-fns"; import { AppWindowMacIcon, ArrowUpRight, CalendarDaysIcon, RefreshCwIcon } from "lucide-react"; @@ -19,7 +19,6 @@ import { SplashLoader } from "@hypr/ui/components/ui/splash"; import { cn } from "@hypr/ui/lib/utils"; import { useSession } from "@hypr/utils/contexts"; import { formatUpcomingTime } from "@hypr/utils/datetime"; -import { safeNavigate } from "@hypr/utils/navigation"; type EventWithSession = Event & { session: Session | null }; @@ -128,14 +127,12 @@ function EventItem({ const handleOpenCalendar = () => { const date = new Date(event.start_date); + const formattedDate = format(date, "yyyy-MM-dd"); + const url = `/app/finder?view=calendar&date=${formattedDate}`; - const params = { - to: "/app/calendar", - search: { date: format(date, "yyyy-MM-dd") }, - } as const satisfies LinkProps; - - const url = `${params.to}?date=${params.search.date}`; - safeNavigate({ type: "calendar" }, url); + windowsCommands.windowShow({ type: "finder" }).then(() => { + windowsCommands.windowEmitNavigate({ type: "finder" }, url); + }); }; const isActive = activeSessionId diff --git a/apps/desktop/src/components/left-sidebar/notes-list.tsx b/apps/desktop/src/components/left-sidebar/notes-list.tsx index 9b8127de26..4388e13ad6 100644 --- a/apps/desktop/src/components/left-sidebar/notes-list.tsx +++ b/apps/desktop/src/components/left-sidebar/notes-list.tsx @@ -1,7 +1,7 @@ import { Trans } from "@lingui/react/macro"; import { useLingui } from "@lingui/react/macro"; import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { type LinkProps, useMatch, useNavigate } from "@tanstack/react-router"; +import { useMatch, useNavigate } from "@tanstack/react-router"; import { confirm } from "@tauri-apps/plugin-dialog"; import { endOfMonth, startOfMonth, subMonths } from "date-fns"; import { AppWindowMacIcon, ArrowUpRight, CalendarDaysIcon, TrashIcon } from "lucide-react"; @@ -24,7 +24,6 @@ import { SplashLoader } from "@hypr/ui/components/ui/splash"; import { cn } from "@hypr/ui/lib/utils"; import { useSession, useSessions } from "@hypr/utils/contexts"; import { format, formatDate, formatRelative } from "@hypr/utils/datetime"; -import { safeNavigate } from "@hypr/utils/navigation"; interface NotesListProps { filter: (session: Session) => boolean; @@ -235,14 +234,13 @@ function NoteItem({ }; const handleOpenCalendar = () => { - const params = { - to: "/app/calendar", - search: { date: format(currentSession.created_at, "yyyy-MM-dd") }, - } as const satisfies LinkProps; + const date = new Date(currentSession.created_at); + const formattedDate = format(date, "yyyy-MM-dd"); + const url = `/app/finder?view=calendar&date=${formattedDate}`; - const url = `${params.to}?date=${params.search.date}`; - - safeNavigate({ type: "calendar" }, url); + windowsCommands.windowShow({ type: "finder" }).then(() => { + windowsCommands.windowEmitNavigate({ type: "finder" }, url); + }); }; const buttonRef = useRef(null); diff --git a/apps/desktop/src/components/left-sidebar/search-list.tsx b/apps/desktop/src/components/left-sidebar/search-list.tsx index 878ff3821d..51a87f3126 100644 --- a/apps/desktop/src/components/left-sidebar/search-list.tsx +++ b/apps/desktop/src/components/left-sidebar/search-list.tsx @@ -165,13 +165,6 @@ export function SessionMatch({ match: { item: session }, isSelected, query }: { const routeMatch = useMatch({ from: "/app/note/$id", shouldThrow: false }); const isActive = routeMatch?.params.id === session.id; - // Auto-scroll disabled - // useEffect(() => { - // if (isSelected && elementRef.current) { - // elementRef.current.scrollIntoView({ block: "nearest" }); - // } - // }, [isSelected]); - const handleClick = () => { navigate({ to: "/app/note/$id", @@ -209,13 +202,6 @@ function EventMatch({ match, isSelected, query }: { const event = match.item; const elementRef = useRef(null); - // Auto-scroll disabled - // useEffect(() => { - // if (isSelected && elementRef.current) { - // elementRef.current.scrollIntoView({ block: "nearest" }); - // } - // }, [isSelected]); - const handleClick = () => { navigate({ to: "/app/new", search: { calendarEventId: event.id } }); }; @@ -259,13 +245,6 @@ function HumanMatch({ match: { item }, isSelected, query }: { const isActive = routeMatch?.params.id === item.id; - // Auto-scroll disabled - // useEffect(() => { - // if (isSelected && elementRef.current) { - // elementRef.current.scrollIntoView({ block: "nearest" }); - // } - // }, [isSelected]); - const handleClick = () => { navigate({ to: "/app/human/$id", @@ -341,13 +320,6 @@ function OrganizationMatch({ match: { item: organization }, isSelected, query }: const isActive = routeMatch?.params.id === organization.id; - // Auto-scroll disabled - // useEffect(() => { - // if (isSelected && elementRef.current) { - // elementRef.current.scrollIntoView({ block: "nearest" }); - // } - // }, [isSelected]); - const handleClick = () => { navigate({ to: "/app/organization/$id", diff --git a/apps/desktop/src/components/left-sidebar/top-area/calendar-button.tsx b/apps/desktop/src/components/left-sidebar/top-area/finder-button.tsx similarity index 64% rename from apps/desktop/src/components/left-sidebar/top-area/calendar-button.tsx rename to apps/desktop/src/components/left-sidebar/top-area/finder-button.tsx index e58967c264..3fd83f86e9 100644 --- a/apps/desktop/src/components/left-sidebar/top-area/calendar-button.tsx +++ b/apps/desktop/src/components/left-sidebar/top-area/finder-button.tsx @@ -1,13 +1,13 @@ import { Trans } from "@lingui/react/macro"; -import { CalendarDaysIcon } from "lucide-react"; +import { Folder } from "lucide-react"; import { commands as windowsCommands } from "@hypr/plugin-windows"; import { Button } from "@hypr/ui/components/ui/button"; import { Tooltip, TooltipContent, TooltipTrigger } from "@hypr/ui/components/ui/tooltip"; -export function CalendarButton() { - const handleClickCalendar = () => { - windowsCommands.windowShow({ type: "calendar" }); +export function FinderButton() { + const handleClickFinder = () => { + windowsCommands.windowShow({ type: "finder" }); }; return ( @@ -16,14 +16,14 @@ export function CalendarButton() { - Open calendar view + Open finder view ); diff --git a/apps/desktop/src/components/left-sidebar/top-area/index.tsx b/apps/desktop/src/components/left-sidebar/top-area/index.tsx index 5d65a53039..ebed4553f5 100644 --- a/apps/desktop/src/components/left-sidebar/top-area/index.tsx +++ b/apps/desktop/src/components/left-sidebar/top-area/index.tsx @@ -3,7 +3,7 @@ import { type as getOsType } from "@tauri-apps/plugin-os"; import { LeftSidebarButton } from "@/components/toolbar/buttons/left-sidebar-button"; import { cn } from "@hypr/ui/lib/utils"; -import { CalendarButton } from "./calendar-button"; +import { FinderButton } from "./finder-button"; import { SettingsButton } from "./settings-button"; export function TopArea() { @@ -23,7 +23,7 @@ export function TopArea() { > - + diff --git a/apps/desktop/src/components/toolbar/bars/calendar-toolbar.tsx b/apps/desktop/src/components/toolbar/bars/calendar-toolbar.tsx deleted file mode 100644 index 1cb7b14f3e..0000000000 --- a/apps/desktop/src/components/toolbar/bars/calendar-toolbar.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { Trans, useLingui } from "@lingui/react/macro"; -import { useNavigate } from "@tanstack/react-router"; -import { clsx } from "clsx"; -import { addMonths, subMonths } from "date-fns"; -import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"; - -import { Button } from "@hypr/ui/components/ui/button"; - -interface CalendarToolbarProps { - date: Date; -} - -export function CalendarToolbar({ date }: CalendarToolbarProps) { - const { i18n } = useLingui(); - const navigate = useNavigate(); - const today = new Date(); - - const handlePreviousMonth = () => { - const prevMonth = subMonths(date, 1); - navigate({ - to: "/app/calendar", - search: { date: prevMonth.toISOString() }, - replace: true, - }); - }; - - const handleNextMonth = () => { - const nextMonth = addMonths(date, 1); - navigate({ - to: "/app/calendar", - search: { date: nextMonth.toISOString() }, - replace: true, - }); - }; - - const handleToday = () => { - navigate({ - to: "/app/calendar", - search: { date: today.toISOString() }, - replace: true, - }); - }; - - const weekDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - - return ( -
-
-

- {i18n.date(date, { month: "long", year: "numeric" })} -

- -
- - - - - -
-
- -
- {weekDays.map((day, index) => ( -
- {day} -
- ))} -
-
- ); -} diff --git a/apps/desktop/src/components/toolbar/bars/index.tsx b/apps/desktop/src/components/toolbar/bars/index.tsx index 8cf9928083..a098a7b170 100644 --- a/apps/desktop/src/components/toolbar/bars/index.tsx +++ b/apps/desktop/src/components/toolbar/bars/index.tsx @@ -1,4 +1,3 @@ -export * from "./calendar-toolbar"; export * from "./default-toolbar"; export * from "./entity-toolbar"; export * from "./main-toolbar"; diff --git a/apps/desktop/src/components/toolbar/index.tsx b/apps/desktop/src/components/toolbar/index.tsx index 132c0a78f8..c573b429ce 100644 --- a/apps/desktop/src/components/toolbar/index.tsx +++ b/apps/desktop/src/components/toolbar/index.tsx @@ -2,13 +2,12 @@ import { useMatch } from "@tanstack/react-router"; import { useEditMode } from "@/contexts/edit-mode-context"; import { getCurrentWebviewWindowLabel } from "@hypr/plugin-windows"; -import { CalendarToolbar, DefaultToolbar, EntityToolbar, MainToolbar, NoteToolbar } from "./bars"; +import { DefaultToolbar, EntityToolbar, MainToolbar, NoteToolbar } from "./bars"; export default function Toolbar() { const noteMatch = useMatch({ from: "/app/note/$id", shouldThrow: false }); const organizationMatch = useMatch({ from: "/app/organization/$id", shouldThrow: false }); const humanMatch = useMatch({ from: "/app/human/$id", shouldThrow: false }); - const calendarMatch = useMatch({ from: "/app/calendar", shouldThrow: false }); const plansMatch = useMatch({ from: "/app/plans", shouldThrow: false }); const { isEditing, toggleEditMode } = useEditMode(); @@ -17,14 +16,8 @@ export default function Toolbar() { const isNote = !!noteMatch; const isOrg = !!organizationMatch; const isHuman = !!humanMatch; - const isCalendar = !!calendarMatch; const isPlans = !!plansMatch; - if (isCalendar) { - const date = calendarMatch?.search?.date ? new Date(calendarMatch.search.date as string) : new Date(); - return ; - } - if (isPlans) { return ; } diff --git a/apps/desktop/src/components/workspace-calendar/event-card.tsx b/apps/desktop/src/components/workspace-calendar/event-card.tsx index cbf7f55b8b..93015c9d04 100644 --- a/apps/desktop/src/components/workspace-calendar/event-card.tsx +++ b/apps/desktop/src/components/workspace-calendar/event-card.tsx @@ -1,16 +1,16 @@ import { Trans } from "@lingui/react/macro"; import { useQuery } from "@tanstack/react-query"; -import type { LinkProps } from "@tanstack/react-router"; + import { format } from "date-fns"; -import { ExternalLinkIcon, Pen } from "lucide-react"; +import { Calendar, FileText, Pen } from "lucide-react"; import { useMemo, useState } from "react"; import { useHypr } from "@/contexts"; +import { openURL } from "@/utils/shell"; import type { Event } from "@hypr/plugin-db"; import { commands as dbCommands } from "@hypr/plugin-db"; -import { Button } from "@hypr/ui/components/ui/button"; +import { commands as windowsCommands } from "@hypr/plugin-windows"; import { Popover, PopoverContent, PopoverTrigger } from "@hypr/ui/components/ui/popover"; -import { safeNavigate } from "@hypr/utils/navigation"; export function EventCard({ event, @@ -65,25 +65,15 @@ export function EventCard({ setOpen(false); if (session.data) { - const props = { - to: "/app/note/$id", - params: { id: session.data.id }, - } as const satisfies LinkProps; - - const url = props.to.replace("$id", props.params.id); - - safeNavigate({ type: "main" }, url); + const url = `/app/note/${session.data.id}`; + windowsCommands.windowShow({ type: "main" }).then(() => { + windowsCommands.windowEmitNavigate({ type: "main" }, url); + }); } else { - const props = { - to: "/app/new", - search: { calendarEventId: event.id }, - } as const satisfies LinkProps; - - const url = props.to.concat( - `?calendarEventId=${props.search.calendarEventId}`, - ); - - safeNavigate({ type: "main" }, url); + const url = `/app/new?calendarEventId=${event.id}`; + windowsCommands.windowShow({ type: "main" }).then(() => { + windowsCommands.windowEmitNavigate({ type: "main" }, url); + }); } }; @@ -98,33 +88,23 @@ export function EventCard({ return ( -
-
+
+
{event.name || "Untitled Event"}
- - {showTime && ( -
- {format(getStartDate(), "h:mm a")} - {format(getEndDate(), "h:mm a")} -
- )}
-
-
- {event.name || "Untitled Event"} -
- - +
+ event.google_event_url && openURL(event.google_event_url as string).catch(error => + console.error("Failed to open event URL:", error) + )} + > + {event.name || "Untitled Event"}

@@ -137,36 +117,33 @@ export function EventCard({

{participantsPreview && participantsPreview.length > 0 && ( -
+
{participantsPreview.join(", ")}
)} {session.data ? ( - + +
+ {session.data.title || "Untitled Note"} +
+
) : ( - + +
+ Create Note +
+
)}
diff --git a/apps/desktop/src/components/workspace-calendar/index.tsx b/apps/desktop/src/components/workspace-calendar/index.tsx index 827e7a824e..013f82aa5f 100644 --- a/apps/desktop/src/components/workspace-calendar/index.tsx +++ b/apps/desktop/src/components/workspace-calendar/index.tsx @@ -90,15 +90,27 @@ export default function WorkspaceCalendar({ const daySessions = getSessionsForDay(date); const dayEvents = getEventsForDay(date); + // Filter out sessions that are linked to events to prevent duplicate display + // When a session is linked to an event, show only the event (not both) + const unlinkedSessions = daySessions.filter(session => { + // If session has calendar_event_id, check if that event exists in current events + if (session.calendar_event_id) { + // If the linked event exists in our events list, don't show the session separately + return !events.some(event => event.id === session.calendar_event_id); + } + // Session without calendar_event_id can be shown + return true; + }); + if (isFutureDate) { - return [...dayEvents, ...daySessions] as CalendarItem[]; + return [...dayEvents, ...unlinkedSessions] as CalendarItem[]; } if (isPastDate) { - return daySessions as CalendarItem[]; + return unlinkedSessions as CalendarItem[]; } - return [...dayEvents, ...daySessions] as CalendarItem[]; + return [...dayEvents, ...unlinkedSessions] as CalendarItem[]; }; const getCalendarDays = () => { diff --git a/apps/desktop/src/components/workspace-calendar/note-card.tsx b/apps/desktop/src/components/workspace-calendar/note-card.tsx index 19dafa4612..4bc6ea817f 100644 --- a/apps/desktop/src/components/workspace-calendar/note-card.tsx +++ b/apps/desktop/src/components/workspace-calendar/note-card.tsx @@ -1,16 +1,14 @@ -import { Trans } from "@lingui/react/macro"; import { useQuery } from "@tanstack/react-query"; -import type { LinkProps } from "@tanstack/react-router"; + import { format } from "date-fns"; -import { Pen } from "lucide-react"; +import { File, FileText } from "lucide-react"; import { useMemo, useState } from "react"; import { useHypr } from "@/contexts"; -import { type Session } from "@hypr/plugin-db"; +import type { Session } from "@hypr/plugin-db"; import { commands as dbCommands } from "@hypr/plugin-db"; -import { Button } from "@hypr/ui/components/ui/button"; +import { commands as windowsCommands } from "@hypr/plugin-windows"; import { Popover, PopoverContent, PopoverTrigger } from "@hypr/ui/components/ui/popover"; -import { safeNavigate } from "@hypr/utils/navigation"; export function NoteCard({ session, @@ -22,6 +20,17 @@ export function NoteCard({ const { userId } = useHypr(); const [open, setOpen] = useState(false); + const linkedEvent = useQuery({ + queryKey: ["session-linked-event", session.calendar_event_id], + queryFn: async () => { + if (!session.calendar_event_id) { + return null; + } + return await dbCommands.getEvent(session.calendar_event_id); + }, + enabled: !!session.calendar_event_id, + }); + const participants = useQuery({ queryKey: ["participants", session.id], queryFn: async () => { @@ -55,73 +64,83 @@ export function NoteCard({ const handleClick = (id: string) => { setOpen(false); - const props = { - to: "/app/note/$id", - params: { id }, - } as const satisfies LinkProps; - - const url = props.to.replace("$id", props.params.id); - - safeNavigate({ type: "main" }, url); + const url = `/app/note/${id}`; + windowsCommands.windowShow({ type: "main" }).then(() => { + windowsCommands.windowEmitNavigate({ type: "main" }, url); + }); }; const getStartDate = () => { - return session.calendar_event_id - ? new Date(session.created_at) - : new Date(); + if (session.record_start) { + return new Date(session.record_start); + } + return new Date(session.created_at); }; const getEndDate = () => { - return session.calendar_event_id - ? new Date(session.created_at) - : new Date(); + if (session.record_start && session.record_end) { + return new Date(session.record_end); + } + return getStartDate(); }; + const isRecordedSession = session.record_start && session.record_end; + const shouldShowRange = isRecordedSession; + return ( -
-
+
+ {isRecordedSession + ? + : }
- {session.title || "Untitled"} + {linkedEvent.data?.name || session.title || "Untitled"}
- - {showTime && ( -
- {format(getStartDate(), "h:mm a")} - {format(getEndDate(), "h:mm a")} -
- )}
-
- {session.title || "Untitled"} -
+

+ {linkedEvent.data?.name || session.title || "Untitled"} +

- {format(getStartDate(), "MMM d, h:mm a")} - {" - "} - {format(getStartDate(), "yyyy-MM-dd") - !== format(getEndDate(), "yyyy-MM-dd") - ? format(getEndDate(), "MMM d, h:mm a") - : format(getEndDate(), "h:mm a")} + {shouldShowRange + ? ( + <> + {format(getStartDate(), "MMM d, h:mm a")} + {" - "} + {format(getStartDate(), "yyyy-MM-dd") + !== format(getEndDate(), "yyyy-MM-dd") + ? format(getEndDate(), "MMM d, h:mm a") + : format(getEndDate(), "h:mm a")} + + ) + : ( + <> + Created: {format(getStartDate(), "MMM d, h:mm a")} + + )}

{participantsPreview && participantsPreview.length > 0 && ( -
+
{participantsPreview.join(", ")}
)} - + {isRecordedSession + ? + : } +
+ {linkedEvent.data?.name || session.title || "Untitled"} +
+
); diff --git a/apps/desktop/src/locales/en/messages.po b/apps/desktop/src/locales/en/messages.po index 20523a2348..6ca5479c0b 100644 --- a/apps/desktop/src/locales/en/messages.po +++ b/apps/desktop/src/locales/en/messages.po @@ -368,7 +368,7 @@ msgid "Apple" msgstr "Apple" #: src/components/toolbar/buttons/delete-note-button.tsx:43 -#: src/components/left-sidebar/notes-list.tsx:268 +#: src/components/left-sidebar/notes-list.tsx:266 msgid "Are you sure you want to delete this note?" msgstr "Are you sure you want to delete this note?" @@ -528,7 +528,7 @@ msgstr "Create agenda" msgid "Create new note" msgstr "Create new note" -#: src/components/workspace-calendar/event-card.tsx:166 +#: src/components/workspace-calendar/event-card.tsx:144 msgid "Create Note" msgstr "Create Note" @@ -558,7 +558,7 @@ msgstr "Custom Vocabulary" #: src/components/settings/views/template.tsx:215 #: src/components/settings/views/team.tsx:165 -#: src/components/left-sidebar/notes-list.tsx:335 +#: src/components/left-sidebar/notes-list.tsx:333 msgid "Delete" msgstr "Delete" @@ -724,7 +724,7 @@ msgstr "Help us improve Hyprnote by sharing anonymous usage data" msgid "Help us tailor your Hyprnote experience" msgstr "Help us tailor your Hyprnote experience" -#: src/components/left-sidebar/events-list.tsx:305 +#: src/components/left-sidebar/events-list.tsx:302 #~ msgid "Hide Event" #~ msgstr "Hide Event" @@ -805,7 +805,6 @@ msgstr "Loading events..." msgid "Loading templates..." msgstr "Loading templates..." -#: src/components/workspace-calendar/event-card.tsx:163 #: src/components/settings/components/calendar/calendar-selector.tsx:95 msgid "Loading..." msgstr "Loading..." @@ -867,8 +866,8 @@ msgstr "My Templates" msgid "New note" msgstr "New note" -#: src/components/left-sidebar/notes-list.tsx:312 -#: src/components/left-sidebar/events-list.tsx:181 +#: src/components/left-sidebar/notes-list.tsx:310 +#: src/components/left-sidebar/events-list.tsx:178 msgid "New window" msgstr "New window" @@ -912,7 +911,7 @@ msgstr "No Template (Default)" msgid "No templates yet" msgstr "No templates yet" -#: src/components/left-sidebar/events-list.tsx:95 +#: src/components/left-sidebar/events-list.tsx:94 msgid "No upcoming events" msgstr "No upcoming events" @@ -941,23 +940,23 @@ msgstr "Official Templates" #~ msgstr "Ooh! Suggestion!" #: src/components/left-sidebar/top-area/calendar-button.tsx:26 -msgid "Open calendar view" -msgstr "Open calendar view" +#~ msgid "Open calendar view" +#~ msgstr "Open calendar view" #: src/components/left-sidebar/top-area/finder-button.tsx:26 -#~ msgid "Open finder view" -#~ msgstr "Open finder view" +msgid "Open finder view" +msgstr "Open finder view" #: src/components/toolbar/buttons/new-window-button.tsx:35 -#: src/components/left-sidebar/search-list.tsx:319 -#: src/components/left-sidebar/search-list.tsx:396 +#: src/components/left-sidebar/search-list.tsx:298 +#: src/components/left-sidebar/search-list.tsx:368 msgid "Open in new window" msgstr "Open in new window" #: src/components/workspace-calendar/note-card.tsx:123 #: src/components/workspace-calendar/event-card.tsx:153 -msgid "Open Note" -msgstr "Open Note" +#~ msgid "Open Note" +#~ msgstr "Open Note" #: src/components/settings/views/integrations.tsx:255 msgid "Optional base folder path within your Obsidian vault." @@ -1206,7 +1205,7 @@ msgstr "This is a short description of your company." msgid "This is the name of the company you work for." msgstr "This is the name of the company you work for." -#: src/components/toolbar/bars/calendar-toolbar.tsx:67 +#: src/components/finder/views/calendar-view.tsx:64 msgid "Today" msgstr "Today" @@ -1250,7 +1249,7 @@ msgstr "Untitled" msgid "Untitled Template" msgstr "Untitled Template" -#: src/components/left-sidebar/events-list.tsx:62 +#: src/components/left-sidebar/events-list.tsx:61 msgid "Upcoming" msgstr "Upcoming" @@ -1282,11 +1281,11 @@ msgstr "username" msgid "Vault Name" msgstr "Vault Name" -#: src/components/left-sidebar/notes-list.tsx:323 +#: src/components/left-sidebar/notes-list.tsx:321 msgid "View calendar" msgstr "View calendar" -#: src/components/left-sidebar/events-list.tsx:193 +#: src/components/left-sidebar/events-list.tsx:190 #: src/components/editor-area/note-header/chips/event-chip.tsx:246 msgid "View in calendar" msgstr "View in calendar" diff --git a/apps/desktop/src/locales/ko/messages.po b/apps/desktop/src/locales/ko/messages.po index 234668df1c..af8640fb57 100644 --- a/apps/desktop/src/locales/ko/messages.po +++ b/apps/desktop/src/locales/ko/messages.po @@ -368,7 +368,7 @@ msgid "Apple" msgstr "" #: src/components/toolbar/buttons/delete-note-button.tsx:43 -#: src/components/left-sidebar/notes-list.tsx:268 +#: src/components/left-sidebar/notes-list.tsx:266 msgid "Are you sure you want to delete this note?" msgstr "" @@ -528,7 +528,7 @@ msgstr "" msgid "Create new note" msgstr "" -#: src/components/workspace-calendar/event-card.tsx:166 +#: src/components/workspace-calendar/event-card.tsx:144 msgid "Create Note" msgstr "" @@ -558,7 +558,7 @@ msgstr "" #: src/components/settings/views/template.tsx:215 #: src/components/settings/views/team.tsx:165 -#: src/components/left-sidebar/notes-list.tsx:335 +#: src/components/left-sidebar/notes-list.tsx:333 msgid "Delete" msgstr "" @@ -724,7 +724,7 @@ msgstr "" msgid "Help us tailor your Hyprnote experience" msgstr "" -#: src/components/left-sidebar/events-list.tsx:305 +#: src/components/left-sidebar/events-list.tsx:302 #~ msgid "Hide Event" #~ msgstr "" @@ -805,7 +805,6 @@ msgstr "" msgid "Loading templates..." msgstr "" -#: src/components/workspace-calendar/event-card.tsx:163 #: src/components/settings/components/calendar/calendar-selector.tsx:95 msgid "Loading..." msgstr "" @@ -867,8 +866,8 @@ msgstr "" msgid "New note" msgstr "" -#: src/components/left-sidebar/notes-list.tsx:312 -#: src/components/left-sidebar/events-list.tsx:181 +#: src/components/left-sidebar/notes-list.tsx:310 +#: src/components/left-sidebar/events-list.tsx:178 msgid "New window" msgstr "" @@ -912,7 +911,7 @@ msgstr "" msgid "No templates yet" msgstr "" -#: src/components/left-sidebar/events-list.tsx:95 +#: src/components/left-sidebar/events-list.tsx:94 msgid "No upcoming events" msgstr "" @@ -941,23 +940,23 @@ msgstr "" #~ msgstr "" #: src/components/left-sidebar/top-area/calendar-button.tsx:26 -msgid "Open calendar view" -msgstr "" +#~ msgid "Open calendar view" +#~ msgstr "" #: src/components/left-sidebar/top-area/finder-button.tsx:26 -#~ msgid "Open finder view" -#~ msgstr "" +msgid "Open finder view" +msgstr "" #: src/components/toolbar/buttons/new-window-button.tsx:35 -#: src/components/left-sidebar/search-list.tsx:319 -#: src/components/left-sidebar/search-list.tsx:396 +#: src/components/left-sidebar/search-list.tsx:298 +#: src/components/left-sidebar/search-list.tsx:368 msgid "Open in new window" msgstr "" #: src/components/workspace-calendar/note-card.tsx:123 #: src/components/workspace-calendar/event-card.tsx:153 -msgid "Open Note" -msgstr "" +#~ msgid "Open Note" +#~ msgstr "" #: src/components/settings/views/integrations.tsx:255 msgid "Optional base folder path within your Obsidian vault." @@ -1206,7 +1205,7 @@ msgstr "" msgid "This is the name of the company you work for." msgstr "" -#: src/components/toolbar/bars/calendar-toolbar.tsx:67 +#: src/components/finder/views/calendar-view.tsx:64 msgid "Today" msgstr "" @@ -1250,7 +1249,7 @@ msgstr "" msgid "Untitled Template" msgstr "" -#: src/components/left-sidebar/events-list.tsx:62 +#: src/components/left-sidebar/events-list.tsx:61 msgid "Upcoming" msgstr "" @@ -1282,11 +1281,11 @@ msgstr "" msgid "Vault Name" msgstr "" -#: src/components/left-sidebar/notes-list.tsx:323 +#: src/components/left-sidebar/notes-list.tsx:321 msgid "View calendar" msgstr "" -#: src/components/left-sidebar/events-list.tsx:193 +#: src/components/left-sidebar/events-list.tsx:190 #: src/components/editor-area/note-header/chips/event-chip.tsx:246 msgid "View in calendar" msgstr "" diff --git a/apps/desktop/src/routeTree.gen.ts b/apps/desktop/src/routeTree.gen.ts index ee1e7a603e..2389b77444 100644 --- a/apps/desktop/src/routeTree.gen.ts +++ b/apps/desktop/src/routeTree.gen.ts @@ -15,8 +15,8 @@ import { Route as AppIndexRouteImport } from './routes/app.index' import { Route as AppSettingsRouteImport } from './routes/app.settings' import { Route as AppPlansRouteImport } from './routes/app.plans' import { Route as AppNewRouteImport } from './routes/app.new' +import { Route as AppFinderRouteImport } from './routes/app.finder' import { Route as AppControlRouteImport } from './routes/app.control' -import { Route as AppCalendarRouteImport } from './routes/app.calendar' import { Route as AppOrganizationIdRouteImport } from './routes/app.organization.$id' import { Route as AppNoteIdRouteImport } from './routes/app.note.$id' import { Route as AppHumanIdRouteImport } from './routes/app.human.$id' @@ -52,16 +52,16 @@ const AppNewRoute = AppNewRouteImport.update({ path: '/new', getParentRoute: () => AppRoute, } as any) +const AppFinderRoute = AppFinderRouteImport.update({ + id: '/finder', + path: '/finder', + getParentRoute: () => AppRoute, +} as any) const AppControlRoute = AppControlRouteImport.update({ id: '/control', path: '/control', getParentRoute: () => AppRoute, } as any) -const AppCalendarRoute = AppCalendarRouteImport.update({ - id: '/calendar', - path: '/calendar', - getParentRoute: () => AppRoute, -} as any) const AppOrganizationIdRoute = AppOrganizationIdRouteImport.update({ id: '/organization/$id', path: '/organization/$id', @@ -86,8 +86,8 @@ const AppNoteEventIdRoute = AppNoteEventIdRouteImport.update({ export interface FileRoutesByFullPath { '/app': typeof AppRouteWithChildren '/video': typeof VideoRoute - '/app/calendar': typeof AppCalendarRoute '/app/control': typeof AppControlRoute + '/app/finder': typeof AppFinderRoute '/app/new': typeof AppNewRoute '/app/plans': typeof AppPlansRoute '/app/settings': typeof AppSettingsRoute @@ -99,8 +99,8 @@ export interface FileRoutesByFullPath { } export interface FileRoutesByTo { '/video': typeof VideoRoute - '/app/calendar': typeof AppCalendarRoute '/app/control': typeof AppControlRoute + '/app/finder': typeof AppFinderRoute '/app/new': typeof AppNewRoute '/app/plans': typeof AppPlansRoute '/app/settings': typeof AppSettingsRoute @@ -114,8 +114,8 @@ export interface FileRoutesById { __root__: typeof rootRouteImport '/app': typeof AppRouteWithChildren '/video': typeof VideoRoute - '/app/calendar': typeof AppCalendarRoute '/app/control': typeof AppControlRoute + '/app/finder': typeof AppFinderRoute '/app/new': typeof AppNewRoute '/app/plans': typeof AppPlansRoute '/app/settings': typeof AppSettingsRoute @@ -130,8 +130,8 @@ export interface FileRouteTypes { fullPaths: | '/app' | '/video' - | '/app/calendar' | '/app/control' + | '/app/finder' | '/app/new' | '/app/plans' | '/app/settings' @@ -143,8 +143,8 @@ export interface FileRouteTypes { fileRoutesByTo: FileRoutesByTo to: | '/video' - | '/app/calendar' | '/app/control' + | '/app/finder' | '/app/new' | '/app/plans' | '/app/settings' @@ -157,8 +157,8 @@ export interface FileRouteTypes { | '__root__' | '/app' | '/video' - | '/app/calendar' | '/app/control' + | '/app/finder' | '/app/new' | '/app/plans' | '/app/settings' @@ -218,6 +218,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AppNewRouteImport parentRoute: typeof AppRoute } + '/app/finder': { + id: '/app/finder' + path: '/finder' + fullPath: '/app/finder' + preLoaderRoute: typeof AppFinderRouteImport + parentRoute: typeof AppRoute + } '/app/control': { id: '/app/control' path: '/control' @@ -225,13 +232,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AppControlRouteImport parentRoute: typeof AppRoute } - '/app/calendar': { - id: '/app/calendar' - path: '/calendar' - fullPath: '/app/calendar' - preLoaderRoute: typeof AppCalendarRouteImport - parentRoute: typeof AppRoute - } '/app/organization/$id': { id: '/app/organization/$id' path: '/organization/$id' @@ -264,8 +264,8 @@ declare module '@tanstack/react-router' { } interface AppRouteChildren { - AppCalendarRoute: typeof AppCalendarRoute AppControlRoute: typeof AppControlRoute + AppFinderRoute: typeof AppFinderRoute AppNewRoute: typeof AppNewRoute AppPlansRoute: typeof AppPlansRoute AppSettingsRoute: typeof AppSettingsRoute @@ -277,8 +277,8 @@ interface AppRouteChildren { } const AppRouteChildren: AppRouteChildren = { - AppCalendarRoute: AppCalendarRoute, AppControlRoute: AppControlRoute, + AppFinderRoute: AppFinderRoute, AppNewRoute: AppNewRoute, AppPlansRoute: AppPlansRoute, AppSettingsRoute: AppSettingsRoute, diff --git a/apps/desktop/src/routes/app.calendar.tsx b/apps/desktop/src/routes/app.calendar.tsx deleted file mode 100644 index 6c5897a999..0000000000 --- a/apps/desktop/src/routes/app.calendar.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router"; -import { zodValidator } from "@tanstack/zod-adapter"; -import { endOfMonth, startOfMonth } from "date-fns"; -import { z } from "zod"; - -import WorkspaceCalendar from "@/components/workspace-calendar"; -import { commands as dbCommands } from "@hypr/plugin-db"; - -const schema = z.object({ - date: z.string().optional(), - sessionId: z.string().optional(), -}); - -export const Route = createFileRoute("/app/calendar")({ - component: Component, - validateSearch: zodValidator(schema), - loaderDeps: ({ search }) => ({ search }), - loader: async ({ context: { queryClient, userId }, deps: { search } }) => { - const eventPromise = search.sessionId - ? queryClient.fetchQuery({ - queryKey: ["event-session", search.sessionId], - queryFn: () => dbCommands.sessionGetEvent(search.sessionId!), - }) - : Promise.resolve(null); - - const event = await eventPromise; - - const date = event?.start_date - ? new Date(event.start_date) - : search.date - ? new Date(search.date) - : new Date(); - - const [start, end] = [startOfMonth(date), endOfMonth(date)].map((v) => v.toISOString()); - - const sessionsPromise = queryClient.fetchQuery({ - queryKey: ["sessions", start, end], - queryFn: () => - dbCommands.listSessions({ - type: "dateRange", - user_id: userId, - start, - end, - limit: 100, - }), - }); - - const eventsPromise = queryClient.fetchQuery({ - queryKey: ["events", start, end], - queryFn: () => - dbCommands.listEvents({ - type: "dateRange", - user_id: userId, - start, - end, - limit: 100, - }), - }); - - const [sessions, events] = await Promise.all([sessionsPromise, eventsPromise]); - return { sessions, events, date }; - }, -}); - -function Component() { - const { sessions, events, date } = Route.useLoaderData(); - - return ; -} diff --git a/apps/desktop/src/routes/app.finder.tsx b/apps/desktop/src/routes/app.finder.tsx new file mode 100644 index 0000000000..a209fac416 --- /dev/null +++ b/apps/desktop/src/routes/app.finder.tsx @@ -0,0 +1,234 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { endOfMonth, startOfMonth } from "date-fns"; +import { z } from "zod"; + +import { ViewSelector } from "@/components/finder/view-selector"; +import { CalendarView, ContactView, FolderView, TableView } from "@/components/finder/views"; +import { commands as dbCommands } from "@hypr/plugin-db"; +import { cn } from "@hypr/ui/lib/utils"; + +const schema = z.object({ + view: z.enum(["folder", "calendar", "table", "contact"]).default("calendar"), + date: z.string().optional(), + sessionId: z.string().optional(), + personId: z.string().optional(), + orgId: z.string().optional(), +}); + +export const Route = createFileRoute("/app/finder")({ + component: FinderView, + validateSearch: zodValidator(schema), + loaderDeps: ({ search }) => ({ search }), + loader: async ({ context: { queryClient, userId }, deps: { search } }) => { + const currentDate = search.date ? new Date(search.date) : new Date(); + + const baseData = { + view: search.view, + date: currentDate, + }; + + if (search.view === "calendar") { + const eventPromise = search.sessionId + ? queryClient.fetchQuery({ + queryKey: ["event-session", search.sessionId], + queryFn: () => dbCommands.sessionGetEvent(search.sessionId!), + }) + : Promise.resolve(null); + + const event = await eventPromise; + + const date = event?.start_date + ? new Date(event.start_date) + : search.date + ? new Date(search.date) + : new Date(); + + const [start, end] = [startOfMonth(date), endOfMonth(date)].map((v) => v.toISOString()); + + const sessionsPromise = queryClient.fetchQuery({ + queryKey: ["sessions", start, end], + queryFn: () => + dbCommands.listSessions({ + type: "dateRange", + user_id: userId, + start, + end, + limit: 100, + }), + }); + + const eventsPromise = queryClient.fetchQuery({ + queryKey: ["calendar-events", start, end], + queryFn: () => + dbCommands.listEvents({ + type: "dateRange", + user_id: userId, + start, + end, + limit: 100, + }), + }); + + const [sessions, rawEvents] = await Promise.all([ + sessionsPromise, + eventsPromise, + ]); + + // Deduplicate events by tracking_id to handle any sync issues + // Keep the most recent event (by database id) for each tracking_id + const eventsByTrackingId = new Map(); + rawEvents.forEach(event => { + const existing = eventsByTrackingId.get(event.tracking_id); + if (!existing || event.id > existing.id) { + eventsByTrackingId.set(event.tracking_id, event); + } + }); + const events = Array.from(eventsByTrackingId.values()); + + return { + ...baseData, + date, + sessions, + events, + }; + } + + if (search.view === "table") { + const currentDate = search.date ? new Date(search.date) : new Date(); + const [start, end] = [startOfMonth(currentDate), endOfMonth(currentDate)].map((v) => v.toISOString()); + + const sessionsPromise = queryClient.fetchQuery({ + queryKey: ["sessions-table", start, end], + queryFn: () => + dbCommands.listSessions({ + type: "dateRange", + user_id: userId, + start, + end, + limit: 100, + }), + }); + + const eventsPromise = queryClient.fetchQuery({ + queryKey: ["events-table", start, end], + queryFn: () => + dbCommands.listEvents({ + type: "dateRange", + user_id: userId, + start, + end, + limit: 100, + }), + }); + + const [sessions, rawEvents] = await Promise.all([ + sessionsPromise, + eventsPromise, + ]); + + // Deduplicate events by tracking_id to handle any sync issues + // Keep the most recent event (by database id) for each tracking_id + const eventsByTrackingId = new Map(); + rawEvents.forEach(event => { + const existing = eventsByTrackingId.get(event.tracking_id); + if (!existing || event.id > existing.id) { + eventsByTrackingId.set(event.tracking_id, event); + } + }); + const events = Array.from(eventsByTrackingId.values()); + + return { + ...baseData, + sessions, + events, + }; + } + + if (search.view === "folder") { + return baseData; + } + + if (search.view === "contact") { + return baseData; + } + + return baseData; + }, +}); + +export type ViewType = "folder" | "calendar" | "table" | "contact"; + +interface LoaderData { + view: ViewType; + date: Date; + sessions?: any[]; + events?: any[]; +} + +function FinderView() { + const { view, date, sessions, events } = Route.useLoaderData() as LoaderData; + const navigate = Route.useNavigate(); + const { userId } = Route.useRouteContext(); + const searchParams = Route.useSearch(); + + const handleViewChange = (newView: ViewType) => { + navigate({ + search: (prev) => ({ + ...prev, + view: newView, + }), + replace: true, + }); + }; + + const handleNavigate = (params: { date: string }) => { + navigate({ + search: (prev) => ({ + ...prev, + ...params, + }), + replace: true, + }); + }; + + return ( +
+
+ +
+ +
+ {view === "folder" && ( + + )} + {view === "calendar" && sessions && events && ( + + )} + {view === "table" && sessions && events && ( + + )} + {view === "contact" && ( + + )} +
+
+ ); +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 177f16dea6..bd29bb6c60 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,6 +1,5 @@ export * from "./ai"; export * from "./datetime"; export * from "./fetch"; -export * from "./navigation"; export * from "./organization"; export * from "./string"; diff --git a/packages/utils/src/navigation.ts b/packages/utils/src/navigation.ts deleted file mode 100644 index cc871ffd74..0000000000 --- a/packages/utils/src/navigation.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { commands as windowsCommands } from "@hypr/plugin-windows"; -import type { HyprWindow } from "@hypr/plugin-windows"; - -/** - * Safely navigate to a URL in a specific window type - * This ensures the window is visible before attempting navigation - * to prevent potential crashes in the URL scheme handler - */ -export const safeNavigate = async ( - window: HyprWindow, - url: string, - maxAttempts = 50, -): Promise => { - // First ensure the window is shown - await windowsCommands.windowShow(window); - - // Then check visibility before navigating - let attempts = 0; - - const checkAndNavigate = async (): Promise => { - try { - const isVisible = await windowsCommands.windowIsVisible(window); - - if (isVisible) { - await windowsCommands.windowEmitNavigate(window, url); - return; - } else if (attempts < maxAttempts) { - attempts++; - // If not visible yet, check again after a short delay - setTimeout(checkAndNavigate, 100); - } else { - console.error("Max attempts reached waiting for window visibility"); - } - } catch (err) { - console.error("Error during safe navigation:", err); - } - }; - - // Start checking after a short initial delay - setTimeout(checkAndNavigate, 200); -}; diff --git a/plugins/apple-calendar/src/sync.rs b/plugins/apple-calendar/src/sync.rs index 9f7499e2be..79f79e909f 100644 --- a/plugins/apple-calendar/src/sync.rs +++ b/plugins/apple-calendar/src/sync.rs @@ -124,6 +124,9 @@ async fn _sync_events( ) -> Result { let mut state = EventSyncState::default(); + // Track system events that have been handled to prevent duplicates + let mut handled_system_event_ids = std::collections::HashSet::::new(); + // Collect all system events for rescheduled event detection let all_system_events: Vec<&hypr_calendar_interface::Event> = system_events_per_selected_calendar @@ -158,6 +161,9 @@ async fn _sync_events( google_event_url: db_event.google_event_url.clone(), }; state.to_update.push(updated_event); + + // Mark this system event as handled + handled_system_event_ids.insert(matching_event.id.clone()); continue; } @@ -179,6 +185,9 @@ async fn _sync_events( google_event_url: db_event.google_event_url.clone(), }; state.to_update.push(updated_event); + + // Mark this rescheduled system event as handled to prevent duplicate creation + handled_system_event_ids.insert(rescheduled_event.id.clone()); continue; } diff --git a/plugins/windows/js/bindings.gen.ts b/plugins/windows/js/bindings.gen.ts index da93ff0acc..9373783a0f 100644 --- a/plugins/windows/js/bindings.gen.ts +++ b/plugins/windows/js/bindings.gen.ts @@ -70,7 +70,7 @@ windowDestroyed: "plugin:windows:window-destroyed" /** user-defined types **/ -export type HyprWindow = { type: "main" } | { type: "note"; value: string } | { type: "human"; value: string } | { type: "organization"; value: string } | { type: "calendar" } | { type: "settings" } | { type: "video"; value: string } | { type: "plans" } | { type: "control" } +export type HyprWindow = { type: "main" } | { type: "note"; value: string } | { type: "human"; value: string } | { type: "organization"; value: string } | { type: "finder" } | { type: "settings" } | { type: "video"; value: string } | { type: "plans" } | { type: "control" } export type KnownPosition = "left-half" | "right-half" | "center" export type MainWindowState = { left_sidebar_expanded: boolean | null; right_panel_expanded: boolean | null } export type Navigate = { path: string } diff --git a/plugins/windows/src/ext.rs b/plugins/windows/src/ext.rs index 126c9969da..14532fae2a 100644 --- a/plugins/windows/src/ext.rs +++ b/plugins/windows/src/ext.rs @@ -18,8 +18,8 @@ pub enum HyprWindow { Human(String), #[serde(rename = "organization")] Organization(String), - #[serde(rename = "calendar")] - Calendar, + #[serde(rename = "finder")] + Finder, #[serde(rename = "settings")] Settings, #[serde(rename = "video")] @@ -37,7 +37,7 @@ impl std::fmt::Display for HyprWindow { Self::Note(id) => write!(f, "note-{}", id), Self::Human(id) => write!(f, "human-{}", id), Self::Organization(id) => write!(f, "organization-{}", id), - Self::Calendar => write!(f, "calendar"), + Self::Finder => write!(f, "finder"), Self::Settings => write!(f, "settings"), Self::Video(id) => write!(f, "video-{}", id), Self::Plans => write!(f, "plans"), @@ -52,7 +52,7 @@ impl std::str::FromStr for HyprWindow { fn from_str(s: &str) -> Result { match s { "main" => return Ok(Self::Main), - "calendar" => return Ok(Self::Calendar), + "finder" => return Ok(Self::Finder), "settings" => return Ok(Self::Settings), _ => {} } @@ -143,7 +143,7 @@ impl HyprWindow { Self::Note(_) => "Note".into(), Self::Human(_) => "Human".into(), Self::Organization(_) => "Organization".into(), - Self::Calendar => "Calendar".into(), + Self::Finder => "Finder".into(), Self::Settings => "Settings".into(), Self::Video(_) => "Video".into(), Self::Plans => "Plans".into(), @@ -316,10 +316,10 @@ impl HyprWindow { .min_inner_size(480.0, 360.0) .center() .build()?, - Self::Calendar => self - .window_builder(app, "/app/calendar") - .inner_size(640.0, 532.0) - .min_inner_size(640.0, 532.0) + Self::Finder => self + .window_builder(app, "/app/finder") + .inner_size(900.0, 650.0) + .min_inner_size(800.0, 600.0) .build()?, Self::Settings => self .window_builder(app, "/app/settings")