Skip to content

Commit

Permalink
Apple Notes: Add text to note (raycast#12017)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomaslombart committed Apr 26, 2024
1 parent 930fc91 commit 52057f9
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 25 deletions.
4 changes: 4 additions & 0 deletions extensions/apple-notes/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Apple Notes Changelog

## [Add text to note] - 2024-04-26

Add a new command called `Add Text to Note` allowing you to quickly append text to your notes for faster note-taking. You can also add text to a note from the `Search Notes command`.

## [Use new URI scheme] - 2024-04-25

Merge `Copy Mobile Note URL` into `Copy Note URL` by using the `applenotes://` scheme that works on all platforms.
Expand Down
23 changes: 15 additions & 8 deletions extensions/apple-notes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
{
"name": "index",
"title": "Search Notes",
"subtitle": "Notes",
"description": "Search notes in the Apple Notes app.",
"subtitle": "Apple Notes",
"description": "Search through your Apple notes.",
"mode": "view"
},
{
"name": "new",
"title": "New Note",
"subtitle": "Notes",
"description": "Create a new note in the Apple Notes app.",
"subtitle": "Apple Notes",
"description": "Create a new note in your Apple Notes.",
"mode": "no-view",
"keywords": [
"write note",
Expand All @@ -48,8 +48,8 @@
{
"name": "ai",
"title": "AI Note",
"subtitle": "Notes",
"description": "Create a new note filled with AI in the Apple Notes app.",
"subtitle": "Apple Notes",
"description": "Create a new note filled with AI in your Apple notes.",
"mode": "no-view",
"arguments": [
{
Expand All @@ -68,8 +68,8 @@
{
"name": "menu-bar",
"title": "Menu Bar Notes",
"subtitle": "Notes",
"description": "View your recent and pinned notes in the menu bar.",
"subtitle": "Apple Notes",
"description": "View your recent and pinned Apple notes in the menu bar.",
"mode": "menu-bar",
"preferences": [
{
Expand All @@ -81,6 +81,13 @@
"required": false
}
]
},
{
"name": "add-text",
"title": "Add Text to Note",
"subtitle": "Apple Notes",
"description": "Add some text to an Apple note.",
"mode": "view"
}
],
"preferences": [
Expand Down
7 changes: 7 additions & 0 deletions extensions/apple-notes/src/add-text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { LaunchProps } from "@raycast/api";

import AddTextForm from "./components/AddTextForm";

export default function AddTextToNote(props: LaunchProps) {
return <AddTextForm draftValues={props.draftValues} />;
}
8 changes: 8 additions & 0 deletions extensions/apple-notes/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,11 @@ export async function getNotePlainText(id: string) {
end tell
`);
}
export async function setNoteBody(id: string, body: string) {
return runAppleScript(`
tell application "Notes"
set theNote to note id "${escapeDoubleQuotes(id)}"
set body of theNote to "${escapeDoubleQuotes(body)}"
end tell
`);
}
91 changes: 91 additions & 0 deletions extensions/apple-notes/src/components/AddTextForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Action, ActionPanel, Form, Icon, Toast, closeMainWindow, showToast, useNavigation } from "@raycast/api";
import { FormValidation, showFailureToast, useForm } from "@raycast/utils";

import { getNoteBody, setNoteBody } from "../api";
import { useNotes } from "../useNotes";

type AddTextFormProps = {
draftValues?: Form.Values;
noteId?: string;
};

type AddTextFormValues = {
note: string;
prepend: boolean;
text: string;
};

export default function AddTextForm({ draftValues, noteId }: AddTextFormProps) {
const { data, isLoading, permissionView } = useNotes();
const { pop } = useNavigation();

if (permissionView) {
return permissionView;
}

const { itemProps, handleSubmit, reset } = useForm<AddTextFormValues>({
async onSubmit(values) {
const noteTitle =
[...data.pinnedNotes, ...data.unpinnedNotes].find((note) => note.id === values.note)?.title || "Note";

try {
await showToast({ style: Toast.Style.Animated, title: `Adding text to "${noteTitle}"` });
const noteBody = await getNoteBody(values.note);
const text = values.prepend ? `${values.text}\n\n${noteBody}` : `${noteBody}\n\n${values.text}`;
await setNoteBody(values.note, text);
if (noteId) {
await pop();
} else {
await closeMainWindow();
}
await showToast({ style: Toast.Style.Success, title: `Added text to "${noteTitle}"` });

reset({ text: "" });
} catch (error) {
await showFailureToast(error, { title: `Failed adding text to "${noteTitle}"` });
}
},
initialValues: {
note: noteId ?? draftValues?.note ?? "",
text: draftValues?.text ?? "",
prepend: draftValues?.prepend ?? false,
},
validation: {
note: FormValidation.Required,
text: FormValidation.Required,
},
});

return (
<Form
actions={
<ActionPanel>
<Action.SubmitForm onSubmit={handleSubmit} title="Add Text to Note" icon={Icon.Plus} />
</ActionPanel>
}
isLoading={isLoading}
enableDrafts={!noteId}
>
<Form.Dropdown {...itemProps.note} title="Note" isLoading={isLoading} storeValue>
<Form.Dropdown.Section>
{data.pinnedNotes.map((note) => {
return <Form.Dropdown.Item key={note.id} title={note.title} value={note.id} icon="notes-icon.png" />;
})}

{data.unpinnedNotes.map((note) => {
return <Form.Dropdown.Item key={note.id} title={note.title} value={note.id} icon="notes-icon.png" />;
})}
</Form.Dropdown.Section>
</Form.Dropdown>

<Form.TextArea enableMarkdown title="Text" {...itemProps.text} />

<Form.Checkbox
{...itemProps.prepend}
label="Add text at the top"
info="If checked, the text will be added at the top of the note instead of the bottom"
storeValue
/>
</Form>
);
}
44 changes: 27 additions & 17 deletions extensions/apple-notes/src/components/NoteActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { deleteNoteById, restoreNoteById, openNoteSeparately, getNotePlainText,
import { fileIcon } from "../helpers";
import { NoteItem, useNotes } from "../useNotes";

import AddTextForm from "./AddTextForm";
import NoteDetail from "./NoteDetail";

const preferences = getPreferenceValues<Preferences>();
Expand Down Expand Up @@ -103,24 +104,33 @@ export default function NoteActions({ noteTitles, note, isDeleted, isDetail, mut
/>
{secondaryOpen}

{noteTitles ? <RelatedNotes noteTitles={noteTitles} note={note} /> : null}

{isDeleted ? (
<Action
title="Restore to Notes Folder"
icon={Icon.ArrowCounterClockwise}
onAction={restoreNote}
shortcut={{ modifiers: ["cmd", "shift"], key: "r" }}
/>
) : (
<Action
title="Delete Note"
icon={Icon.Trash}
style={Action.Style.Destructive}
onAction={deleteNote}
shortcut={Keyboard.Shortcut.Common.Remove}
<ActionPanel.Section>
<Action.Push
title="Add Text to Note"
icon={Icon.Plus}
shortcut={{ modifiers: ["cmd", "shift"], key: "a" }}
target={<AddTextForm noteId={note.id} />}
/>
)}

{noteTitles ? <RelatedNotes noteTitles={noteTitles} note={note} /> : null}

{isDeleted ? (
<Action
title="Restore to Notes Folder"
icon={Icon.ArrowCounterClockwise}
onAction={restoreNote}
shortcut={{ modifiers: ["cmd", "shift"], key: "r" }}
/>
) : (
<Action
title="Delete Note"
icon={Icon.Trash}
style={Action.Style.Destructive}
onAction={deleteNote}
shortcut={Keyboard.Shortcut.Common.Remove}
/>
)}
</ActionPanel.Section>

<ActionPanel.Section>
<Action.CopyToClipboard
Expand Down

0 comments on commit 52057f9

Please sign in to comment.