Skip to content

Commit

Permalink
Merge pull request #399 from penge/notes-overview
Browse files Browse the repository at this point in the history
Add notes Overview page
penge authored Sep 8, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 1d6988b + 2837783 commit 870c7ee
Showing 15 changed files with 229 additions and 377 deletions.
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -59,16 +59,26 @@

## Context menu

Context menu allows you to quickly save selected text from any website to My Notes, or to transfer selected text to My Notes on other computers.
Context menu can be displayed on right-click on any website and based on the context used to quickly save:

To use Context menu, select the text on website, right-click and see "My Notes" Context menu.
<ol type="a">
<li>selected text</li>
<li>current page URL (right-click on an empty space)</li>
<li>image</li>
</ol>

Destination can be any local note, or My Notes on other computers.

Options are based on the context but in general are:

Context menu has these options:
- `Save to [note name]` – Option for every note. My Notes doesn't have to be open. Google Drive Sync is not required.
- `Save to remotely open My Notes` – My Notes on other computers needs to be open. The same Google Account needs to be used. Google Drive Sync is not required. The destination note will be named `@received`.

- `Save to [note name]` – Option for every note. As you create new notes, they are automatically added to the list. My Notes doesn't have to be open. Google Drive Sync is not required.
- `Save to remotely open My Notes` – My Notes on other computers needs to be open. The same Google Account needs to be used. Google Drive Sync is not required. The destination note to save the text will be named **"@received"** (created automatically if it doesn't exist, otherwise updated).
There is a few general purpose notes that can be used as destination. Their name starts with `@` and they are created automatically when needed:

Context menu also allows you to save current page URL (no text selected) to **"@clipboard"** (created automatically if it doesn't exist, otherwise updated).
- `@received`
- `@clipboard`
- `@images`

<br><br>

@@ -87,17 +97,11 @@ Click on the **"Save"** button to save the custom theme.

## Command palette

Command palette is a window which you can open with `Cmd + P` (or `Ctrl + P`) and use your keyboard to quickly perform any of the following actions:

<ol type="A">
<li>Find note(s) <b>by their name,</b> and open one. (default behavior)</li>
<li>Find note(s) <b>by their content,</b> and open one. (type <code>?</code> first, then continue)</li>
<li>Find <b>commands,</b> and execute one. (type <code>></code> first, then continue)</li>
</ol>
Command palette is a window which you can open with `Cmd + P` (or `Ctrl + P`) and use your keyboard to quickly find <b>commands,</b> and execute one.

To navigate between the results, use `Up` and `Down` arrow keys.
To navigate between the commands, use `Up` and `Down` arrow keys.

To open a selected note or execute a selected command, press `Enter`.
To execute a selected command, press `Enter`.

The last executed command can be repeated with `Cmd + Shift + P` (or `Ctrl + Shift + P`).

5 changes: 0 additions & 5 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
@@ -138,11 +138,6 @@
"Options": "Options",
"Sync notes to and from Google Drive": "Sync notes to and from Google Drive",
"Command palette": "Command palette",
"Command palette detail": {
"line1": "By default, Command palette looks for notes <b>by their name.</b>",
"line2": "Type {{symbol}} first, and continue to start search for <b>commands.</b>",
"line3": "Type {{symbol}} first, and continue to start search for notes <b>by their content.</b>"
},
"Repeat last command": "Repeat last command",
"Toggle Focus mode": "Toggle Focus mode",
"Toggle Sidebar": "Toggle Sidebar",
95 changes: 25 additions & 70 deletions src/notes.tsx
Original file line number Diff line number Diff line change
@@ -2,9 +2,8 @@
/* eslint-disable react/jsx-pascal-case */
import { h, render, Fragment } from "preact";
import {
useState, useEffect, useRef, useCallback, useMemo,
useState, useEffect, useRef, useCallback,
} from "preact/hooks";

import {
Os,
Storage,
@@ -44,17 +43,17 @@ import {
} from "notes/content/save";
import sendMessage from "shared/messages/send";

import { getActiveFromUrl, getFocusOverride } from "notes/location";
import { getActiveFromUrl, getFocusOverride, isOverview } from "notes/location";
import Overview from "notes/overview/Overview";
import getFirstAvailableNoteName from "notes/filters/get-first-available-note-name";
import notesHistory from "notes/history";
import keyboardShortcuts, { KeyboardShortcut } from "notes/keyboard-shortcuts";
import { useKeyboardShortcut } from "notes/hooks/use-keyboard-shortcut";
import {
Command, commands, toggleSidebar, toggleToolbar,
Command, toggleSidebar, toggleToolbar, toggleFocusMode,
} from "notes/commands";
import { exportNote } from "notes/export";
import { notesToSidebarNotes } from "notes/adapters";
import { t } from "i18n";

let autoSyncIntervalId: number | undefined;

@@ -68,6 +67,8 @@ const Notes = (): h.JSX.Element => {
const [tabId, setTabId] = useState<number | undefined>(undefined);
const [initialized, setInitialized] = useState<boolean>(false);

const [view] = useState<"default" | "overview">(isOverview() ? "overview" : "default");

// Notifications
const [notification, setNotification] = useState<Notification | undefined>(undefined);

@@ -382,8 +383,8 @@ const Notes = (): h.JSX.Element => {

// Sidebar
useEffect(() => {
document.body.classList.toggle("with-sidebar", sidebar);
}, [sidebar]);
document.body.classList.toggle("with-sidebar", view === "default" && sidebar);
}, [sidebar, view]);

// Sidebar width
useEffect(() => {
@@ -433,8 +434,8 @@ const Notes = (): h.JSX.Element => {
raw: note.raw || false,
});

document.title = note ? notesProps.active : "My Notes";
}, [notesProps.active]);
document.title = (view === "default" && note) ? notesProps.active : "My Notes";
}, [notesProps.active, view]);

// Toolbar
useEffect(() => {
@@ -459,18 +460,10 @@ const Notes = (): h.JSX.Element => {
});
});
keyboardShortcuts.subscribe(KeyboardShortcut.OnOpenOptions, chrome.runtime.openOptionsPage);
keyboardShortcuts.subscribe(KeyboardShortcut.OnToggleFocusMode, () => {
if (getFocusOverride()) {
return;
}
chrome.storage.local.get(["focus"], (local) => {
chrome.storage.local.set({ focus: !local.focus });
});
});

keyboardShortcuts.subscribe(KeyboardShortcut.OnToggleSidebar, toggleSidebar);

keyboardShortcuts.subscribe(KeyboardShortcut.OnToggleToolbar, toggleToolbar);
keyboardShortcuts.subscribe(KeyboardShortcut.OnToggleFocusMode, toggleFocusMode);

keyboardShortcuts.subscribe(KeyboardShortcut.OnSync, () => sendMessage(MessageType.SYNC));
}, [os]);
@@ -504,73 +497,29 @@ const Notes = (): h.JSX.Element => {
chrome.storage.local.set({ active: noteName });
}, [notesProps]);

// Command Palette
const commandPaletteCommands: { name: string, translation: h.JSX.Element, command: Command }[] = useMemo(() => [
{
name: "Insert current Date",
translation: t("Insert current Date"),
command: commands.InsertCurrentDate,
},
{
name: "Insert current Time",
translation: t("Insert current Time"),
command: commands.InsertCurrentTime,
},
{
name: "Insert current Date and Time",
translation: t("Insert current Date and Time"),
command: commands.InsertCurrentDateAndTime,
},
{
name: "Toggle Sidebar",
translation: t("Shortcuts descriptions.Toggle Sidebar"),
command: toggleSidebar,
},
{
name: "Toggle Toolbar",
translation: t("Shortcuts descriptions.Toggle Toolbar"),
command: toggleToolbar,
},
], []);

// Repeat last executed command
const [setOnRepeatLastExecutedCommandHandler] = useKeyboardShortcut(KeyboardShortcut.OnRepeatLastExecutedCommand);

// Command Palette
const [setOnToggleCommandPaletteHandler] = useKeyboardShortcut(KeyboardShortcut.OnToggleCommandPalette);
useEffect(() => {
if (!notesOrder) {
return;
}

// Detach when there are no notes
if (!Object.keys(notesProps.notes).length) {
setOnToggleCommandPaletteHandler(undefined);
setCommandPaletteProps(null);
return;
}

// Start preparing props for Command Palette
const currentNoteLocked: boolean = notesProps.active in notesProps.notes && notesProps.notes[notesProps.active].locked === true;
const newCommands = currentNoteLocked ? [] : commandPaletteCommands;

// Props for Command Palette
const currentNoteLocked: boolean = notesProps.active in notesProps.notes && notesProps.notes[notesProps.active].locked === true;
const props: CommandPaletteProps = {
notes: notesToSidebarNotes(notesProps.notes, notesOrder, order),
commands: newCommands,
onActivateNote: (noteName: string) => {
includeContentCommands: !currentNoteLocked,
onCommandToExecute: (command: Command) => {
setCommandPaletteProps(null);
range.restore(() => handleOnActivateNote(noteName));
},
onExecuteCommand: (commandName: string) => {
const foundCommand = commandPaletteCommands.find((command) => command.name === commandName);
if (foundCommand) {
setCommandPaletteProps(null);
range.restore(() => {
foundCommand.command();
setOnRepeatLastExecutedCommandHandler(foundCommand.command);
});
}
range.restore(() => {
command();
setOnRepeatLastExecutedCommandHandler(command);
});
},
};

@@ -589,7 +538,7 @@ const Notes = (): h.JSX.Element => {

// Update props for already visible Command Palette
setCommandPaletteProps((prev) => (!prev ? prev : props));
}, [os, notesProps, notesOrder, order, handleOnActivateNote, commandPaletteCommands]);
}, [notesProps]);

// Automatically show modal to create a new note if there are 0 notes
useEffect(() => {
@@ -620,6 +569,12 @@ const Notes = (): h.JSX.Element => {
}, 6000); // and then Auto Sync every 6 seconds
}, [initialized, autoSync]);

if (view === "overview" && notesOrder && order) {
return (
<Overview notes={notesToSidebarNotes(notesProps.notes, notesOrder, order)} />
);
}

return (
<Fragment>
{notification && (
23 changes: 18 additions & 5 deletions src/notes/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dateUtils from "shared/date/date-utils";
import { getFocusOverride } from "notes/location";
import { getFocusOverride, isOverview } from "notes/location";
import table from "./table";
import highlight from "./highlight";

@@ -94,32 +94,44 @@ const commands: { [key in AvailableCommand]: Command } = {
RemoveFormat,
};

const canToggle = () => !getFocusOverride() && !isOverview();

const toggleSidebar: Command = () => {
if (getFocusOverride()) {
if (!canToggle()) {
return;
}

chrome.storage.local.get(["focus"], (local) => {
if (!local.focus) { // toggle only if not in focus mode
if (!local.focus) { // toggle only if NOT in focus mode
const hasSidebar = document.body.classList.toggle("with-sidebar");
chrome.storage.local.set({ sidebar: hasSidebar });
}
});
};

const toggleToolbar: Command = () => {
if (getFocusOverride()) {
if (!canToggle()) {
return;
}

chrome.storage.local.get(["focus"], (local) => {
if (!local.focus) { // toggle only if not in focus mode
if (!local.focus) { // toggle only if NOT in focus mode
const hasToolbar = document.body.classList.toggle("with-toolbar");
chrome.storage.local.set({ toolbar: hasToolbar });
}
});
};

const toggleFocusMode: Command = () => {
if (!canToggle()) {
return;
}

chrome.storage.local.get(["focus"], (local) => {
chrome.storage.local.set({ focus: !local.focus });
});
};

export {
commands,

@@ -133,4 +145,5 @@ export {

toggleSidebar,
toggleToolbar,
toggleFocusMode,
};
Loading

0 comments on commit 870c7ee

Please sign in to comment.