From 18c2b42852f1e75b2c55262fb9fa48052afe8af5 Mon Sep 17 00:00:00 2001 From: Natsumi Date: Fri, 7 Nov 2025 01:22:33 +1100 Subject: [PATCH] Calendar local datetime format and download buttons --- Dotnet/AppApi/Cef/AppApiCef.cs | 23 ++++ Dotnet/AppApi/Common/AppApiCommonBase.cs | 1 + Dotnet/AppApi/Electron/AppApiElectron.cs | 4 + src/components/NavMenu.vue | 3 +- src/localization/en/en.json | 6 +- src/shared/utils/base/date.js | 117 ++++++++++-------- src/shared/utils/base/format.js | 2 + src/types/globals.d.ts | 1 + .../components/GroupCalendarEventCard.vue | 62 +++++++++- .../Tools/dialogs/GroupCalendarDialog.vue | 5 +- 10 files changed, 164 insertions(+), 60 deletions(-) diff --git a/Dotnet/AppApi/Cef/AppApiCef.cs b/Dotnet/AppApi/Cef/AppApiCef.cs index 27efe3b6..50e64eae 100644 --- a/Dotnet/AppApi/Cef/AppApiCef.cs +++ b/Dotnet/AppApi/Cef/AppApiCef.cs @@ -221,5 +221,28 @@ namespace VRCX { MainForm.Instance.BeginInvoke(new MethodInvoker(() => { MainForm.Instance.SetTrayIconNotification(notify); })); } + + public override void OpenCalendarFile(string icsContent) + { + // validate content + if (!icsContent.StartsWith("BEGIN:VCALENDAR") || + !icsContent.EndsWith("END:VCALENDAR")) + throw new Exception("Invalid calendar file"); + + try + { + var tempPath = Path.Combine(Program.AppDataDirectory, "event.ics"); + File.WriteAllText(tempPath, icsContent); + Process.Start(new ProcessStartInfo + { + FileName = tempPath, + UseShellExecute = true + })?.Dispose(); + } + catch (Exception ex) + { + logger.Error(ex, "Failed to open calendar file"); + } + } } } \ No newline at end of file diff --git a/Dotnet/AppApi/Common/AppApiCommonBase.cs b/Dotnet/AppApi/Common/AppApiCommonBase.cs index 08da47eb..27336122 100644 --- a/Dotnet/AppApi/Common/AppApiCommonBase.cs +++ b/Dotnet/AppApi/Common/AppApiCommonBase.cs @@ -28,6 +28,7 @@ namespace VRCX public abstract void CopyImageToClipboard(string path); public abstract void FlashWindow(); public abstract void SetUserAgent(); + public abstract void OpenCalendarFile(string icsContent); // Folders public abstract string GetVRChatAppDataLocation(); diff --git a/Dotnet/AppApi/Electron/AppApiElectron.cs b/Dotnet/AppApi/Electron/AppApiElectron.cs index a491c1be..c59dab33 100644 --- a/Dotnet/AppApi/Electron/AppApiElectron.cs +++ b/Dotnet/AppApi/Electron/AppApiElectron.cs @@ -147,5 +147,9 @@ namespace VRCX public override void SetTrayIconNotification(bool notify) { } + + public override void OpenCalendarFile(string icsContent) + { + } } } \ No newline at end of file diff --git a/src/components/NavMenu.vue b/src/components/NavMenu.vue index 32f05b0a..6b075553 100644 --- a/src/components/NavMenu.vue +++ b/src/components/NavMenu.vue @@ -7,7 +7,8 @@ :width="50" :stroke-width="3" :percentage="updateProgress" - :format="updateProgressText"> + :format="updateProgressText" + style="padding: 7px">
; SetUserAgent(): Promise; SetTrayIconNotification(notify: boolean): Promise; + OpenCalendarFile(icsContent: string): Promise; // Common Functions GetColourFromUserID(userId: string): Promise; diff --git a/src/views/Tools/components/GroupCalendarEventCard.vue b/src/views/Tools/components/GroupCalendarEventCard.vue index 66e2b967..632cc825 100644 --- a/src/views/Tools/components/GroupCalendarEventCard.vue +++ b/src/views/Tools/components/GroupCalendarEventCard.vue @@ -14,6 +14,16 @@
+ + {{ + t('dialog.group_calendar.event_card.export_to_calendar') + }} + + + {{ + t('dialog.group_calendar.event_card.download_ics') + }} + {{ capitalizeFirst(event.category) }} @@ -24,7 +34,7 @@ {{ event.closeInstanceAfterEndMinutes + ' min' }} - {{ dayjs(event.createdAt).format('YYYY-MM-DD HH:mm') }} + {{ formatDateFilter(event.createdAt, 'long') }} {{ event.description }} @@ -53,12 +63,13 @@