Skip to content

Commit

Permalink
web: add go to next/previous tab shortcut
Browse files Browse the repository at this point in the history
Signed-off-by: 01zulfi <[email protected]>
  • Loading branch information
01zulfi committed Dec 18, 2024
1 parent 6098935 commit 66b7340
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 3 deletions.
52 changes: 52 additions & 0 deletions apps/web/__e2e__/editor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,55 @@ test("#1468 count words separated by newlines", async ({ page }) => {

expect((await notes.editor.getWordCount()) === 10).toBeTruthy();
});

test("control + right arrow should go to next note", async ({ page }) => {
const app = new AppModel(page);
await app.goto();
const notes = await app.goToNotes();
const note1 = await notes.createNote({
title: "Note 1",
content: "Note 1 content"
});
const note2 = await notes.createNote({
title: "Note 2",
content: "Note 2 content"
});

await note1?.openNote();
await note2?.openNote();
await page.keyboard.press("Control+ArrowRight");

expect(await notes.editor.getTitle()).toBe("Note 1");
expect(await notes.editor.getContent("text")).toBe("Note 1 content");

await page.keyboard.press("Control+ArrowRight");

expect(await notes.editor.getTitle()).toBe("Note 2");
expect(await notes.editor.getContent("text")).toBe("Note 2 content");
});

test("control + left arrow should go to previous note", async ({ page }) => {
const app = new AppModel(page);
await app.goto();
const notes = await app.goToNotes();
const note1 = await notes.createNote({
title: "Note 1",
content: "Note 1 content"
});
const note2 = await notes.createNote({
title: "Note 2",
content: "Note 2 content"
});

await note1?.openNote();
await note2?.openNote();
await page.keyboard.press("Control+ArrowLeft");

expect(await notes.editor.getTitle()).toBe("Note 1");
expect(await notes.editor.getContent("text")).toBe("Note 1 content");

await page.keyboard.press("Control+ArrowLeft");

expect(await notes.editor.getTitle()).toBe("Note 2");
expect(await notes.editor.getContent("text")).toBe("Note 2 content");
});
21 changes: 19 additions & 2 deletions apps/web/src/components/editor/action-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { Button, Flex, Text } from "@theme-ui/components";
import { useState } from "react";
import { useEffect, useRef, useState } from "react";
import {
ArrowLeft,
Cross,
Expand Down Expand Up @@ -439,10 +439,27 @@ function Tab(props: TabProps) {
: Note;
const { attributes, listeners, setNodeRef, transform, transition, active } =
useSortable({ id });
const activeTabRef = useRef<HTMLElement | null>(null);

useEffect(() => {
if (activeTabRef.current) {
const tab = activeTabRef.current;
tab.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "nearest"
});
}
}, [isActive]);

return (
<Flex
ref={setNodeRef}
ref={(el) => {
setNodeRef(el);
if (isActive) {
activeTabRef.current = el;
}
}}
className="tab"
sx={{
borderRadius: "default",
Expand Down
10 changes: 9 additions & 1 deletion apps/web/src/components/editor/tiptap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,15 @@ function TipTap(props: TipTapProps) {
const tiptapOptions = useMemo<Partial<TiptapOptions>>(() => {
return {
editorProps: {
handleKeyDown(view, event) {
handleKeyDown(_, event) {
if (event.ctrlKey && event.key === "ArrowRight") {
event.preventDefault();
useEditorStore.getState().openNextSession("right");
}
if (event.ctrlKey && event.key === "ArrowLeft") {
event.preventDefault();
useEditorStore.getState().openNextSession("left");
}
if ((event.ctrlKey || event.metaKey) && event.key === "s") {
event.preventDefault();
onChange?.(
Expand Down
22 changes: 22 additions & 0 deletions apps/web/src/stores/editor-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,28 @@ class EditorStore extends BaseStore<EditorStore> {
}
};

openNextSession = (dir: "right" | "left") => {
const { sessions, activeSessionId } = this.get();
if (sessions.length === 0 || sessions.length === 1) return;

const index = sessions.findIndex((s) => s.id === activeSessionId);

if (index === -1) return;

switch (dir) {
case "right":
if (index === sessions.length - 1) {
return this.openSession(sessions[0].id);
}
return this.openSession(sessions[index + 1].id);
case "left":
if (index === 0) {
return this.openSession(sessions[sessions.length - 1].id);
}
return this.openSession(sessions[index - 1].id);
}
};

addSession = (session: EditorSession, activate = true) => {
let oldSessionId: string | null = null;

Expand Down

0 comments on commit 66b7340

Please sign in to comment.