Skip to content

Commit ad423fa

Browse files
committed
Add new folder button, and confirm when overwriting
1 parent 8c164c9 commit ad423fa

File tree

9 files changed

+362
-228
lines changed

9 files changed

+362
-228
lines changed

src/dialog/browser/browser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {AsyncDialog, DialogDirectories, DialogOptions} from '../common/inte
1515
import {type DownloadOptions, DownloadProvider, type ProgressCallback} from './download.js'
1616
import type {Provider} from './interface.js'
1717
import {WebStorageProvider} from './storage.js'
18-
import DialogUI from './ui/Dialog.svelte'
18+
import DialogUI from './ui/FileDialog.svelte'
1919

2020
export class BrowserDialog implements AsyncDialog {
2121
'async' = true as const

src/dialog/browser/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class CachingDirBrowser implements DirBrowser {
6565
}
6666
}
6767

68-
async browse(dir_path: string, _filter?: string[]): Promise<DirEntry[]> {
68+
async browse(dir_path: string): Promise<DirEntry[]> {
6969
if (!dir_path.startsWith('/usr')) {
7070
throw new Error('Can only browse /usr')
7171
}

src/dialog/browser/interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export interface Provider {
2727

2828
/** Browse a directory; may cache all the files or request each time you change directory */
2929
export interface DirBrowser {
30-
browse(path: string, filter?: string[]): Promise<DirEntry[]>
30+
browse(path: string): Promise<DirEntry[]>
3131
}
3232

3333
export interface DirEntry {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<script context="module" lang="ts">
2+
export const enum AlertMode {
3+
ALERT = 0,
4+
CONFIRM = 1,
5+
PROMPT = 2,
6+
}
7+
</script>
8+
9+
<style>
10+
#val_input {
11+
box-sizing: border-box;
12+
width: 100%;
13+
}
14+
</style>
15+
16+
<script lang="ts">
17+
import BaseDialog from './BaseDialog.svelte'
18+
19+
let base_dialog: BaseDialog
20+
let message: string
21+
let mode: AlertMode
22+
let val_input: HTMLInputElement
23+
24+
export function open(_mode: AlertMode, title: string, _message: string): Promise<string | boolean> {
25+
message = _message
26+
mode = _mode
27+
const promise = base_dialog.open(title)
28+
if (val_input) {
29+
val_input.value = ''
30+
val_input.focus()
31+
}
32+
return promise
33+
}
34+
35+
function on_cancel() {
36+
base_dialog.resolve(false)
37+
}
38+
39+
function on_create_input(node: HTMLInputElement) {
40+
val_input = node
41+
val_input.focus()
42+
val_input.value = ''
43+
}
44+
45+
function on_input_keydown(ev: KeyboardEvent) {
46+
if (ev.code === 'Enter') {
47+
on_submit()
48+
ev.preventDefault()
49+
}
50+
}
51+
52+
function on_submit() {
53+
if (mode === AlertMode.PROMPT) {
54+
const val = val_input.value.trim()
55+
base_dialog.resolve(val || false)
56+
}
57+
else {
58+
base_dialog.resolve(true)
59+
}
60+
}
61+
</script>
62+
63+
<BaseDialog bind:this={base_dialog}>
64+
<p>{message}</p>
65+
<div>
66+
{#if mode === AlertMode.PROMPT}
67+
<input id="val_input" on:keydown={on_input_keydown} use:on_create_input>
68+
{/if}
69+
</div>
70+
<div class="foot">
71+
<div>
72+
{#if mode !== AlertMode.ALERT}
73+
<button class="close" on:click={on_cancel}>Cancel</button>
74+
{/if}
75+
<button class="submit" on:click={on_submit}>Ok</button>
76+
</div>
77+
</div>
78+
</BaseDialog>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<script lang="ts">
2+
let dialog: HTMLDialogElement
3+
export let extra_class = ''
4+
export let max_height = '200px'
5+
export let max_width = '300px'
6+
let promise_resolve: (res: string | boolean) => void
7+
let title = ''
8+
9+
export async function open(_title: string): Promise<string | boolean> {
10+
title = _title
11+
const promise: Promise<string | boolean> = new Promise((resolve) => promise_resolve = resolve)
12+
dialog.showModal()
13+
return promise
14+
}
15+
16+
export function resolve(val: string | boolean) {
17+
dialog.close()
18+
promise_resolve(val)
19+
}
20+
21+
function on_close() {
22+
resolve(false)
23+
}
24+
</script>
25+
26+
<style>
27+
dialog {
28+
box-sizing: border-box;
29+
font-family: sans-serif;
30+
height: 100%;
31+
user-select: none;
32+
width: 100%;
33+
}
34+
35+
dialog::backdrop {
36+
background: linear-gradient(rgba(64, 64, 64, 25%), rgba(64, 64, 64, 40%));
37+
}
38+
39+
.inner {
40+
display: flex;
41+
flex-direction: column;
42+
height: 100%;
43+
width: 100%;
44+
}
45+
46+
.inner > :global(div) {
47+
padding: 5px 0;
48+
}
49+
50+
.head h1 {
51+
margin: 0;
52+
}
53+
54+
.head .close {
55+
background: none;
56+
border: none;
57+
padding: 10px;
58+
position: absolute;
59+
right: 10px;
60+
top: 10px;
61+
}
62+
</style>
63+
64+
<dialog bind:this={dialog}
65+
class={extra_class}
66+
on:close={on_close}
67+
style="max-height: {max_height}; max-width: {max_width}"
68+
>
69+
<div class="inner">
70+
<div class="head">
71+
<h1>{title}</h1>
72+
<button class="close" aria-label="Close" on:click={on_close}>✖</button>
73+
</div>
74+
<slot></slot>
75+
</div>
76+
</dialog>

0 commit comments

Comments
 (0)