From 90b0d529d730d373458b99070f37041ff1c89e65 Mon Sep 17 00:00:00 2001 From: David Alecrim Date: Thu, 16 May 2024 10:55:11 +0100 Subject: [PATCH] [Simple Reminder] Update the UI when no reminders are active (#12368) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: update the UI when no reminders are actibe * Update menubar on changes * Update CHANGELOG.md and optimise images --------- Co-authored-by: Per Nielsen Tikær Co-authored-by: raycastbot --- extensions/simple-reminder/CHANGELOG.md | 7 ++++ .../simple-reminder/assets/menu-bar-logo.png | Bin 0 -> 450 bytes .../assets/menu-bar-logo@dark.png | Bin 0 -> 454 bytes extensions/simple-reminder/package-lock.json | 33 +++++++++++----- extensions/simple-reminder/package.json | 4 +- .../src/handlers/createNewReminder.ts | 4 +- .../src/handlers/deleteExistingReminder.ts | 2 + .../src/handlers/setRecurrenceForReminder.ts | 4 +- .../simple-reminder/src/reminderMenuBar.tsx | 36 ++++++++++++++++-- .../src/utils/getNextReminder.ts | 5 +++ .../src/utils/updateMenubar.ts | 9 +++++ 11 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 extensions/simple-reminder/assets/menu-bar-logo.png create mode 100644 extensions/simple-reminder/assets/menu-bar-logo@dark.png create mode 100644 extensions/simple-reminder/src/utils/getNextReminder.ts create mode 100644 extensions/simple-reminder/src/utils/updateMenubar.ts diff --git a/extensions/simple-reminder/CHANGELOG.md b/extensions/simple-reminder/CHANGELOG.md index e12d0d6994b..39bf9805718 100644 --- a/extensions/simple-reminder/CHANGELOG.md +++ b/extensions/simple-reminder/CHANGELOG.md @@ -1,5 +1,12 @@ # Simple Reminder Changelog +## [Reminder Menu Bar] - 2024-05-15 + +- Add empty reminder action in reminder menu bar to show the user that no reminders are set and that they can add a new reminder +- Add a title to the reminder menu bar showing the next reminder coming up +- Reminder title in the menu bar will be shown as distance when 2 or less are remaining (e.g. daily in 5 minutes) +- Change the icon in the menu bar to reflect the system theme preference + ## [Reminder Menu Bar] - 2024-05-07 - Add a menu bar command to check the reminder list in the macOS menu bar diff --git a/extensions/simple-reminder/assets/menu-bar-logo.png b/extensions/simple-reminder/assets/menu-bar-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c6743755a16734ee031427175e0ed8ab14a73de5 GIT binary patch literal 450 zcmV;z0X_bSP)kdg0004rNklaM%%s;BPd;n(}?{78-w)+thQifk}SjwTFpg6eX@APt(KjGR}B zY&%6>kyCclfKe)lD(m!+U_N_%t0Gdj#I;dERG6jSEEPn_i>Nu|ERbaZAul2ljuCgX zlBLy+yhsRY;~ud|fE#h|RZu(6h!q0dh-a^YIw&I+32-CIUIq10Ma&c6MpV5D8b{6) z0d9o63R*(E(Mw3LTX_}mhcm=Ac|!7T#hI6xhImJ;5#d%|4QGG<0Fly9gxeHx;Pn^N z$l2mMn+SPb=N~1+BV9le33PfTZuw7*0&<=><(zmR)#sq3IlhnvD&pwA7;c$VR zD?V?|6>={4ym__nb&iN`Qp7S~wv0&WreS$55swUDJ|7U5S>*dqfeL;wH)07*qoM6N<$g6pEnEC2ui literal 0 HcmV?d00001 diff --git a/extensions/simple-reminder/assets/menu-bar-logo@dark.png b/extensions/simple-reminder/assets/menu-bar-logo@dark.png new file mode 100644 index 0000000000000000000000000000000000000000..db70872bffada190c922eda7d631b9b384782875 GIT binary patch literal 454 zcmV;%0XhDOP)kdg0004vNkl!FF}Ab<#l`723HOl-5~=`~#A|KmwpC!c4z-+g(Wca7~R-^R7^c)^4QHlln34HNN#8EurJyo9!y zc)=oAit;6}7%$kwU(-=O9VnYIoO6mF^3j5Ppq$F}#&6tVH_4D)+?Eo}Xtx6m?~^ecJisGI9dbN=95KIvbI;Ko;9+<;;- wh@^G^z>YK-R2J;{8N6p9d8!N>e(vAzKl*V6zRyY@F#rGn07*qoM6N<$g4D^<$p8QV literal 0 HcmV?d00001 diff --git a/extensions/simple-reminder/package-lock.json b/extensions/simple-reminder/package-lock.json index acb43f48e0c..818e36eab09 100644 --- a/extensions/simple-reminder/package-lock.json +++ b/extensions/simple-reminder/package-lock.json @@ -7,8 +7,8 @@ "name": "simple-reminder", "license": "MIT", "dependencies": { - "@raycast/api": "^1.69.3", - "@raycast/utils": "^1.13.3", + "@raycast/api": "^1.73.3", + "@raycast/utils": "^1.15.0", "chrono-node": "^2.6.3", "date-fns": "^3.6.0", "natural": "^6.2.0" @@ -156,9 +156,9 @@ } }, "node_modules/@raycast/api": { - "version": "1.69.3", - "resolved": "https://registry.npmjs.org/@raycast/api/-/api-1.69.3.tgz", - "integrity": "sha512-mhG0Nu6T+qZFe1gjuUJwavcOSlHEVZBHnS+ISQj5rmStQhLFqLR/xlENII65e3lQ7IZe8/EP4avsds0Ck7UdOA==", + "version": "1.73.3", + "resolved": "https://registry.npmjs.org/@raycast/api/-/api-1.73.3.tgz", + "integrity": "sha512-7HK5MtJCrB1yk7ROvEcVeJkZlkg/vbNJubh8YVHqeq4ejXn069qAfWhb7unIVYnrQYnsCBqx4MIXKFHDydjINg==", "hasInstallScript": true, "dependencies": { "@types/node": "^20.8.10", @@ -225,16 +225,18 @@ } }, "node_modules/@raycast/utils": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@raycast/utils/-/utils-1.13.3.tgz", - "integrity": "sha512-PfR1mcHN1lfk7XgYEozTcGVFA0FSKkc9WxPmcqWo3YrcF/h7Wj2bIKZ88uA6Zb0TpzDhRcmvNvEvvG7THEZooQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@raycast/utils/-/utils-1.15.0.tgz", + "integrity": "sha512-fVHT+9S0EotXGlWH779wSZMpGHGc13kSpA/m5CBUwkd1MRtWWbSuMs5ObJ46KRBAAYJQBSnm4eDck935WtUONQ==", "dependencies": { "content-type": "^1.0.5", "cross-fetch": "^3.1.6", "dequal": "^2.0.3", "media-typer": "^1.1.0", "object-hash": "^3.0.0", - "signal-exit": "^4.0.2" + "signal-exit": "^4.0.2", + "stream-chain": "^2.2.5", + "stream-json": "^1.8.0" }, "peerDependencies": { "@raycast/api": ">=1.69.0" @@ -1784,6 +1786,19 @@ "node": ">=0.10.0" } }, + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==" + }, + "node_modules/stream-json": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.8.0.tgz", + "integrity": "sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==", + "dependencies": { + "stream-chain": "^2.2.5" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", diff --git a/extensions/simple-reminder/package.json b/extensions/simple-reminder/package.json index 601a71dbea8..e4e4c8a6356 100644 --- a/extensions/simple-reminder/package.json +++ b/extensions/simple-reminder/package.json @@ -59,8 +59,8 @@ } ], "dependencies": { - "@raycast/api": "^1.69.3", - "@raycast/utils": "^1.13.3", + "@raycast/api": "^1.73.3", + "@raycast/utils": "^1.15.0", "chrono-node": "^2.6.3", "natural": "^6.2.0", "date-fns": "^3.6.0" diff --git a/extensions/simple-reminder/src/handlers/createNewReminder.ts b/extensions/simple-reminder/src/handlers/createNewReminder.ts index 61bd1619409..c78f2972796 100644 --- a/extensions/simple-reminder/src/handlers/createNewReminder.ts +++ b/extensions/simple-reminder/src/handlers/createNewReminder.ts @@ -1,7 +1,8 @@ -import { Reminder } from "../types/reminder"; import { LocalStorage, showToast, Toast } from "@raycast/api"; +import { Reminder } from "../types/reminder"; import { dateSortPredicate } from "../utils/dateSortPredicate"; import Style = Toast.Style; +import { updateMenubar } from "../utils/updateMenubar"; type CreateNewReminderProps = { reminder: Reminder; @@ -21,4 +22,5 @@ export async function createNewReminder(props: CreateNewReminderProps) { await LocalStorage.setItem(props.reminder.id, JSON.stringify(props.reminder)); props.setSearchText(""); await showToast(Style.Success, "Reminder set", "When the time is right, we'll notify you!"); + await updateMenubar(); } diff --git a/extensions/simple-reminder/src/handlers/deleteExistingReminder.ts b/extensions/simple-reminder/src/handlers/deleteExistingReminder.ts index 86ac5f0c501..c5843a34555 100644 --- a/extensions/simple-reminder/src/handlers/deleteExistingReminder.ts +++ b/extensions/simple-reminder/src/handlers/deleteExistingReminder.ts @@ -2,6 +2,7 @@ import { Alert, Color, confirmAlert, Icon, LocalStorage, showToast, Toast } from import { Reminder } from "../types/reminder"; import ActionStyle = Alert.ActionStyle; import Style = Toast.Style; +import { updateMenubar } from "../utils/updateMenubar"; type DeleteReminderProps = { reminderId: string; @@ -31,5 +32,6 @@ export async function deleteExistingReminder(props: DeleteReminderProps) { props.setReminders(props.existingReminders.filter((existingReminder) => existingReminder.id !== props.reminderId)); await LocalStorage.removeItem(props.reminderId); await showToast(Style.Success, "Reminder deleted", "This reminder will no longer pester you!"); + await updateMenubar(); } } diff --git a/extensions/simple-reminder/src/handlers/setRecurrenceForReminder.ts b/extensions/simple-reminder/src/handlers/setRecurrenceForReminder.ts index 32c9c510f4e..ed3d6ceddd2 100644 --- a/extensions/simple-reminder/src/handlers/setRecurrenceForReminder.ts +++ b/extensions/simple-reminder/src/handlers/setRecurrenceForReminder.ts @@ -1,6 +1,7 @@ -import { LocalStorage } from "@raycast/api"; +import { LocalStorage, showToast, Toast } from "@raycast/api"; import { Frequency } from "../types/frequency"; import { Reminder } from "../types/reminder"; +import Style = Toast.Style; type SetRecurrenceForReminderProps = { reminderId: string; @@ -14,4 +15,5 @@ export async function setRecurrenceForReminder(props: SetRecurrenceForReminderPr reminder.frequency = props.frequency; props.setReminders([...props.existingReminders]); await LocalStorage.setItem(reminder.id, JSON.stringify(reminder)); + await showToast(Style.Success, "Recurrence set", `Happening ${props.frequency}`); } diff --git a/extensions/simple-reminder/src/reminderMenuBar.tsx b/extensions/simple-reminder/src/reminderMenuBar.tsx index 1d4dba7463e..a0ee138f3db 100644 --- a/extensions/simple-reminder/src/reminderMenuBar.tsx +++ b/extensions/simple-reminder/src/reminderMenuBar.tsx @@ -1,9 +1,21 @@ -import { Action, MenuBarExtra, Clipboard } from "@raycast/api"; -import { hasFrequencyPredicate, hasNoFrequencyPredicate } from "./utils/arrayPredicates"; +import { MenuBarExtra, Clipboard, open, Cache } from "@raycast/api"; import { useMemo, useState } from "react"; +import { formatDistance } from "date-fns/formatDistance"; import { useFetchStoredReminders } from "./hooks/useFetchStoredReminders"; +import { hasFrequencyPredicate, hasNoFrequencyPredicate } from "./utils/arrayPredicates"; +import { getNextReminder } from "./utils/getNextReminder"; import { Reminder } from "./types/reminder"; +const addReminderDeeplink = `raycast://extensions/comoser/simple-reminder/index`; +const raycastApplication = { name: "Raycast", path: "/Applications/Raycast.app" }; +const TWO_HOURS_IN_MS = 2 * 60 * 60 * 1000; + +function getDateTimeStringForMenuBarTitle(date: Date): string { + if (date.getTime() - new Date().getTime() < TWO_HOURS_IN_MS) + return formatDistance(date, new Date().toLocaleString(), { addSuffix: true }); + return date.toLocaleString(); +} + export default function Command() { const [isLoading, setIsLoading] = useState(true); const [reminders, setReminders] = useState([]); @@ -12,12 +24,30 @@ export default function Command() { useFetchStoredReminders(setReminders, setIsLoading); + const showNextReminderInMenuBarTitle = () => { + const nextReminder = getNextReminder(reminders); + if (!nextReminder) return "No reminders set"; + return `${nextReminder.topic} ${getDateTimeStringForMenuBarTitle(nextReminder.date)}`; + }; + const onCopyReminderTopicAction = (reminderTopic: string) => { return async () => await Clipboard.copy(reminderTopic); }; + const onOpenAddReminderAction = () => { + void open(addReminderDeeplink, raycastApplication); + }; + return ( - + + {!isLoading && !recurrentReminders.length && !otherReminders.length && ( + + )} {recurrentReminders.length ? ( {recurrentReminders.map((reminder) => ( diff --git a/extensions/simple-reminder/src/utils/getNextReminder.ts b/extensions/simple-reminder/src/utils/getNextReminder.ts new file mode 100644 index 00000000000..a9325ac78ca --- /dev/null +++ b/extensions/simple-reminder/src/utils/getNextReminder.ts @@ -0,0 +1,5 @@ +import { Reminder } from "../types/reminder"; + +export function getNextReminder(reminders: Reminder[]): Reminder | undefined { + return reminders.find((reminder) => reminder.date.getTime() > new Date().getTime()); +} diff --git a/extensions/simple-reminder/src/utils/updateMenubar.ts b/extensions/simple-reminder/src/utils/updateMenubar.ts new file mode 100644 index 00000000000..63bc6d3be51 --- /dev/null +++ b/extensions/simple-reminder/src/utils/updateMenubar.ts @@ -0,0 +1,9 @@ +import { launchCommand, LaunchType } from "@raycast/api"; + +export async function updateMenubar() { + try { + await launchCommand({ name: "reminderMenuBar", type: LaunchType.Background }); + } catch { + // Silent fail, since this will automatically update in 1 minute or when the user clicks the reminder menu bar + } +}