|
37 | 37 | ]; |
38 | 38 | let currentPath: string = './'; |
39 | 39 | let currentDir: Directory; |
40 | | - export let expanded = writable(['lib-0', 'tree-0']); |
| 40 | + export let expanded = writable([]); |
| 41 | + let initialized = false; |
| 42 | + let initialPath: string = './'; |
| 43 | + let pathNotFound = false; |
41 | 44 |
|
42 | 45 | onMount(async () => { |
43 | 46 | try { |
|
61 | 64 | })); |
62 | 65 | currentDir = directories[0]; |
63 | 66 | isLoading = false; |
| 67 | + $expanded = Array.from(new Set([...$expanded, './'])); |
64 | 68 | } catch { |
65 | 69 | return; |
66 | 70 | } |
67 | 71 | }); |
68 | 72 |
|
69 | | - async function fetchContents(e: CustomEvent) { |
70 | | - const path = e.detail.fullPath as string; |
| 73 | + async function loadPath(path: string) { |
71 | 74 | currentPath = path; |
72 | 75 |
|
73 | 76 | const pathSegments = path.split('/').filter((segment) => segment !== '.' && segment !== ''); |
|
99 | 102 | const contentDirectories = content.contents.filter((e) => e.isDirectory); |
100 | 103 |
|
101 | 104 | if (contentDirectories.length === 0) { |
| 105 | + $expanded = Array.from(new Set([...$expanded, path])); |
102 | 106 | return; |
103 | 107 | } |
104 | 108 |
|
|
133 | 137 | }); |
134 | 138 | } |
135 | 139 | directories = [...directories]; |
136 | | - $expanded = [...$expanded, path]; |
| 140 | + $expanded = Array.from(new Set([...$expanded, path])); |
137 | 141 | } catch (error) { |
138 | 142 | console.error(error); |
139 | 143 | } finally { |
|
142 | 146 | } |
143 | 147 | } |
144 | 148 |
|
| 149 | + async function fetchContents(e: CustomEvent) { |
| 150 | + const path = e.detail.fullPath as string; |
| 151 | + await loadPath(path); |
| 152 | + } |
| 153 | +
|
| 154 | + function normalizePath(path: string): string { |
| 155 | + if (!path || path === '') return './'; |
| 156 | + if (path === './') return './'; |
| 157 | + if (path.startsWith('./')) return path.replace(/\/$/, ''); |
| 158 | + if (path.startsWith('/')) return '.' + path.replace(/\/$/, ''); |
| 159 | + return './' + path.replace(/\/$/, ''); |
| 160 | + } |
| 161 | +
|
| 162 | + async function expandToPath(path: string) { |
| 163 | + pathNotFound = false; |
| 164 | + const normalized = normalizePath(path); |
| 165 | + const segments = normalized.split('/').filter((s) => s !== '.' && s !== ''); |
| 166 | + let cumulative = './'; |
| 167 | + $expanded = Array.from(new Set([...$expanded, './'])); |
| 168 | + for (const segment of segments) { |
| 169 | + cumulative = cumulative === './' ? `./${segment}` : `${cumulative}/${segment}`; |
| 170 | + const parentSegments = cumulative.split('/').filter((s) => s !== '.' && s !== ''); |
| 171 | + let cursor = directories[0]; |
| 172 | + for (const s of parentSegments.slice(0, -1)) { |
| 173 | + const next = cursor.children?.find((d) => d.title === s); |
| 174 | + if (!next) { |
| 175 | + pathNotFound = true; |
| 176 | + return; |
| 177 | + } |
| 178 | + cursor = next; |
| 179 | + } |
| 180 | + await loadPath(cursor.fullPath ?? './'); |
| 181 | + const exists = cursor.children?.some((d) => d.title === segment); |
| 182 | + if (!exists) { |
| 183 | + pathNotFound = true; |
| 184 | + return; |
| 185 | + } |
| 186 | + $expanded = Array.from(new Set([...$expanded, cumulative])); |
| 187 | + } |
| 188 | + currentPath = normalized; |
| 189 | + } |
| 190 | +
|
| 191 | + $: if (show && !initialized && !isLoading) { |
| 192 | + initialized = true; |
| 193 | + initialPath = normalizePath(rootDir ?? './'); |
| 194 | + currentPath = initialPath; |
| 195 | + expandToPath(initialPath); |
| 196 | + } |
| 197 | +
|
| 198 | + $: if (!show && initialized) { |
| 199 | + initialized = false; |
| 200 | + pathNotFound = false; |
| 201 | + } |
| 202 | +
|
145 | 203 | function handleSubmit() { |
146 | 204 | rootDir = currentPath; |
147 | 205 | show = false; |
|
156 | 214 |
|
157 | 215 | <svelte:fragment slot="footer"> |
158 | 216 | <Button secondary on:click={() => (show = false)}>Cancel</Button> |
159 | | - <Button submit disabled={isLoading}>Save</Button> |
| 217 | + <Button submit disabled={isLoading || currentPath === initialPath}>Save</Button> |
160 | 218 | </svelte:fragment> |
161 | 219 | </Modal> |
0 commit comments