Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Apple Reminders] Include optional overdue list view and default due date for new reminders #16294

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion extensions/apple-reminders/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Apple Reminders Changelog

## [Add todo view and option to set default date of new reminders to today] - 2025-01-11

- Add a new optional view called "Todo", which only shows overdue reminders
- Add an option to set the default date of new reminders to today.

## [Add weekdays and weekends options for recurring reminders] - 2024-12-04

- Add weekdays and weekends options for recurring reminders in the `Create Reminder` command.
Expand All @@ -18,7 +23,7 @@ The Create Reminder command will automatically pre-fill the title with the initi

## [Change AI model for Quick Add Reminder] - 2024-05-23

Now, Quick Add Reminder will use GPT-4o instead of GPT-4 Turbo.
Now, Quick Add Reminder will use GPT-4o instead of GPT-4 Turbo.

## [Add Saved Locations] - 2024-04-16

Expand Down
28 changes: 18 additions & 10 deletions extensions/apple-reminders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"jondelgado",
"phil_s",
"michalzuch",
"ridemountainpig"
"ridemountainpig",
"maxnyby"
],
"owner": "raycast",
"access": "public",
Expand Down Expand Up @@ -43,6 +44,14 @@
"label": "Use Time of Day Grouping",
"description": "When enabled, today's reminders will be grouped by the time of day they are due.",
"default": false
},
{
"name": "showTodoList",
"type": "checkbox",
"required": false,
"label": "Display Todo List",
"description": "When enabled, adds a new list showing only overdue reminders.",
"default": false
}
]
},
Expand All @@ -60,6 +69,14 @@
"description": "When enabled, the Reminders's default list will be initially selected instead of the last used list.",
"default": false,
"required": false
},
{
"name": "selectTodayAsDefault",
"type": "checkbox",
"label": "Initially select today for new reminders",
"description": "When enabled, \"Today\" will be initially selected for new reminders.",
"default": false,
"required": false
}
]
},
Expand Down Expand Up @@ -144,15 +161,6 @@
"description": "When enabled, the number of reminders will be hidden if there are no reminders left (\"Display menu bar count\" needs to be enabled)",
"default": false,
"required": false
},
{
"name": "sortMenuBarRemindersByDueDate",
"type": "checkbox",
"label": "Sort menu bar reminders by time",
"description": "When enabled, the reminders in the menu bar will be sorted by time.",
"default": false,
"required": false,
"title": "Sort"
}
],
"interval": "10m"
Expand Down
15 changes: 12 additions & 3 deletions extensions/apple-reminders/src/create-reminder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
PopToRootType,
} from "@raycast/api";
import { FormValidation, MutatePromise, useForm } from "@raycast/utils";
import { format } from "date-fns";
import { addMilliseconds, format, startOfToday } from "date-fns";
import { createReminder } from "swift:../swift/AppleReminders";

import LocationForm from "./components/LocationForm";
Expand Down Expand Up @@ -67,7 +67,7 @@ export function CreateReminderForm({ draftValues, listId, mutate }: CreateRemind

const defaultList = data?.lists.find((list) => list.isDefault);

const { selectDefaultList } = getPreferenceValues<Preferences.CreateReminder>();
const { selectDefaultList, selectTodayAsDefault } = getPreferenceValues<Preferences.CreateReminder>();
let initialListId;
if (listId !== "all") {
initialListId = listId;
Expand All @@ -77,11 +77,20 @@ export function CreateReminderForm({ draftValues, listId, mutate }: CreateRemind
initialListId = defaultList.id;
}

let initialDueDate;
if (draftValues?.dueDate) {
initialDueDate = draftValues?.dueDate;
} else if (selectTodayAsDefault) {
initialDueDate = addMilliseconds(startOfToday(), 1);
} else {
initialDueDate = draftValues?.dueDate;
}

const { itemProps, handleSubmit, focus, values, setValue } = useForm<CreateReminderValues>({
initialValues: {
title: draftValues?.title ?? "",
notes: draftValues?.notes ?? "",
dueDate: draftValues?.dueDate,
dueDate: initialDueDate,
priority: draftValues?.priority,
listId: initialListId,
isRecurring: draftValues?.isRecurring ?? false,
Expand Down
6 changes: 6 additions & 0 deletions extensions/apple-reminders/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ export function getDateString(date: string) {
export function getTodayInLocalTime() {
return formatISO(new Date(), { representation: "date" });
}
export function getTimeInLocalTime() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTodayInLocalTime() implemented above does the same thing, thing function is obsolete

return formatISO(new Date());
}

export function isPast(date: string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isOverdue() implements the same thing, this function is obsolete

return isBefore(date, isFullDay(date) ? getTimeInLocalTime() : new Date());
}
export function isOverdue(date: string) {
return isBefore(date, isFullDay(date) ? getTodayInLocalTime() : new Date());
}
Expand Down
9 changes: 6 additions & 3 deletions extensions/apple-reminders/src/hooks/useViewReminders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import React, { useMemo } from "react";
import { getCompletedReminders } from "swift:../../swift/AppleReminders";
const { useTimeOfDayGrouping } = getPreferenceValues<Preferences.MyReminders>();

import { displayDueDate, getDateString, isFullDay, isOverdue, isToday } from "../helpers";
import { displayDueDate, getDateString, isFullDay, isOverdue, isPast, isToday } from "../helpers";

import { Data, Priority, Reminder } from "./useData";

Expand Down Expand Up @@ -136,7 +136,7 @@ export function groupByDueDates(reminders: Reminder[]) {
}

const remindersOnDate = useTimeOfDayGrouping
? allDueDates.filter((date) => isBefore(date, today))
? allDueDates.filter((date) => !isBefore(date, today) && date !== today)
: allDueDates.filter((date) => date);

remindersOnDate.forEach((date) => {
Expand Down Expand Up @@ -210,7 +210,7 @@ export default function useViewReminders(listId: string, { data }: { data?: Data
{ execute: showCompletedReminders },
);

const viewDefault = listId === "today" || listId === "scheduled" ? "dueDate" : "default";
const viewDefault = listId === "today" || listId === "scheduled" || listId === "todo" ? "dueDate" : "default";

const [sortBy, setSortBy] = useCachedState<SortByOption>(`sort-by-${listId}`, viewDefault);
const [groupBy, setGroupBy] = useCachedState<GroupByOption>(`group-by-${listId}`, viewDefault);
Expand All @@ -221,6 +221,7 @@ export default function useViewReminders(listId: string, { data }: { data?: Data
if (listId === "all") return true;
if (listId === "today")
return reminder.dueDate ? isOverdue(reminder.dueDate) || isToday(reminder.dueDate) : false;
if (listId === "todo") return reminder.dueDate ? isPast(reminder.dueDate) : false;
if (listId === "scheduled") return !!reminder.dueDate;
return reminder.list?.id === listId;
};
Expand Down Expand Up @@ -298,6 +299,8 @@ export default function useViewReminders(listId: string, { data }: { data?: Data
title = "All";
} else if (listId === "today") {
title = "Today";
} else if (listId === "todo") {
title = "Todo";
} else if (listId === "scheduled") {
title = "Scheduled";
} else {
Expand Down
6 changes: 1 addition & 5 deletions extensions/apple-reminders/src/menu-bar.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was sorting removed? It doesn't seem related to the feature you are introducing.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {

import { getPriorityIcon, isOverdue, isToday, isTomorrow, truncate } from "./helpers";
import { Priority, Reminder, useData } from "./hooks/useData";
import { sortByDate } from "./hooks/useViewReminders";

const REMINDERS_FILE_ICON = "/System/Applications/Reminders.app";

Expand All @@ -47,10 +46,7 @@ export default function Command() {
const upcoming: Reminder[] = [];
const other: Reminder[] = [];

const { sortMenuBarRemindersByDueDate } = getPreferenceValues<Preferences.MenuBar>();
const sortedReminders = sortMenuBarRemindersByDueDate ? reminders.sort(sortByDate) : reminders;

sortedReminders?.forEach((reminder: Reminder) => {
reminders?.forEach((reminder: Reminder) => {
if (reminder.isCompleted) return;

if (!reminder.dueDate) {
Expand Down
5 changes: 4 additions & 1 deletion extensions/apple-reminders/src/my-reminders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useData } from "./hooks/useData";
import useViewReminders from "./hooks/useViewReminders";

export default function Command() {
const { displayCompletionDate } = getPreferenceValues<Preferences.MyReminders>();
const { displayCompletionDate, showTodoList } = getPreferenceValues<Preferences.MyReminders>();
const [listId, setListId] = useCachedState<string>("today");
const [newReminderTitle, setNewReminderTitle] = useCachedState<string>("");

Expand Down Expand Up @@ -44,6 +44,9 @@ export default function Command() {
{data?.lists && data.lists.length > 0 ? (
<>
<List.Dropdown.Section>
{!showTodoList ? null : (
<List.Dropdown.Item title="Todo" icon={{ source: Icon.List, tintColor: Color.Green }} value="todo" />
)}
<List.Dropdown.Item
title="Today"
icon={{ source: Icon.Calendar, tintColor: Color.Blue }}
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks weekdays and weekends interval introduced in previous extension updates.

Original file line number Diff line number Diff line change
Expand Up @@ -175,26 +175,9 @@ struct Recurrence: Decodable {
}

var recurrenceFrequency: EKRecurrenceFrequency
var daysOfTheWeek: [EKRecurrenceDayOfWeek]? = nil

switch recurrence.frequency {
case "daily":
recurrenceFrequency = .daily
case "weekdays":
recurrenceFrequency = .weekly
daysOfTheWeek = [
EKRecurrenceDayOfWeek(.monday),
EKRecurrenceDayOfWeek(.tuesday),
EKRecurrenceDayOfWeek(.wednesday),
EKRecurrenceDayOfWeek(.thursday),
EKRecurrenceDayOfWeek(.friday)
]
case "weekends":
recurrenceFrequency = .weekly
daysOfTheWeek = [
EKRecurrenceDayOfWeek(.saturday),
EKRecurrenceDayOfWeek(.sunday)
]
case "weekly":
recurrenceFrequency = .weekly
case "monthly":
Expand All @@ -208,12 +191,6 @@ struct Recurrence: Decodable {
let recurrenceRule = EKRecurrenceRule(
recurrenceWith: recurrenceFrequency,
interval: recurrence.interval,
daysOfTheWeek: daysOfTheWeek,
daysOfTheMonth: nil,
monthsOfTheYear: nil,
weeksOfTheYear: nil,
daysOfTheYear: nil,
setPositions: nil,
end: recurrenceEnd
)
reminder.addRecurrenceRule(recurrenceRule)
Expand Down
Loading