Convert the whole filesystem UI to Typescript
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI.mjs"
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI"
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
export let nav
|
||||
export let nav: FSNavigator
|
||||
export let show_hidden = false
|
||||
export let large_icons = false
|
||||
</script>
|
||||
@@ -13,8 +14,8 @@ export let large_icons = false
|
||||
{#each $nav.children as child, index (child.path)}
|
||||
<a
|
||||
href={"/d"+fs_encode_path(child.path)}
|
||||
on:click|preventDefault={() => dispatch("node_click", index)}
|
||||
on:contextmenu={e => dispatch("node_context", {event: e, index: index})}
|
||||
on:click|preventDefault={e => dispatch("node_click", {index: index, original: e})}
|
||||
on:contextmenu={e => dispatch("node_context", {index: index, original: e})}
|
||||
class="node"
|
||||
class:node_selected={child.fm_selected}
|
||||
class:hidden={child.name.startsWith(".") && !show_hidden}
|
||||
@@ -26,7 +27,7 @@ export let large_icons = false
|
||||
{#if child.id}
|
||||
<a
|
||||
href="/d/{child.id}"
|
||||
on:click|preventDefault|stopPropagation={() => {dispatch("node_share_click", index)}}
|
||||
on:click|preventDefault|stopPropagation={e => {dispatch("node_share_click", {index: index, original: e})}}
|
||||
class="button action_button"
|
||||
>
|
||||
<i class="icon" title="This file / directory is shared. Click to open public link">share</i>
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { fs_mkdir } from "filesystem/FilesystemAPI.mjs";
|
||||
import { fs_mkdir } from "filesystem/FilesystemAPI";
|
||||
import Button from "layout/Button.svelte";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
export let nav;
|
||||
export let nav: FSNavigator
|
||||
|
||||
let name_input;
|
||||
let name_input: HTMLInputElement;
|
||||
let new_dir_name = ""
|
||||
let error_msg = ""
|
||||
let create_dir = async () => {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import FilePicker from "file_viewer/FilePicker.svelte";
|
||||
import { fs_import } from "filesystem/FilesystemAPI.mjs";
|
||||
import { fs_import } from "filesystem/FilesystemAPI";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
export let nav
|
||||
let file_picker
|
||||
export let nav: FSNavigator
|
||||
let file_picker: FilePicker
|
||||
|
||||
export const open = () => file_picker.open()
|
||||
|
||||
const import_files = async files => {
|
||||
// TODO: Give files a proper type
|
||||
const import_files = async (files: any) => {
|
||||
nav.set_loading(true)
|
||||
|
||||
let fileids = []
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<script>
|
||||
import { fs_delete_all, fs_rename } from "filesystem/FilesystemAPI.mjs"
|
||||
<script lang="ts" context="module">
|
||||
export type FMNodeEvent = {
|
||||
index: number,
|
||||
original: MouseEvent,
|
||||
}
|
||||
</script>
|
||||
<script lang="ts">
|
||||
import { fs_delete_all, fs_rename, type FSNode } from "filesystem/FilesystemAPI"
|
||||
import { onMount } from "svelte"
|
||||
import CreateDirectory from "./CreateDirectory.svelte"
|
||||
import ListView from "./ListView.svelte"
|
||||
@@ -7,29 +13,32 @@ import GalleryView from "./GalleryView.svelte"
|
||||
import CompactView from "./CompactView.svelte"
|
||||
import Button from "layout/Button.svelte";
|
||||
import FileImporter from "./FileImporter.svelte";
|
||||
import { formatDate } from "util/Formatting.svelte";
|
||||
import { drop_target } from "lib/DropTarget.ts"
|
||||
import { formatDate } from "util/Formatting";
|
||||
import { drop_target } from "lib/DropTarget"
|
||||
import SearchBar from "./SearchBar.svelte";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
import FsUploadWidget from "filesystem/upload_widget/FSUploadWidget.svelte";
|
||||
import EditWindow from "filesystem/edit_window/EditWindow.svelte";
|
||||
|
||||
export let nav
|
||||
export let upload_widget
|
||||
export let edit_window
|
||||
export let nav: FSNavigator
|
||||
export let upload_widget: FsUploadWidget
|
||||
export let edit_window: EditWindow
|
||||
export let directory_view = ""
|
||||
let large_icons = false
|
||||
let uploader
|
||||
let uploader: FsUploadWidget
|
||||
let mode = "viewing"
|
||||
let creating_dir = false
|
||||
let show_hidden = false
|
||||
let file_importer
|
||||
let file_importer: FileImporter
|
||||
|
||||
export const upload = files => {
|
||||
export const upload = (files: File[]) => {
|
||||
return uploader.upload(files)
|
||||
}
|
||||
|
||||
// Navigation functions
|
||||
|
||||
const node_click = e => {
|
||||
let index = e.detail
|
||||
const node_click = (e: CustomEvent<FMNodeEvent>) => {
|
||||
const index = e.detail.index
|
||||
|
||||
creating_dir = false
|
||||
|
||||
@@ -48,27 +57,29 @@ const node_click = e => {
|
||||
select_node(index)
|
||||
}
|
||||
}
|
||||
let node_context = e => {
|
||||
let node_context = (e: CustomEvent<FMNodeEvent>) => {
|
||||
// If this is a touch event we will select the item
|
||||
if (navigator.maxTouchPoints && navigator.maxTouchPoints > 0) {
|
||||
e.detail.event.preventDefault()
|
||||
node_select({detail: e.detail.index})
|
||||
e.detail.original.preventDefault()
|
||||
node_select(e)
|
||||
}
|
||||
}
|
||||
const node_share_click = e => {
|
||||
let index = e.detail
|
||||
|
||||
const node_share_click = (e: CustomEvent<FMNodeEvent>) => {
|
||||
creating_dir = false
|
||||
nav.navigate(nav.children[index].id, true)
|
||||
nav.navigate(nav.children[e.detail.index].id, true)
|
||||
}
|
||||
const node_select = e => {
|
||||
let index = e.detail
|
||||
const node_select = (e: CustomEvent<FMNodeEvent>) => {
|
||||
const index = e.detail.index
|
||||
mode = "selecting"
|
||||
nav.children[index].fm_selected = !nav.children[index].fm_selected
|
||||
}
|
||||
|
||||
const node_settings = e => edit_window.edit(nav.children[e.detail], false, "file")
|
||||
const node_branding = e => edit_window.edit(nav.children[e.detail], false, "branding")
|
||||
const node_settings = (e: CustomEvent<FMNodeEvent>) => {
|
||||
edit_window.edit(nav.children[e.detail.index], false, "file")
|
||||
}
|
||||
const node_branding = (e: CustomEvent<FMNodeEvent>) => {
|
||||
edit_window.edit(nav.children[e.detail.index], false, "branding")
|
||||
}
|
||||
|
||||
const navigate_back = () => {
|
||||
creating_dir = false
|
||||
@@ -147,7 +158,7 @@ const toggle_view = () => {
|
||||
}
|
||||
const toggle_large_icons = () => {
|
||||
large_icons = !large_icons
|
||||
localStorage.setItem("large_icons", large_icons)
|
||||
localStorage.setItem("large_icons", JSON.stringify(large_icons))
|
||||
}
|
||||
|
||||
// Moving functions
|
||||
@@ -157,7 +168,7 @@ let moving_items = []
|
||||
// We need to detect if shift is pressed so we can select multiple items
|
||||
let shift_pressed = false
|
||||
let last_selected_node = -1
|
||||
const keypress = e => {
|
||||
const keypress = (e: KeyboardEvent) => {
|
||||
if (e.key === "Shift") {
|
||||
shift_pressed = e.type === "keydown"
|
||||
} else if (e.type === "keydown" && e.key === "a" && e.ctrlKey) {
|
||||
@@ -176,7 +187,7 @@ const keypress = e => {
|
||||
}
|
||||
}
|
||||
|
||||
const select_node = index => {
|
||||
const select_node = (index: number) => {
|
||||
if (shift_pressed) {
|
||||
// If shift is pressed we do a range select. We select all files between
|
||||
// the last selected file and the file that is being selected now
|
||||
@@ -199,7 +210,7 @@ const select_node = index => {
|
||||
// function watches the children array for changes and updates the selection
|
||||
// when it changes
|
||||
$: update($nav.children)
|
||||
const update = (children) => {
|
||||
const update = (children: FSNode[]) => {
|
||||
creating_dir = false
|
||||
|
||||
// Highlight the files which were previously selected
|
||||
@@ -327,11 +338,7 @@ onMount(() => {
|
||||
<i class="icon">move_to_inbox</i>
|
||||
</button>
|
||||
|
||||
<button
|
||||
on:click={selecting_mode}
|
||||
class:button_highlight={mode === "selecting"}
|
||||
title="Select and delete files"
|
||||
>
|
||||
<button on:click={selecting_mode} title="Select and delete files">
|
||||
<i class="icon">select_all</i>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from "svelte"
|
||||
import ListView from "./ListView.svelte"
|
||||
import GalleryView from "./GalleryView.svelte"
|
||||
@@ -6,19 +6,20 @@ import CompactView from "./CompactView.svelte"
|
||||
import Modal from "util/Modal.svelte";
|
||||
import LoadingIndicator from "util/LoadingIndicator.svelte";
|
||||
import Breadcrumbs from "filesystem/Breadcrumbs.svelte"
|
||||
import { FSNavigator } from "filesystem/FSNavigator.js";
|
||||
import { FSNavigator } from "filesystem/FSNavigator";
|
||||
import type { FMNodeEvent } from "./FileManager.svelte";
|
||||
import type { FSNode } from "filesystem/FilesystemAPI";
|
||||
|
||||
let nav = new FSNavigator(false)
|
||||
let modal
|
||||
let modal: Modal
|
||||
let dispatch = createEventDispatcher()
|
||||
let directory_view = ""
|
||||
let loading = false
|
||||
const loading_evt = e => loading = e.detail
|
||||
let large_icons = false
|
||||
let show_hidden = false
|
||||
export let select_multiple = false
|
||||
|
||||
export const open = path => {
|
||||
export const open = (path: string) => {
|
||||
modal.show()
|
||||
nav.navigate(path, false)
|
||||
}
|
||||
@@ -32,8 +33,8 @@ $: selected_files = $nav.children.reduce((acc, file) => {
|
||||
|
||||
// Navigation functions
|
||||
|
||||
const node_click = e => {
|
||||
let index = e.detail
|
||||
const node_click = (e: CustomEvent<FMNodeEvent>) => {
|
||||
const index = e.detail.index
|
||||
|
||||
if (nav.children[index].type === "dir") {
|
||||
nav.navigate(nav.children[index].path, true)
|
||||
@@ -41,16 +42,15 @@ const node_click = e => {
|
||||
select_node(index)
|
||||
}
|
||||
}
|
||||
let node_context = e => {
|
||||
let node_context = (e: CustomEvent<FMNodeEvent>) => {
|
||||
// If this is a touch event we will select the item
|
||||
if (navigator.maxTouchPoints && navigator.maxTouchPoints > 0) {
|
||||
e.detail.event.preventDefault()
|
||||
node_select({detail: e.detail.index})
|
||||
e.detail.original.preventDefault()
|
||||
node_select(e)
|
||||
}
|
||||
}
|
||||
const node_select = e => {
|
||||
let index = e.detail
|
||||
mode = "selecting"
|
||||
const node_select = (e: CustomEvent<FMNodeEvent>) => {
|
||||
const index = e.detail.index
|
||||
nav.children[index].fm_selected = !nav.children[index].fm_selected
|
||||
}
|
||||
|
||||
@@ -69,13 +69,13 @@ const toggle_view = () => {
|
||||
// We need to detect if shift is pressed so we can select multiple items
|
||||
let shift_pressed = false
|
||||
let last_selected_node = -1
|
||||
const detect_shift = (e) => {
|
||||
const detect_shift = (e: KeyboardEvent) => {
|
||||
if (e.key === "Shift") {
|
||||
shift_pressed = e.type === "keydown"
|
||||
}
|
||||
}
|
||||
|
||||
const select_node = index => {
|
||||
const select_node = (index: number) => {
|
||||
if (select_multiple && shift_pressed) {
|
||||
// If shift is pressed we do a range select. We select all files between
|
||||
// the last selected file and the file that is being selected now
|
||||
@@ -101,7 +101,7 @@ const select_node = index => {
|
||||
}
|
||||
|
||||
let done = () => {
|
||||
let selected_files = []
|
||||
let selected_files: FSNode[] = []
|
||||
for (let i = 0; i < nav.children.length; i++) {
|
||||
if (nav.children[i].fm_selected) {
|
||||
selected_files.push(nav.children[i])
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { fs_node_icon, fs_node_type, fs_encode_path } from "filesystem/FilesystemAPI.mjs";
|
||||
import { fs_node_icon, fs_node_type, fs_encode_path } from "filesystem/FilesystemAPI";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
export let nav
|
||||
export let nav: FSNavigator
|
||||
export let show_hidden = false
|
||||
export let large_icons = false
|
||||
</script>
|
||||
@@ -12,8 +13,8 @@ export let large_icons = false
|
||||
{#each $nav.children as child, index (child.path)}
|
||||
<a class="file"
|
||||
href={"/d"+fs_encode_path(child.path)}
|
||||
on:click|preventDefault={() => dispatch("node_click", index)}
|
||||
on:contextmenu={e => dispatch("node_context", {event: e, index: index})}
|
||||
on:click|preventDefault={e => dispatch("node_click", {index: index, original: e})}
|
||||
on:contextmenu={e => dispatch("node_context", {index: index, original: e})}
|
||||
class:selected={child.fm_selected}
|
||||
class:hidden={child.name.startsWith(".") && !show_hidden}
|
||||
class:large_icons
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { formatDataVolume } from "util/Formatting.svelte";
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI.mjs"
|
||||
import { formatDataVolume } from "util/Formatting";
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI"
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
export let nav
|
||||
export let nav: FSNavigator
|
||||
export let show_hidden = false
|
||||
export let large_icons = false
|
||||
export let hide_edit = false
|
||||
@@ -22,8 +23,8 @@ export let hide_branding = false
|
||||
{#each $nav.children as child, index (child.path)}
|
||||
<a
|
||||
href={"/d"+fs_encode_path(child.path)}
|
||||
on:click|preventDefault={() => dispatch("node_click", index)}
|
||||
on:contextmenu={e => dispatch("node_context", {event: e, index: index})}
|
||||
on:click|preventDefault={e => dispatch("node_click", {index: index, original: e})}
|
||||
on:contextmenu={e => dispatch("node_context", {index: index, original: e})}
|
||||
class="node"
|
||||
class:node_selected={child.fm_selected}
|
||||
class:hidden={child.name.startsWith(".") && !show_hidden}
|
||||
@@ -46,19 +47,19 @@ export let hide_branding = false
|
||||
{:else if child.id}
|
||||
<a
|
||||
href="/d/{child.id}"
|
||||
on:click|preventDefault|stopPropagation={() => {dispatch("node_share_click", index)}}
|
||||
on:click|preventDefault|stopPropagation={e => {dispatch("node_share_click", {index: index, original: e})}}
|
||||
class="button action_button"
|
||||
>
|
||||
<i class="icon" title="This file / directory is shared. Click to open public link">share</i>
|
||||
</a>
|
||||
{/if}
|
||||
{#if child.properties && child.properties.branding_enabled && !hide_branding}
|
||||
<button class="action_button" on:click|preventDefault|stopPropagation={() => dispatch("node_branding", index)}>
|
||||
{#if child.properties !== undefined && child.properties.branding_enabled !== undefined && !hide_branding}
|
||||
<button class="action_button" on:click|preventDefault|stopPropagation={e => dispatch("node_branding", {index: index, original: e})}>
|
||||
<i class="icon">palette</i>
|
||||
</button>
|
||||
{/if}
|
||||
{#if $nav.permissions.write && !hide_edit}
|
||||
<button class="action_button" on:click|preventDefault|stopPropagation={() => dispatch("node_settings", index)}>
|
||||
<button class="action_button" on:click|preventDefault|stopPropagation={e => dispatch("node_settings", {index: index, original: e})}>
|
||||
<i class="icon">edit</i>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { fs_search, fs_encode_path, fs_thumbnail_url } from "filesystem/FilesystemAPI.mjs";
|
||||
import { fs_search, fs_encode_path, fs_thumbnail_url } from "filesystem/FilesystemAPI";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
export let nav
|
||||
export let nav: FSNavigator
|
||||
|
||||
let search_bar
|
||||
let search_bar: HTMLInputElement
|
||||
let error = ""
|
||||
let search_term = ""
|
||||
let search_results = []
|
||||
let search_results: string[] = []
|
||||
let selected_result = 0
|
||||
let searching = false
|
||||
let last_searched_term = ""
|
||||
@@ -71,7 +72,7 @@ const search = async (limit = 10) => {
|
||||
}
|
||||
}
|
||||
|
||||
const clear_search = (blur) => {
|
||||
const clear_search = (blur: boolean) => {
|
||||
error = ""
|
||||
search_term = ""
|
||||
search_results = []
|
||||
@@ -89,12 +90,12 @@ const clear_search = (blur) => {
|
||||
|
||||
// Cursor navigation events can only be prevented with keydown. But we want to
|
||||
// use keyup for searching, so we use two listeners here
|
||||
const input_keydown = e => {
|
||||
const input_keydown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape" || e.key === "ArrowUp" || e.key === "ArrowDown") {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
const input_keyup = e => {
|
||||
const input_keyup = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
clear_search(true)
|
||||
} else if (e.key === "ArrowUp") {
|
||||
@@ -117,15 +118,15 @@ const submit_search = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const open_result = index => {
|
||||
const open_result = (index: number) => {
|
||||
nav.navigate(search_results[index], true)
|
||||
clear_search(false)
|
||||
}
|
||||
|
||||
const window_keydown = (e) => {
|
||||
const window_keydown = (e: KeyboardEvent) => {
|
||||
if (e.ctrlKey || e.altKey || e.metaKey) {
|
||||
return // prevent custom shortcuts from interfering with system shortcuts
|
||||
} else if (document.activeElement.type && document.activeElement.type === "text") {
|
||||
} else if ((document.activeElement as any).type !== undefined && (document.activeElement as any).type === "text") {
|
||||
return // Prevent shortcuts from interfering with input fields
|
||||
}
|
||||
|
||||
@@ -171,7 +172,7 @@ const window_keydown = (e) => {
|
||||
/>
|
||||
{#if search_term !== ""}
|
||||
<!-- Button needs to be of button type in order to not submit the form -->
|
||||
<button on:click={clear_search} type="button">
|
||||
<button on:click={() => clear_search(false)} type="button">
|
||||
<i class="icon">close</i>
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user