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

Add notes Overview page #399

Merged
merged 2 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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`).

Expand Down
5 changes: 0 additions & 5 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
95 changes: 25 additions & 70 deletions src/notes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand All @@ -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);

Expand Down Expand Up @@ -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(() => {
Expand Down Expand Up @@ -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(() => {
Expand All @@ -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]);
Expand Down Expand Up @@ -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);
});
},
};

Expand All @@ -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(() => {
Expand Down Expand Up @@ -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 && (
Expand Down
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";

Expand Down Expand Up @@ -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,

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

toggleSidebar,
toggleToolbar,
toggleFocusMode,
};
Loading