Skip to content
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
8 changes: 7 additions & 1 deletion src/lib/components/QuickNote.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script lang="ts">
import { onMount } from 'svelte';
import { invalidateAll } from '$app/navigation';
import { modLabel } from '$lib/keys';
import { quickNote, openQuickNote, closeQuickNote } from '$lib/quick-note.svelte';

// The quick-note jot: a small card floating over the editor, opened with
Expand All @@ -17,6 +19,10 @@
sceneId?: string | null;
} = $props();

// The platform's command modifier for the hint line; SSR says Ctrl.
let mod = $state<'Cmd' | 'Ctrl'>('Ctrl');
onMount(() => (mod = modLabel()));

let text = $state('');
let saving = $state(false);
let message = $state<string | null>(null);
Expand Down Expand Up @@ -115,7 +121,7 @@
<p class="qn-error" role="alert">{message}</p>
{/if}
<footer class="qn-foot">
<span class="qn-hint">Ctrl+Enter saves, Esc closes.</span>
<span class="qn-hint">{mod}+Enter saves, Esc closes.</span>
<button class="btn btn-sm btn-ghost" type="button" onclick={close}>Close</button>
<button
class="btn btn-sm btn-primary"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/docs/planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ If you run a campaign, a note per sitting works well: keep the running log in a

A note can also be attached to one scene. In the editor, open the Notes panel on the right and select "New note on this scene": the note is made, attached, and opened in the Notes view for you to write. From then on it shows at the top of the Notes panel whenever the scene is open, and in the story's note list like any other note.

To jot something down without leaving the editor, press Ctrl+Alt+N (Cmd+Alt+N on a Mac) or run "Quick note" from the command palette. A small card opens over the editor: write the thought, then Ctrl+Enter or "Save note" files it with the story's notes - attached to the open scene when there is one - and puts you back where you were. The first line becomes the note's title.
To jot something down without leaving the editor, press Ctrl+Alt+N (Cmd+Option+N on a Mac) or run "Quick note" from the command palette. A small card opens over the editor: write the thought, then Ctrl+Enter or "Save note" files it with the story's notes - attached to the open scene when there is one - and puts you back where you were. The first line becomes the note's title.

## History

Expand Down
3 changes: 2 additions & 1 deletion src/lib/docs/shortcuts.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Keyboard shortcuts

Codex keeps to a small set of shortcuts. On a Mac, use Cmd where Ctrl is shown.
Codex keeps to a small set of shortcuts. On a Mac, use Cmd where Ctrl is shown
and Option where Alt is shown.

## Anywhere

Expand Down
2 changes: 1 addition & 1 deletion src/lib/keys.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('isApplePlatform', () => {
expect(isApplePlatform('iPad')).toBe(true);
});

it('leaves everything else on Ctrl', () => {
it('leaves everything else on Ctrl and Alt', () => {
expect(isApplePlatform('Win32')).toBe(false);
expect(isApplePlatform('Windows')).toBe(false);
expect(isApplePlatform('Linux x86_64')).toBe(false);
Expand Down
21 changes: 16 additions & 5 deletions src/lib/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@ export function isApplePlatform(platform: string): boolean {
return /mac|iphone|ipad|ipod/i.test(platform);
}

function currentPlatform(): string {
return (
(navigator as { userAgentData?: { platform?: string } }).userAgentData?.platform ??
navigator.platform ??
''
);
}

// The label for the platform's command modifier. The server cannot know the
// platform, so SSR says Ctrl; callers re-read this after mount to correct it.
export function modLabel(): 'Cmd' | 'Ctrl' {
if (!browser) return 'Ctrl';
const platform =
(navigator as { userAgentData?: { platform?: string } }).userAgentData?.platform ??
navigator.platform ??
'';
return isApplePlatform(platform) ? 'Cmd' : 'Ctrl';
return isApplePlatform(currentPlatform()) ? 'Cmd' : 'Ctrl';
}

// The label for the platform's alternate modifier, which Apple keyboards call
// Option. Same SSR caveat as modLabel.
export function altLabel(): 'Option' | 'Alt' {
if (!browser) return 'Alt';
return isApplePlatform(currentPlatform()) ? 'Option' : 'Alt';
}
12 changes: 11 additions & 1 deletion src/routes/stories/[id]/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script lang="ts">
import { onMount } from 'svelte';
import { SvelteSet } from 'svelte/reactivity';
import { beforeNavigate, goto, invalidateAll } from '$app/navigation';
import { altLabel, modLabel } from '$lib/keys';
import { resolve } from '$app/paths';
import { page } from '$app/state';
import { focusMode } from '$lib/focus-mode.svelte';
Expand Down Expand Up @@ -48,6 +50,14 @@

let { data }: { data: PageData } = $props();

// The platform's modifier labels for shortcut hints; SSR says Ctrl/Alt.
let mod = $state<'Cmd' | 'Ctrl'>('Ctrl');
let alt = $state<'Option' | 'Alt'>('Alt');
onMount(() => {
mod = modLabel();
alt = altLabel();
});

// The writing surface's typography as CSS variables: the font and line
// spacing come from the writer's editor-appearance preferences; the default
// alignment rides with page setup, since it travels into the export.
Expand Down Expand Up @@ -877,7 +887,7 @@
</div>
{/each}
<div class="todo-hint">
Write a line starting with TODO:, or select prose and press Ctrl+Alt+M.
Write a line starting with TODO:, or select prose and press {mod}+{alt}+M.
</div>
</div>
{/if}
Expand Down