From 1e20af831e7be626f383c3e18a90ab779de3374e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 12:53:08 -0400 Subject: [PATCH 01/11] mobile toggle --- package.json | 2 +- pnpm-lock.yaml | 11 +- src/routes/tutorial/[slug]/+page.svelte | 160 ++++++++++-------- .../tutorial/[slug]/ScreenToggle.svelte | 55 +++--- .../tutorial/[slug]/ToggleButton.svelte | 70 ++++++++ .../tutorial/[slug]/filetree/File.svelte | 4 +- .../tutorial/[slug]/filetree/Filetree.svelte | 5 - .../tutorial/[slug]/filetree/Folder.svelte | 40 +++-- .../tutorial/[slug]/filetree/context.js | 1 - 9 files changed, 214 insertions(+), 134 deletions(-) create mode 100644 src/routes/tutorial/[slug]/ToggleButton.svelte diff --git a/package.json b/package.json index ea2158932..87af0b970 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@lezer/javascript": "^1.4.1", "@lezer/lr": "^1.3.3", "@replit/codemirror-lang-svelte": "^6.0.0", - "@rich_harris/svelte-split-pane": "^1.0.1", + "@rich_harris/svelte-split-pane": "^1.0.2", "@webcontainer/api": "^1.0.2", "adm-zip": "^0.5.10", "ansi-to-html": "^0.7.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 60bac2584..cfd001794 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,8 @@ lockfileVersion: 5.4 +overrides: + '@rich_harris/svelte-split-pane': ../libraries/svelte-split-pane + specifiers: '@codemirror/autocomplete': ^6.4.2 '@codemirror/commands': ^6.2.2 @@ -16,7 +19,7 @@ specifiers: '@lezer/lr': ^1.3.3 '@playwright/test': ^1.31.2 '@replit/codemirror-lang-svelte': ^6.0.0 - '@rich_harris/svelte-split-pane': ^1.0.1 + '@rich_harris/svelte-split-pane': ^1.0.2 '@sveltejs/adapter-vercel': 2.3.1 '@sveltejs/kit': ^1.11.0 '@sveltejs/site-kit': ^3.2.2 @@ -59,7 +62,7 @@ dependencies: '@lezer/javascript': 1.4.1 '@lezer/lr': 1.3.3 '@replit/codemirror-lang-svelte': 6.0.0_ybny7xhlf2ysg4majw54z4nkly - '@rich_harris/svelte-split-pane': 1.0.1_svelte@3.56.0 + '@rich_harris/svelte-split-pane': 1.0.2_svelte@3.56.0 '@webcontainer/api': 1.0.2 adm-zip: 0.5.10 ansi-to-html: 0.7.2 @@ -728,8 +731,8 @@ packages: '@lezer/lr': 1.3.3 dev: false - /@rich_harris/svelte-split-pane/1.0.1_svelte@3.56.0: - resolution: {integrity: sha512-/11fp3792qh4pXxO3XtVmIQf6SCDFKcQyyQvVOAKr8U5tG0Z4QaLEXsyOKOpeAkngqWT1dbBfjVynUXa7kb1EA==} + /@rich_harris/svelte-split-pane/1.0.2_svelte@3.56.0: + resolution: {integrity: sha512-8Qhno4kshsBFWC3MnM0++TIbyAvbiuCWXxiCA38VhCr/ZFKQcS8k9mjzWt9eynQjgkyZHejXN0j0V7ws7LV1KA==} peerDependencies: svelte: ^3.54.0 dependencies: diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 6bb3bee4e..13ea7132f 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -23,8 +23,7 @@ export let data; - let width = browser ? window.innerWidth : 1000; - let selected_view = 0; + let show_editor = false; let path = data.exercise.path; let paused = false; @@ -46,9 +45,6 @@ paused = false; }); - $: mobile = writable(false); - $: $mobile = width < 768; - $: completed = is_completed($files, data.exercise.b); $: files.set(Object.values(data.exercise.a)); @@ -105,72 +101,81 @@ -
- -
- { - select_file(e.detail.file); - }} - /> -
- -
- -
- - - -
- - -
-
-
- -
- -
-
-
-
- {#if $mobile} - - {/if} +
+
+ +
+ { + select_file(e.detail.file); + }} + /> +
+ +
+ +
+ + + +
+ + +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
diff --git a/src/routes/tutorial/[slug]/ScreenToggle.svelte b/src/routes/tutorial/[slug]/ScreenToggle.svelte index a40972d78..ea92d6eb6 100644 --- a/src/routes/tutorial/[slug]/ScreenToggle.svelte +++ b/src/routes/tutorial/[slug]/ScreenToggle.svelte @@ -1,42 +1,35 @@ -
- {#each labels as label, index} - - {/each} +
+ + +
diff --git a/src/routes/tutorial/[slug]/ToggleButton.svelte b/src/routes/tutorial/[slug]/ToggleButton.svelte new file mode 100644 index 000000000..3fe5c951d --- /dev/null +++ b/src/routes/tutorial/[slug]/ToggleButton.svelte @@ -0,0 +1,70 @@ + + + + + + diff --git a/src/routes/tutorial/[slug]/filetree/File.svelte b/src/routes/tutorial/[slug]/filetree/File.svelte index e762a51cb..764bf4f25 100644 --- a/src/routes/tutorial/[slug]/filetree/File.svelte +++ b/src/routes/tutorial/[slug]/filetree/File.svelte @@ -10,11 +10,11 @@ /** @type {number} */ export let depth; - const { rename, remove, readonly } = context.get(); + const { rename, remove } = context.get(); let renaming = false; - $: can_remove = !$readonly && !$solution[file.name]; + $: can_remove = !$solution[file.name]; /** @type {import('./ContextMenu.svelte').MenuItems} */ $: actions = can_remove diff --git a/src/routes/tutorial/[slug]/filetree/Filetree.svelte b/src/routes/tutorial/[slug]/filetree/Filetree.svelte index 64252c98f..38f05c90b 100644 --- a/src/routes/tutorial/[slug]/filetree/Filetree.svelte +++ b/src/routes/tutorial/[slug]/filetree/Filetree.svelte @@ -6,9 +6,6 @@ import { files, solution, reset_files, select_file } from '../state.js'; import { afterNavigate } from '$app/navigation'; - /** @type {import('svelte/store').Writable} */ - export let readonly; - /** @type {import('$lib/types').Exercise} */ export let exercise; @@ -26,8 +23,6 @@ context.set({ collapsed, - readonly, - add: async (name, type) => { if (!$solution[name] && !exercise.editing_constraints.create.has(name)) { modal_text = diff --git a/src/routes/tutorial/[slug]/filetree/Folder.svelte b/src/routes/tutorial/[slug]/filetree/Folder.svelte index 60bca73f5..22a0377cd 100644 --- a/src/routes/tutorial/[slug]/filetree/Folder.svelte +++ b/src/routes/tutorial/[slug]/filetree/Folder.svelte @@ -22,7 +22,7 @@ /** @type {'idle' | 'add_file' | 'add_directory' | 'renaming'} */ let mode = 'idle'; - const { collapsed, rename, add, remove, readonly } = context.get(); + const { collapsed, rename, add, remove } = context.get(); $: segments = get_depth(prefix); @@ -44,35 +44,33 @@ can_create.file = false; can_create.directory = false; - if (!$readonly) { - const child_prefixes = []; - - for (const file of $files) { - if ( - file.type === 'directory' && - file.name.startsWith(prefix) && - get_depth(file.name) === depth + 1 - ) { - child_prefixes.push(file.name + '/'); - } + const child_prefixes = []; + + for (const file of $files) { + if ( + file.type === 'directory' && + file.name.startsWith(prefix) && + get_depth(file.name) === depth + 1 + ) { + child_prefixes.push(file.name + '/'); } + } - for (const file of Object.values($solution)) { - if (!file.name.startsWith(prefix)) continue; + for (const file of Object.values($solution)) { + if (!file.name.startsWith(prefix)) continue; - // if already exists in $files, bail - if ($files.find((f) => f.name === file.name)) continue; + // if already exists in $files, bail + if ($files.find((f) => f.name === file.name)) continue; - // if intermediate directory exists, bail - if (child_prefixes.some((prefix) => file.name.startsWith(prefix))) continue; + // if intermediate directory exists, bail + if (child_prefixes.some((prefix) => file.name.startsWith(prefix))) continue; - can_create[file.type] = true; - } + can_create[file.type] = true; } } // fake root directory has no name - $: can_remove = !$readonly && directory.name ? !$solution[directory.name] : false; + $: can_remove = directory.name ? !$solution[directory.name] : false; /** @type {import('./ContextMenu.svelte').MenuItem[]} */ $: actions = [ diff --git a/src/routes/tutorial/[slug]/filetree/context.js b/src/routes/tutorial/[slug]/filetree/context.js index 3e1760547..a9d1fda93 100644 --- a/src/routes/tutorial/[slug]/filetree/context.js +++ b/src/routes/tutorial/[slug]/filetree/context.js @@ -2,7 +2,6 @@ import { setContext, getContext } from 'svelte'; /** * @typedef {{ - * readonly: import('svelte/store').Writable; * collapsed: import('svelte/store').Writable>; * add: (name: string, type: 'file' | 'directory') => Promise; * rename: (stub: import('$lib/types').Stub, name: string) => Promise; From 67d41db17bb678707c8a32be2c9113c20c779fac Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 12:55:00 -0400 Subject: [PATCH 02/11] a11y --- src/routes/tutorial/[slug]/ScreenToggle.svelte | 4 ++-- src/routes/tutorial/[slug]/ToggleButton.svelte | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/routes/tutorial/[slug]/ScreenToggle.svelte b/src/routes/tutorial/[slug]/ScreenToggle.svelte index ea92d6eb6..b4d31435f 100644 --- a/src/routes/tutorial/[slug]/ScreenToggle.svelte +++ b/src/routes/tutorial/[slug]/ScreenToggle.svelte @@ -6,9 +6,9 @@
- + - +
diff --git a/src/routes/tutorial/[slug]/filetree/context.js b/src/routes/tutorial/[slug]/filetree/context.js index a9d1fda93..29ec16ec1 100644 --- a/src/routes/tutorial/[slug]/filetree/context.js +++ b/src/routes/tutorial/[slug]/filetree/context.js @@ -6,6 +6,7 @@ import { setContext, getContext } from 'svelte'; * add: (name: string, type: 'file' | 'directory') => Promise; * rename: (stub: import('$lib/types').Stub, name: string) => Promise; * remove: (stub: import('$lib/types').Stub) => Promise; + * select: (name: string) => void; * }} FileTreeContext */ From c1a28eb2ed81c7194654348af5020c32c8c9c847 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 18:18:56 -0400 Subject: [PATCH 07/11] debugging --- src/routes/tutorial/[slug]/+page.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 5e0da73d5..8e2a83a45 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -41,6 +41,8 @@ }); afterNavigate(async () => { + w = window.innerWidth; + const will_delete = previous_files.some((file) => !(file.name in data.exercise.a)); if (data.exercise.path !== path || will_delete) paused = true; @@ -102,6 +104,10 @@ +
+

w: {w}

+
+
From 74947c5243b7846d05ca589c4323b2bb6a9af996 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 18:23:37 -0400 Subject: [PATCH 08/11] wtf --- src/routes/tutorial/[slug]/+page.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index 8e2a83a45..f860d7d58 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -106,6 +106,7 @@

w: {w}

+

mobile: {mobile}

From fe43f21366a2496935f218cdcee4fb6b052ee615 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 18:42:32 -0400 Subject: [PATCH 09/11] throw CSS at the problem --- src/routes/tutorial/[slug]/+page.svelte | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index f860d7d58..e93a38b87 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -195,6 +195,9 @@ display: flex; flex-direction: column; height: 100%; + /** necessary for innerWidth to be correct, so we can determine `mobile` */ + width: 100vw; + overflow: hidden; } .top { From e44f3dba1203dcbed50fcc2f6bddaaafc3034669 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 18:44:39 -0400 Subject: [PATCH 10/11] remove debugging stuff --- src/routes/tutorial/[slug]/+page.svelte | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index e93a38b87..b3a605928 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -104,11 +104,6 @@ -
-

w: {w}

-

mobile: {mobile}

-
-
From a293707483c3fff5eff5a934ee3aa6d567c11409 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 14 Mar 2023 19:11:14 -0400 Subject: [PATCH 11/11] make view history-driven --- src/routes/tutorial/[slug]/+page.svelte | 18 +++++++++++-- src/routes/tutorial/[slug]/Editor.svelte | 5 +++- .../tutorial/[slug]/ScreenToggle.svelte | 27 ++++++++++++++++--- .../tutorial/[slug]/ToggleButton.svelte | 15 ++++++++--- 4 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/routes/tutorial/[slug]/+page.svelte b/src/routes/tutorial/[slug]/+page.svelte index b3a605928..600a097bf 100644 --- a/src/routes/tutorial/[slug]/+page.svelte +++ b/src/routes/tutorial/[slug]/+page.svelte @@ -100,7 +100,13 @@ - + { + const q = new URLSearchParams(location.search); + show_editor = q.get('view') === 'editor'; + }} +/> @@ -181,7 +187,15 @@
- + { + show_editor = e.detail.pressed; + + const view = show_editor ? 'editor' : 'tutorial'; + history.pushState({}, '', `?view=${view}`); + }} + pressed={show_editor} + />
diff --git a/src/routes/tutorial/[slug]/Editor.svelte b/src/routes/tutorial/[slug]/Editor.svelte index b4ce4390e..fecc78caa 100644 --- a/src/routes/tutorial/[slug]/Editor.svelte +++ b/src/routes/tutorial/[slug]/Editor.svelte @@ -202,7 +202,10 @@ editor_states.clear(); reset($files); - select_state($selected_name); + if (editor_view) { + // could be false if onMount returned early + select_state($selected_name); + } // clear warnings warnings.set({}); diff --git a/src/routes/tutorial/[slug]/ScreenToggle.svelte b/src/routes/tutorial/[slug]/ScreenToggle.svelte index b4d31435f..76355d308 100644 --- a/src/routes/tutorial/[slug]/ScreenToggle.svelte +++ b/src/routes/tutorial/[slug]/ScreenToggle.svelte @@ -1,14 +1,33 @@
- - - + + +