Add loading store to Navigator to keep track of loading state

This commit is contained in:
2024-08-09 13:47:10 +02:00
parent 69744e41a6
commit 12e23b3872
11 changed files with 51 additions and 86 deletions

View File

@@ -12,8 +12,8 @@ import { fs_path_url } from './FilesystemUtil.js';
import { branding_from_path } from './edit_window/Branding.js'
import Menu from './Menu.svelte';
import { Navigator } from "./Navigator.js"
import { writable } from 'svelte/store';
let loading = true
let file_viewer
let file_preview
let toolbar
@@ -24,9 +24,11 @@ let edit_window
let edit_visible = false
let view = "file"
const nav = new Navigator()
const loading = writable(true)
const nav = new Navigator(true)
onMount(() => {
nav.loading = loading
nav.open_node(window.initial_node, false)
// Subscribe to navigation updates. This function returns a deconstructor
@@ -39,8 +41,7 @@ onMount(() => {
// Custom CSS rules for the whole viewer
document.documentElement.style = branding_from_path(nav.path)
// Turn off loading spinner when the navigator is done
loading = false
loading.set(false)
})
})
@@ -120,8 +121,6 @@ const search = async () => {
view = "search"
}
const loading_evt = e => loading = e.detail
</script>
<svelte:window on:keydown={keydown} />
@@ -151,17 +150,12 @@ const loading_evt = e => loading = e.detail
bind:this={file_preview}
nav={nav}
edit_window={edit_window}
on:loading={loading_evt}
on:open_sibling={e => nav.open_sibling(e.detail)}
on:download={download}
on:upload_picker={() => upload_widget.pick_files()}
/>
{:else if view === "search"}
<SearchView
nav={nav}
on:loading={loading_evt}
on:done={() => {view = "file"}}
/>
<SearchView nav={nav} on:done={() => {view = "file"}} />
{/if}
</div>
</div>
@@ -173,25 +167,13 @@ const loading_evt = e => loading = e.detail
style="display: none; width: 1px; height: 1px;">
</iframe>
<DetailsWindow
nav={nav}
bind:visible={details_visible}
/>
<DetailsWindow nav={nav} bind:visible={details_visible} />
<EditWindow
nav={nav}
bind:this={edit_window}
bind:visible={edit_visible}
on:loading={loading_evt}
/>
<EditWindow nav={nav} bind:this={edit_window} bind:visible={edit_visible} />
<UploadWidget
nav={nav}
bind:this={upload_widget}
drop_upload
/>
<UploadWidget nav={nav} bind:this={upload_widget} drop_upload />
<LoadingIndicator loading={$nav.loading || loading}/>
<LoadingIndicator loading={$loading}/>
</div>
<style>

View File

@@ -13,9 +13,7 @@ export class Navigator {
// Initialized will be set to true when the first file or directory is loaded
initialized = false
shuffle = false
loading = false
// Whether navigation events should update the browser history
history_enabled = true
@@ -36,6 +34,15 @@ export class Navigator {
}
}
// If you set the loading property to a boolean writable store the navigator
// will use it to publish its loading states
loading = null
set_loading(b) {
if (this.loading !== null && this.loading.set !== undefined) {
this.loading.set(b)
}
}
// The Navigator acts as a svelte store. This allows for DOM reactivity.
// This works by implementing the store contract:
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
@@ -57,10 +64,10 @@ export class Navigator {
path = "/" + path
}
this.loading = true
console.debug("Navigating to path", path, push_history)
try {
this.set_loading(true)
const resp = await fs_get_node(path)
this.open_node(resp, push_history)
} catch (err) {
@@ -77,7 +84,7 @@ export class Navigator {
alert("Error: " + err)
}
} finally {
this.loading = false
this.set_loading(false)
}
}
@@ -132,9 +139,6 @@ export class Navigator {
for (let i = 0; i < this.subscribers.length; i++) {
this.subscribers[i](this)
}
// Remove spinner
this.loading = false
}
// These are used to navigate forward and backward within a directory (using
@@ -174,16 +178,17 @@ export class Navigator {
return
}
this.loading = true
let siblings
try {
this.set_loading(true)
siblings = await this.get_siblings()
} catch (err) {
console.error(err)
alert(err)
this.loading = false
return
} finally {
this.set_loading(false)
}
let next_sibling = null
@@ -218,10 +223,9 @@ export class Navigator {
// If we found a sibling we open it
if (next_sibling !== null) {
console.debug("Opening sibling", next_sibling.path)
this.navigate(next_sibling.path, true)
await this.navigate(next_sibling.path, true)
} else {
console.debug("No siblings found")
this.loading = false
}
}
}

View File

@@ -32,8 +32,9 @@ const search = async (limit = 10) => {
error = ""
last_searched_term = search_term
last_limit = limit
searching = true
dispatch("loading", true)
nav.set_loading(true)
try {
search_results = await fs_search(nav.base.path, search_term, limit)
@@ -47,7 +48,7 @@ const search = async (limit = 10) => {
}
searching = false
dispatch("loading", false)
nav.set_loading(false)
// It's possible that the user entered another letter while we were
// performing the search reqeust. If this happens we run the search function

View File

@@ -1,14 +1,11 @@
<script>
import { fs_rename, fs_update } from "../FilesystemAPI";
import Modal from "../../util/Modal.svelte";
import { createEventDispatcher } from "svelte";
import BrandingOptions from "./BrandingOptions.svelte";
import { branding_from_node } from "./Branding";
import FileOptions from "./FileOptions.svelte";
import SharingOptions from "./SharingOptions.svelte";
let dispatch = createEventDispatcher()
export let nav
let file = {
path: "",
@@ -78,7 +75,7 @@ const save = async (keep_editing = false) => {
let new_file
try {
dispatch("loading", true)
nav.set_loading(true)
let opts = {shared: shared}
opts.branding_enabled = branding_enabled ? "true" : ""
@@ -113,7 +110,7 @@ const save = async (keep_editing = false) => {
}
return
} finally {
dispatch("loading", false)
nav.set_loading(false)
}
if (open_after_edit) {
@@ -154,7 +151,6 @@ const save = async (keep_editing = false) => {
bind:new_name
bind:visible
bind:open_after_edit
on:loading
/>
{:else if tab === "share"}
<SharingOptions

View File

@@ -1,10 +1,8 @@
<script>
import { createEventDispatcher } from "svelte";
import Button from "../../layout/Button.svelte";
import { fs_delete_all } from "../FilesystemAPI";
import PathLink from "../util/PathLink.svelte";
let dispatch = createEventDispatcher()
export let nav
export let file = {}
export let new_name
@@ -17,14 +15,14 @@ const delete_file = async e => {
e.preventDefault()
try {
dispatch("loading", true)
nav.set_loading(true)
await fs_delete_all(file.path)
} catch (err) {
console.error(err)
alert(err)
return
} finally {
dispatch("loading", false)
nac.set_loading(false)
}
if (open_after_edit) {

View File

@@ -1,8 +1,7 @@
<script>
import { onMount, createEventDispatcher } from "svelte";
import { onMount } from "svelte";
import { fs_mkdir } from "../FilesystemAPI.js";
import Button from "../../layout/Button.svelte";
let dispatch = createEventDispatcher()
export let nav;
@@ -10,16 +9,15 @@ let name_input;
let new_dir_name = ""
let error_msg = ""
let create_dir = async () => {
dispatch("loading", true)
let form = new FormData()
form.append("type", "dir")
try {
nav.set_loading(true)
await fs_mkdir(nav.base.path+"/"+new_dir_name)
new_dir_name = "" // Clear input field
error_msg = "" // Clear error msg
dispatch("done")
nav.reload()
} catch (err) {
if (err.value && err.value === "node_already_exists") {
error_msg = "A directory with this name already exists"
@@ -27,7 +25,7 @@ let create_dir = async () => {
error_msg = "Server returned an error: "+err
}
} finally {
dispatch("loading", false)
nav.set_loading(false)
}
}

View File

@@ -1,21 +1,16 @@
<script>
import { createEventDispatcher } from "svelte";
import FilePicker from "../../file_viewer/FilePicker.svelte";
import { fs_import } from "../FilesystemAPI";
let dispatch = createEventDispatcher()
export let nav
let file_picker
export const open = () => file_picker.open()
const import_files = async files => {
dispatch("loading", true)
console.log(files)
nav.set_loading(true)
let fileids = []
files.forEach(file => {
fileids.push(file.id)
})
@@ -31,10 +26,9 @@ const import_files = async files => {
}
return
} finally {
dispatch("reload")
nav.reload()
}
}
</script>
<FilePicker

View File

@@ -97,7 +97,7 @@ const delete_selected = async () => {
return
}
dispatch("loading", true)
nav.set_loading(true)
try {
// Save all promises with deletion requests in an array
@@ -219,7 +219,7 @@ const move_start = () => {
}
const move_here = async () => {
dispatch("loading", true)
nav.set_loading(true)
let target_dir = nav.base.path + "/"
@@ -338,7 +338,7 @@ onMount(() => {
{/if}
{#if creating_dir}
<CreateDirectory nav={nav} on:done={() => nav.reload()} on:loading />
<CreateDirectory nav={nav} />
{/if}
{#if $nav.base.path === "/me"}
@@ -386,12 +386,7 @@ onMount(() => {
{/if}
</div>
<FileImporter
nav={nav}
bind:this={file_importer}
on:loading
on:reload={() => nav.reload()}
/>
<FileImporter nav={nav} bind:this={file_importer} />
<style>
.container {

View File

@@ -52,7 +52,7 @@ export const toggle_playback = () => {
<Spinner></Spinner>
</div>
{:else if viewer_type === "dir"}
<FileManager nav={nav} edit_window={edit_window} on:loading on:upload_picker>
<FileManager nav={nav} edit_window={edit_window} on:upload_picker>
<CustomBanner path={$nav.path}/>
</FileManager>
{:else if viewer_type === "audio"}
@@ -70,11 +70,11 @@ export const toggle_playback = () => {
<CustomBanner path={$nav.path}/>
</Text>
{:else if viewer_type === "torrent"}
<Torrent nav={nav} bind:this={viewer} on:loading on:download>
<Torrent nav={nav} bind:this={viewer} on:download>
<CustomBanner path={$nav.path}/>
</Torrent>
{:else if viewer_type === "zip"}
<Zip nav={nav} bind:this={viewer} on:loading on:download>
<Zip nav={nav} bind:this={viewer} on:download>
<CustomBanner path={$nav.path}/>
</Zip>
{:else}

View File

@@ -15,9 +15,8 @@ export let nav
let status = "loading"
export const update = async () => {
dispatch("loading", true)
try {
nav.set_loading(true)
let resp = await fetch(fs_path_url(nav.base.path)+"?torrent_info")
if (resp.status >= 400) {
@@ -44,9 +43,9 @@ export const update = async () => {
} catch (err) {
console.error(err)
} finally {
dispatch("loading", false)
}
nav.set_loading(false)
status = "finished"
}
}
let torrent = {

View File

@@ -21,8 +21,6 @@ let comp_ratio = 0
let archive_type = ""
export const update = async () => {
dispatch("loading", true)
if (nav.base.file_type === "application/zip") {
archive_type = "zip"
} else if (nav.base.file_type === "application/x-7z-compressed") {
@@ -30,6 +28,7 @@ export const update = async () => {
}
try {
nav.set_loading(true)
let resp = await fetch(fs_path_url(nav.base.path)+"?zip_info")
if (resp.status >= 400) {
@@ -51,10 +50,9 @@ export const update = async () => {
} catch (err) {
console.error(err)
} finally {
dispatch("loading", false)
}
nav.set_loading(false)
status = "finished"
}
}
const recursive_set_url = (parent_path, file) => {