Add loading store to Navigator to keep track of loading state
This commit is contained in:
@@ -12,8 +12,8 @@ import { fs_path_url } from './FilesystemUtil.js';
|
|||||||
import { branding_from_path } from './edit_window/Branding.js'
|
import { branding_from_path } from './edit_window/Branding.js'
|
||||||
import Menu from './Menu.svelte';
|
import Menu from './Menu.svelte';
|
||||||
import { Navigator } from "./Navigator.js"
|
import { Navigator } from "./Navigator.js"
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
|
||||||
let loading = true
|
|
||||||
let file_viewer
|
let file_viewer
|
||||||
let file_preview
|
let file_preview
|
||||||
let toolbar
|
let toolbar
|
||||||
@@ -24,9 +24,11 @@ let edit_window
|
|||||||
let edit_visible = false
|
let edit_visible = false
|
||||||
let view = "file"
|
let view = "file"
|
||||||
|
|
||||||
const nav = new Navigator()
|
const loading = writable(true)
|
||||||
|
const nav = new Navigator(true)
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
nav.loading = loading
|
||||||
nav.open_node(window.initial_node, false)
|
nav.open_node(window.initial_node, false)
|
||||||
|
|
||||||
// Subscribe to navigation updates. This function returns a deconstructor
|
// Subscribe to navigation updates. This function returns a deconstructor
|
||||||
@@ -39,8 +41,7 @@ onMount(() => {
|
|||||||
// Custom CSS rules for the whole viewer
|
// Custom CSS rules for the whole viewer
|
||||||
document.documentElement.style = branding_from_path(nav.path)
|
document.documentElement.style = branding_from_path(nav.path)
|
||||||
|
|
||||||
// Turn off loading spinner when the navigator is done
|
loading.set(false)
|
||||||
loading = false
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -120,8 +121,6 @@ const search = async () => {
|
|||||||
|
|
||||||
view = "search"
|
view = "search"
|
||||||
}
|
}
|
||||||
|
|
||||||
const loading_evt = e => loading = e.detail
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:keydown={keydown} />
|
<svelte:window on:keydown={keydown} />
|
||||||
@@ -151,17 +150,12 @@ const loading_evt = e => loading = e.detail
|
|||||||
bind:this={file_preview}
|
bind:this={file_preview}
|
||||||
nav={nav}
|
nav={nav}
|
||||||
edit_window={edit_window}
|
edit_window={edit_window}
|
||||||
on:loading={loading_evt}
|
|
||||||
on:open_sibling={e => nav.open_sibling(e.detail)}
|
on:open_sibling={e => nav.open_sibling(e.detail)}
|
||||||
on:download={download}
|
on:download={download}
|
||||||
on:upload_picker={() => upload_widget.pick_files()}
|
on:upload_picker={() => upload_widget.pick_files()}
|
||||||
/>
|
/>
|
||||||
{:else if view === "search"}
|
{:else if view === "search"}
|
||||||
<SearchView
|
<SearchView nav={nav} on:done={() => {view = "file"}} />
|
||||||
nav={nav}
|
|
||||||
on:loading={loading_evt}
|
|
||||||
on:done={() => {view = "file"}}
|
|
||||||
/>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -173,25 +167,13 @@ const loading_evt = e => loading = e.detail
|
|||||||
style="display: none; width: 1px; height: 1px;">
|
style="display: none; width: 1px; height: 1px;">
|
||||||
</iframe>
|
</iframe>
|
||||||
|
|
||||||
<DetailsWindow
|
<DetailsWindow nav={nav} bind:visible={details_visible} />
|
||||||
nav={nav}
|
|
||||||
bind:visible={details_visible}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<EditWindow
|
<EditWindow nav={nav} bind:this={edit_window} bind:visible={edit_visible} />
|
||||||
nav={nav}
|
|
||||||
bind:this={edit_window}
|
|
||||||
bind:visible={edit_visible}
|
|
||||||
on:loading={loading_evt}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<UploadWidget
|
<UploadWidget nav={nav} bind:this={upload_widget} drop_upload />
|
||||||
nav={nav}
|
|
||||||
bind:this={upload_widget}
|
|
||||||
drop_upload
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LoadingIndicator loading={$nav.loading || loading}/>
|
<LoadingIndicator loading={$loading}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@@ -13,9 +13,7 @@ export class Navigator {
|
|||||||
|
|
||||||
// Initialized will be set to true when the first file or directory is loaded
|
// Initialized will be set to true when the first file or directory is loaded
|
||||||
initialized = false
|
initialized = false
|
||||||
|
|
||||||
shuffle = false
|
shuffle = false
|
||||||
loading = false
|
|
||||||
|
|
||||||
// Whether navigation events should update the browser history
|
// Whether navigation events should update the browser history
|
||||||
history_enabled = true
|
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.
|
// The Navigator acts as a svelte store. This allows for DOM reactivity.
|
||||||
// This works by implementing the store contract:
|
// This works by implementing the store contract:
|
||||||
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
|
// https://svelte.dev/docs/svelte-components#script-4-prefix-stores-with-$-to-access-their-values
|
||||||
@@ -57,10 +64,10 @@ export class Navigator {
|
|||||||
path = "/" + path
|
path = "/" + path
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true
|
|
||||||
console.debug("Navigating to path", path, push_history)
|
console.debug("Navigating to path", path, push_history)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
this.set_loading(true)
|
||||||
const resp = await fs_get_node(path)
|
const resp = await fs_get_node(path)
|
||||||
this.open_node(resp, push_history)
|
this.open_node(resp, push_history)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -77,7 +84,7 @@ export class Navigator {
|
|||||||
alert("Error: " + err)
|
alert("Error: " + err)
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.set_loading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +139,6 @@ export class Navigator {
|
|||||||
for (let i = 0; i < this.subscribers.length; i++) {
|
for (let i = 0; i < this.subscribers.length; i++) {
|
||||||
this.subscribers[i](this)
|
this.subscribers[i](this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove spinner
|
|
||||||
this.loading = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are used to navigate forward and backward within a directory (using
|
// These are used to navigate forward and backward within a directory (using
|
||||||
@@ -174,16 +178,17 @@ export class Navigator {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loading = true
|
|
||||||
|
|
||||||
let siblings
|
let siblings
|
||||||
try {
|
try {
|
||||||
|
this.set_loading(true)
|
||||||
siblings = await this.get_siblings()
|
siblings = await this.get_siblings()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
alert(err)
|
alert(err)
|
||||||
this.loading = false
|
|
||||||
return
|
return
|
||||||
|
} finally {
|
||||||
|
this.set_loading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_sibling = null
|
let next_sibling = null
|
||||||
@@ -218,10 +223,9 @@ export class Navigator {
|
|||||||
// If we found a sibling we open it
|
// If we found a sibling we open it
|
||||||
if (next_sibling !== null) {
|
if (next_sibling !== null) {
|
||||||
console.debug("Opening sibling", next_sibling.path)
|
console.debug("Opening sibling", next_sibling.path)
|
||||||
this.navigate(next_sibling.path, true)
|
await this.navigate(next_sibling.path, true)
|
||||||
} else {
|
} else {
|
||||||
console.debug("No siblings found")
|
console.debug("No siblings found")
|
||||||
this.loading = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,8 +32,9 @@ const search = async (limit = 10) => {
|
|||||||
error = ""
|
error = ""
|
||||||
last_searched_term = search_term
|
last_searched_term = search_term
|
||||||
last_limit = limit
|
last_limit = limit
|
||||||
|
|
||||||
searching = true
|
searching = true
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
search_results = await fs_search(nav.base.path, search_term, limit)
|
search_results = await fs_search(nav.base.path, search_term, limit)
|
||||||
@@ -47,7 +48,7 @@ const search = async (limit = 10) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
searching = false
|
searching = false
|
||||||
dispatch("loading", false)
|
nav.set_loading(false)
|
||||||
|
|
||||||
// It's possible that the user entered another letter while we were
|
// It's possible that the user entered another letter while we were
|
||||||
// performing the search reqeust. If this happens we run the search function
|
// performing the search reqeust. If this happens we run the search function
|
||||||
|
@@ -1,14 +1,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import { fs_rename, fs_update } from "../FilesystemAPI";
|
import { fs_rename, fs_update } from "../FilesystemAPI";
|
||||||
import Modal from "../../util/Modal.svelte";
|
import Modal from "../../util/Modal.svelte";
|
||||||
import { createEventDispatcher } from "svelte";
|
|
||||||
import BrandingOptions from "./BrandingOptions.svelte";
|
import BrandingOptions from "./BrandingOptions.svelte";
|
||||||
import { branding_from_node } from "./Branding";
|
import { branding_from_node } from "./Branding";
|
||||||
import FileOptions from "./FileOptions.svelte";
|
import FileOptions from "./FileOptions.svelte";
|
||||||
import SharingOptions from "./SharingOptions.svelte";
|
import SharingOptions from "./SharingOptions.svelte";
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
export let nav
|
export let nav
|
||||||
let file = {
|
let file = {
|
||||||
path: "",
|
path: "",
|
||||||
@@ -78,7 +75,7 @@ const save = async (keep_editing = false) => {
|
|||||||
|
|
||||||
let new_file
|
let new_file
|
||||||
try {
|
try {
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
let opts = {shared: shared}
|
let opts = {shared: shared}
|
||||||
|
|
||||||
opts.branding_enabled = branding_enabled ? "true" : ""
|
opts.branding_enabled = branding_enabled ? "true" : ""
|
||||||
@@ -113,7 +110,7 @@ const save = async (keep_editing = false) => {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("loading", false)
|
nav.set_loading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_after_edit) {
|
if (open_after_edit) {
|
||||||
@@ -154,7 +151,6 @@ const save = async (keep_editing = false) => {
|
|||||||
bind:new_name
|
bind:new_name
|
||||||
bind:visible
|
bind:visible
|
||||||
bind:open_after_edit
|
bind:open_after_edit
|
||||||
on:loading
|
|
||||||
/>
|
/>
|
||||||
{:else if tab === "share"}
|
{:else if tab === "share"}
|
||||||
<SharingOptions
|
<SharingOptions
|
||||||
|
@@ -1,10 +1,8 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte";
|
|
||||||
import Button from "../../layout/Button.svelte";
|
import Button from "../../layout/Button.svelte";
|
||||||
import { fs_delete_all } from "../FilesystemAPI";
|
import { fs_delete_all } from "../FilesystemAPI";
|
||||||
import PathLink from "../util/PathLink.svelte";
|
import PathLink from "../util/PathLink.svelte";
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
|
||||||
export let nav
|
export let nav
|
||||||
export let file = {}
|
export let file = {}
|
||||||
export let new_name
|
export let new_name
|
||||||
@@ -17,14 +15,14 @@ const delete_file = async e => {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
await fs_delete_all(file.path)
|
await fs_delete_all(file.path)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
alert(err)
|
alert(err)
|
||||||
return
|
return
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("loading", false)
|
nac.set_loading(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_after_edit) {
|
if (open_after_edit) {
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { onMount, createEventDispatcher } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { fs_mkdir } from "../FilesystemAPI.js";
|
import { fs_mkdir } from "../FilesystemAPI.js";
|
||||||
import Button from "../../layout/Button.svelte";
|
import Button from "../../layout/Button.svelte";
|
||||||
let dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
export let nav;
|
export let nav;
|
||||||
|
|
||||||
@@ -10,16 +9,15 @@ let name_input;
|
|||||||
let new_dir_name = ""
|
let new_dir_name = ""
|
||||||
let error_msg = ""
|
let error_msg = ""
|
||||||
let create_dir = async () => {
|
let create_dir = async () => {
|
||||||
dispatch("loading", true)
|
|
||||||
|
|
||||||
let form = new FormData()
|
let form = new FormData()
|
||||||
form.append("type", "dir")
|
form.append("type", "dir")
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
nav.set_loading(true)
|
||||||
await fs_mkdir(nav.base.path+"/"+new_dir_name)
|
await fs_mkdir(nav.base.path+"/"+new_dir_name)
|
||||||
new_dir_name = "" // Clear input field
|
new_dir_name = "" // Clear input field
|
||||||
error_msg = "" // Clear error msg
|
error_msg = "" // Clear error msg
|
||||||
dispatch("done")
|
nav.reload()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.value && err.value === "node_already_exists") {
|
if (err.value && err.value === "node_already_exists") {
|
||||||
error_msg = "A directory with this name 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
|
error_msg = "Server returned an error: "+err
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("loading", false)
|
nav.set_loading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,21 +1,16 @@
|
|||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from "svelte";
|
|
||||||
import FilePicker from "../../file_viewer/FilePicker.svelte";
|
import FilePicker from "../../file_viewer/FilePicker.svelte";
|
||||||
import { fs_import } from "../FilesystemAPI";
|
import { fs_import } from "../FilesystemAPI";
|
||||||
|
|
||||||
let dispatch = createEventDispatcher()
|
|
||||||
|
|
||||||
export let nav
|
export let nav
|
||||||
let file_picker
|
let file_picker
|
||||||
|
|
||||||
export const open = () => file_picker.open()
|
export const open = () => file_picker.open()
|
||||||
|
|
||||||
const import_files = async files => {
|
const import_files = async files => {
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
console.log(files)
|
|
||||||
|
|
||||||
let fileids = []
|
let fileids = []
|
||||||
|
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
fileids.push(file.id)
|
fileids.push(file.id)
|
||||||
})
|
})
|
||||||
@@ -31,10 +26,9 @@ const import_files = async files => {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("reload")
|
nav.reload()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<FilePicker
|
<FilePicker
|
||||||
|
@@ -97,7 +97,7 @@ const delete_selected = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Save all promises with deletion requests in an array
|
// Save all promises with deletion requests in an array
|
||||||
@@ -219,7 +219,7 @@ const move_start = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const move_here = async () => {
|
const move_here = async () => {
|
||||||
dispatch("loading", true)
|
nav.set_loading(true)
|
||||||
|
|
||||||
let target_dir = nav.base.path + "/"
|
let target_dir = nav.base.path + "/"
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ onMount(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if creating_dir}
|
{#if creating_dir}
|
||||||
<CreateDirectory nav={nav} on:done={() => nav.reload()} on:loading />
|
<CreateDirectory nav={nav} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $nav.base.path === "/me"}
|
{#if $nav.base.path === "/me"}
|
||||||
@@ -386,12 +386,7 @@ onMount(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<FileImporter
|
<FileImporter nav={nav} bind:this={file_importer} />
|
||||||
nav={nav}
|
|
||||||
bind:this={file_importer}
|
|
||||||
on:loading
|
|
||||||
on:reload={() => nav.reload()}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
|
@@ -52,7 +52,7 @@ export const toggle_playback = () => {
|
|||||||
<Spinner></Spinner>
|
<Spinner></Spinner>
|
||||||
</div>
|
</div>
|
||||||
{:else if viewer_type === "dir"}
|
{: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}/>
|
<CustomBanner path={$nav.path}/>
|
||||||
</FileManager>
|
</FileManager>
|
||||||
{:else if viewer_type === "audio"}
|
{:else if viewer_type === "audio"}
|
||||||
@@ -70,11 +70,11 @@ export const toggle_playback = () => {
|
|||||||
<CustomBanner path={$nav.path}/>
|
<CustomBanner path={$nav.path}/>
|
||||||
</Text>
|
</Text>
|
||||||
{:else if viewer_type === "torrent"}
|
{: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}/>
|
<CustomBanner path={$nav.path}/>
|
||||||
</Torrent>
|
</Torrent>
|
||||||
{:else if viewer_type === "zip"}
|
{: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}/>
|
<CustomBanner path={$nav.path}/>
|
||||||
</Zip>
|
</Zip>
|
||||||
{:else}
|
{:else}
|
||||||
|
@@ -15,9 +15,8 @@ export let nav
|
|||||||
let status = "loading"
|
let status = "loading"
|
||||||
|
|
||||||
export const update = async () => {
|
export const update = async () => {
|
||||||
dispatch("loading", true)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
nav.set_loading(true)
|
||||||
let resp = await fetch(fs_path_url(nav.base.path)+"?torrent_info")
|
let resp = await fetch(fs_path_url(nav.base.path)+"?torrent_info")
|
||||||
|
|
||||||
if (resp.status >= 400) {
|
if (resp.status >= 400) {
|
||||||
@@ -44,9 +43,9 @@ export const update = async () => {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("loading", false)
|
nav.set_loading(false)
|
||||||
}
|
|
||||||
status = "finished"
|
status = "finished"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let torrent = {
|
let torrent = {
|
||||||
|
@@ -21,8 +21,6 @@ let comp_ratio = 0
|
|||||||
let archive_type = ""
|
let archive_type = ""
|
||||||
|
|
||||||
export const update = async () => {
|
export const update = async () => {
|
||||||
dispatch("loading", true)
|
|
||||||
|
|
||||||
if (nav.base.file_type === "application/zip") {
|
if (nav.base.file_type === "application/zip") {
|
||||||
archive_type = "zip"
|
archive_type = "zip"
|
||||||
} else if (nav.base.file_type === "application/x-7z-compressed") {
|
} else if (nav.base.file_type === "application/x-7z-compressed") {
|
||||||
@@ -30,6 +28,7 @@ export const update = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
nav.set_loading(true)
|
||||||
let resp = await fetch(fs_path_url(nav.base.path)+"?zip_info")
|
let resp = await fetch(fs_path_url(nav.base.path)+"?zip_info")
|
||||||
|
|
||||||
if (resp.status >= 400) {
|
if (resp.status >= 400) {
|
||||||
@@ -51,10 +50,9 @@ export const update = async () => {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
} finally {
|
} finally {
|
||||||
dispatch("loading", false)
|
nav.set_loading(false)
|
||||||
}
|
|
||||||
|
|
||||||
status = "finished"
|
status = "finished"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const recursive_set_url = (parent_path, file) => {
|
const recursive_set_url = (parent_path, file) => {
|
||||||
|
Reference in New Issue
Block a user