Fork pd_web, remove everything we don't need
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { fs_encode_path } from "./FilesystemAPI";
|
||||
import { fs_encode_path, node_is_shared } from "./FilesystemAPI";
|
||||
import type { FSNavigator } from "./FSNavigator";
|
||||
|
||||
export let nav: FSNavigator
|
||||
@@ -7,7 +7,6 @@ export let nav: FSNavigator
|
||||
|
||||
<div class="breadcrumbs">
|
||||
{#each $nav.path as node, i (node.path)}
|
||||
{@const shared = node.id !== undefined && node.id !== "me"}
|
||||
<a
|
||||
href={"/d"+fs_encode_path(node.path)}
|
||||
class="breadcrumb button"
|
||||
@@ -16,7 +15,7 @@ export let nav: FSNavigator
|
||||
>
|
||||
{#if node.abuse_type !== undefined}
|
||||
<i class="icon small">block</i>
|
||||
{:else if shared}
|
||||
{:else if node_is_shared(node)}
|
||||
<i class="icon small">share</i>
|
||||
{/if}
|
||||
<div class="node_name" class:base={$nav.base_index === i}>
|
||||
|
@@ -11,8 +11,6 @@ import { fs_download, type FSPath } from "./FilesystemAPI";
|
||||
import Menu from "./Menu.svelte";
|
||||
import { FSNavigator } from "./FSNavigator"
|
||||
import { writable } from "svelte/store";
|
||||
import TransferLimit from "file_viewer/TransferLimit.svelte";
|
||||
import { stats } from "lib/StatsSocket"
|
||||
import { css_from_path } from "filesystem/edit_window/Branding";
|
||||
import AffiliatePrompt from "user_home/AffiliatePrompt.svelte";
|
||||
|
||||
@@ -160,21 +158,6 @@ const keydown = (e: KeyboardEvent) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $nav.context.premium_transfer === false}
|
||||
<div class="download_limit">
|
||||
{#if $stats.limits.transfer_limit_used > $stats.limits.transfer_limit}
|
||||
<div class="highlight_yellow">
|
||||
Your free download limit has been used up and your download
|
||||
speed has been limited to 1 MiB/s. <a href="/#pro"
|
||||
target="_blank">Upgrade to premium</a> to continue fast
|
||||
downloading
|
||||
</div>
|
||||
{:else}
|
||||
<TransferLimit/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<DetailsWindow nav={nav} bind:visible={details_visible} />
|
||||
|
||||
<EditWindow nav={nav} bind:this={edit_window} bind:visible={edit_visible} />
|
||||
@@ -239,16 +222,6 @@ const keydown = (e: KeyboardEvent) => {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Download limit gauge (row 3) */
|
||||
.download_limit {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
background-color: var(--shaded_background);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
/* This max-width needs to be synced with the .toolbar max-width in
|
||||
Toolbar.svelte and the .label max-width in FileStats.svelte */
|
||||
@media (max-width: 1000px) {
|
||||
|
@@ -15,34 +15,41 @@ export type FSPath = {
|
||||
}
|
||||
|
||||
export type FSNode = {
|
||||
type: string,
|
||||
path: string,
|
||||
name: string,
|
||||
created: string,
|
||||
modified: string,
|
||||
mode_string: string,
|
||||
mode_octal: string,
|
||||
created_by: string,
|
||||
type: string
|
||||
path: string
|
||||
name: string
|
||||
created: string
|
||||
modified: string
|
||||
mode_string: string
|
||||
mode_octal: string
|
||||
created_by: string
|
||||
|
||||
abuse_type?: string,
|
||||
abuse_report_time?: string,
|
||||
abuse_type?: string
|
||||
abuse_report_time?: string
|
||||
|
||||
custom_domain_name?: string,
|
||||
custom_domain_name?: string
|
||||
|
||||
file_size: number,
|
||||
file_type: string,
|
||||
sha256_sum: string,
|
||||
file_size: number
|
||||
file_type: string
|
||||
sha256_sum: string
|
||||
|
||||
id?: string,
|
||||
properties?: FSNodeProperties,
|
||||
link_permissions?: FSPermissions,
|
||||
user_permissions?: { [index: string]: FSPermissions },
|
||||
password_permissions?: { [index: string]: FSPermissions },
|
||||
id?: string
|
||||
properties?: FSNodeProperties
|
||||
link_permissions?: FSPermissions
|
||||
user_permissions?: { [index: string]: FSPermissions }
|
||||
password_permissions?: { [index: string]: FSPermissions }
|
||||
|
||||
// Added by us
|
||||
|
||||
// Indicates whether the file is selected in the file manager
|
||||
fm_selected?: boolean,
|
||||
fm_selected?: boolean
|
||||
}
|
||||
|
||||
export const node_is_shared = (node: FSNode): boolean => {
|
||||
if (node.link_permissions !== undefined && node.link_permissions.read) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export type FSNodeProperties = {
|
||||
@@ -81,7 +88,6 @@ export type NodeOptions = {
|
||||
mode?: number,
|
||||
created?: string,
|
||||
modified?: string,
|
||||
shared?: boolean,
|
||||
|
||||
// Permissions
|
||||
link_permissions?: FSPermissions,
|
||||
@@ -316,7 +322,7 @@ export const fs_node_type = (node: FSNode) => {
|
||||
export const fs_node_icon = (node: FSNode, width = 64, height = 64) => {
|
||||
if (node.type === "dir") {
|
||||
// Folders with an ID are publically shared, use the shared folder icon
|
||||
if (node.id) {
|
||||
if (node_is_shared(node)) {
|
||||
return "/res/img/mime/folder-remote.png"
|
||||
} else {
|
||||
return "/res/img/mime/folder.png"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { FSNavigator } from "./FSNavigator";
|
||||
import { fs_node_icon, fs_share_hotlink_url, fs_share_url, fs_update, type FSNode } from "./FilesystemAPI";
|
||||
import { fs_node_icon, fs_share_hotlink_url, fs_share_url, fs_update, node_is_shared, type FSNode, type FSPermissions } from "./FilesystemAPI";
|
||||
import { copy_text } from "util/Util.svelte";
|
||||
import CopyButton from "layout/CopyButton.svelte";
|
||||
import Dialog from "layout/Dialog.svelte";
|
||||
@@ -36,11 +36,16 @@ export const open = async (e: MouseEvent, p: FSNode[]) => {
|
||||
}
|
||||
|
||||
const make_public = async () => {
|
||||
base = await fs_update(base.path, {shared: true})
|
||||
await nav.reload()
|
||||
if (!node_is_shared(base)) {
|
||||
base = await fs_update(
|
||||
base.path,
|
||||
{link_permissions: {read: true} as FSPermissions},
|
||||
)
|
||||
await nav.reload()
|
||||
|
||||
// Insert the new FSNode into the path
|
||||
path[path.length-1] = base
|
||||
// Insert the new FSNode into the path
|
||||
path[path.length-1] = base
|
||||
}
|
||||
}
|
||||
|
||||
const share = async () => {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import ThemePresets from "./ThemePresets.svelte";
|
||||
import { fs_update, fs_node_type, type FSNode, type NodeOptions } from "filesystem/FilesystemAPI";
|
||||
import { fs_update, fs_node_type, type FSNode, type NodeOptions, node_is_shared, type FSPermissions } from "filesystem/FilesystemAPI";
|
||||
import CustomBanner from "filesystem/viewers/CustomBanner.svelte";
|
||||
import HelpButton from "layout/HelpButton.svelte";
|
||||
import FilePicker from "filesystem/filemanager/FilePicker.svelte";
|
||||
@@ -32,8 +32,7 @@ const handle_picker = async (e: CustomEvent<FSNode[]>) => {
|
||||
alert("Please select one file")
|
||||
return
|
||||
}
|
||||
const f = e.detail[0]
|
||||
let file_id = f.id
|
||||
let f = e.detail[0]
|
||||
|
||||
if (fs_node_type(f) !== "image") {
|
||||
alert("Please select an image file")
|
||||
@@ -44,19 +43,21 @@ const handle_picker = async (e: CustomEvent<FSNode[]>) => {
|
||||
}
|
||||
|
||||
// If this image is not public, it will be made public
|
||||
if (file_id === undefined || file_id === "") {
|
||||
if (!node_is_shared(f)) {
|
||||
try {
|
||||
let new_file = await fs_update(e.detail[0].path, {shared: true})
|
||||
file_id = new_file.id
|
||||
f = await fs_update(
|
||||
e.detail[0].path,
|
||||
{link_permissions: {read: true} as FSPermissions},
|
||||
)
|
||||
} catch (err) {
|
||||
alert(err)
|
||||
}
|
||||
}
|
||||
|
||||
if (picking === "brand_header_image") {
|
||||
options.brand_header_image = file_id
|
||||
options.brand_header_image = f.id
|
||||
} else if (picking === "brand_background_image") {
|
||||
options.brand_background_image = file_id
|
||||
options.brand_background_image = f.id
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI"
|
||||
import { fs_encode_path, fs_node_icon, node_is_shared } from "filesystem/FilesystemAPI"
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
import { FileAction } from "./FileManagerLib";
|
||||
|
||||
@@ -26,7 +26,7 @@ export let hide_edit = false
|
||||
<div class="node_name">
|
||||
{child.name}
|
||||
</div>
|
||||
{#if child.id}
|
||||
{#if node_is_shared(child)}
|
||||
<a
|
||||
href="/d/{child.id}"
|
||||
on:click={e => dispatch("file", {index: index, action: FileAction.Share, original: e})}
|
||||
|
@@ -1,41 +0,0 @@
|
||||
<script lang="ts">
|
||||
import FilePicker from "file_viewer/FilePicker.svelte";
|
||||
import { fs_import } from "filesystem/FilesystemAPI";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
|
||||
export let nav: FSNavigator
|
||||
let file_picker: FilePicker
|
||||
|
||||
export const open = () => file_picker.open()
|
||||
|
||||
// TODO: Give files a proper type
|
||||
const import_files = async (files: any) => {
|
||||
nav.set_loading(true)
|
||||
|
||||
let fileids = []
|
||||
files.forEach(file => {
|
||||
fileids.push(file.id)
|
||||
})
|
||||
|
||||
try {
|
||||
await fs_import(nav.base.path, fileids)
|
||||
} catch (err) {
|
||||
if (err.message) {
|
||||
alert(err.message)
|
||||
} else {
|
||||
console.error(err)
|
||||
alert(err)
|
||||
}
|
||||
return
|
||||
} finally {
|
||||
nav.reload()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<FilePicker
|
||||
bind:this={file_picker}
|
||||
on:files={e => {import_files(e.detail)}}
|
||||
multi_select={true}
|
||||
title="Import files from file list">
|
||||
</FilePicker>
|
@@ -6,7 +6,6 @@ import ListView from "./ListView.svelte"
|
||||
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";
|
||||
import { drop_target } from "lib/DropTarget"
|
||||
import SearchBar from "./SearchBar.svelte";
|
||||
@@ -24,7 +23,6 @@ let uploader: FsUploadWidget
|
||||
let mode = "viewing"
|
||||
let creating_dir = false
|
||||
let show_hidden = false
|
||||
let file_importer: FileImporter
|
||||
|
||||
export const upload = (files: File[]) => {
|
||||
return uploader.upload(files)
|
||||
@@ -303,8 +301,6 @@ onMount(() => {
|
||||
>
|
||||
<div class="width_container">
|
||||
{#if mode === "viewing"}
|
||||
<SearchBar nav={nav}/>
|
||||
|
||||
<div class="toolbar">
|
||||
<div class="toolbar_left">
|
||||
<button on:click={navigate_back} title="Back">
|
||||
@@ -350,16 +346,15 @@ onMount(() => {
|
||||
|
||||
<Button click={() => {creating_dir = !creating_dir}} highlight={creating_dir} icon="create_new_folder" title="Make folder"/>
|
||||
|
||||
<button on:click={() => file_importer.open()} title="Import files from list">
|
||||
<i class="icon">move_to_inbox</i>
|
||||
</button>
|
||||
|
||||
<button on:click={selecting_mode} title="Select and delete files">
|
||||
<i class="icon">select_all</i>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SearchBar nav={nav}/>
|
||||
|
||||
{:else if mode === "selecting"}
|
||||
<div class="toolbar toolbar_edit">
|
||||
<Button click={viewing_mode} icon="close"/>
|
||||
@@ -415,8 +410,6 @@ onMount(() => {
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<FileImporter nav={nav} bind:this={file_importer} />
|
||||
|
||||
<style>
|
||||
.container {
|
||||
height: 100%;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { formatDataVolume } from "util/Formatting";
|
||||
import { fs_encode_path, fs_node_icon } from "filesystem/FilesystemAPI"
|
||||
import { fs_encode_path, fs_node_icon, node_is_shared } from "filesystem/FilesystemAPI"
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
import SortButton from "layout/SortButton.svelte";
|
||||
import { FileAction } from "./FileManagerLib";
|
||||
@@ -46,7 +46,7 @@ export let hide_branding = false
|
||||
<div class="icons_wrap">
|
||||
{#if child.abuse_type !== undefined}
|
||||
<i class="icon" title="This file / directory has received an abuse report. It cannot be shared">block</i>
|
||||
{:else if child.id}
|
||||
{:else if node_is_shared(child)}
|
||||
<a
|
||||
href="/d/{child.id}"
|
||||
on:click={e => dispatch("file", {index: index, action: FileAction.Share, original: e})}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { onMount, tick } from "svelte";
|
||||
import Spinner from "util/Spinner.svelte";
|
||||
import { fs_node_type, fs_thumbnail_url } from "filesystem/FilesystemAPI";
|
||||
import { fs_node_type } from "filesystem/FilesystemAPI";
|
||||
import FileManager from "filesystem/filemanager/FileManager.svelte";
|
||||
import Audio from "./Audio.svelte";
|
||||
import File from "./File.svelte";
|
||||
@@ -12,8 +12,6 @@ import Video from "./Video.svelte";
|
||||
import Torrent from "./Torrent.svelte";
|
||||
import Zip from "./Zip.svelte";
|
||||
import CustomBanner from "./CustomBanner.svelte";
|
||||
import { stats } from "lib/StatsSocket"
|
||||
import SlowDown from "layout/SlowDown.svelte";
|
||||
import type { FSNavigator } from "filesystem/FSNavigator";
|
||||
import FsUploadWidget from "filesystem/upload_widget/FSUploadWidget.svelte";
|
||||
import EditWindow from "filesystem/edit_window/EditWindow.svelte";
|
||||
@@ -82,14 +80,6 @@ export const seek = (delta: number) => {
|
||||
<FileManager nav={nav} upload_widget={upload_widget} edit_window={edit_window}>
|
||||
<CustomBanner path={$nav.path}/>
|
||||
</FileManager>
|
||||
{:else if $nav.context.premium_transfer === false && $stats.limits.transfer_limit_used > $stats.limits.transfer_limit}
|
||||
<SlowDown
|
||||
on:download
|
||||
file_size={$nav.base.file_size}
|
||||
file_name={$nav.base.name}
|
||||
file_type={$nav.base.file_type}
|
||||
icon_href={fs_thumbnail_url($nav.base.path, 256, 256)}
|
||||
/>
|
||||
{:else if viewer_type === "audio"}
|
||||
<Audio nav={nav} bind:this={viewer}>
|
||||
<CustomBanner path={$nav.path}/>
|
||||
@@ -99,7 +89,7 @@ export const seek = (delta: number) => {
|
||||
{:else if viewer_type === "video"}
|
||||
<Video nav={nav} bind:this={viewer} on:open_sibling/>
|
||||
{:else if viewer_type === "pdf"}
|
||||
<Pdf nav={nav}/>
|
||||
<Pdf nav={nav} bind:this={viewer}/>
|
||||
{:else if viewer_type === "text"}
|
||||
<Text nav={nav} bind:this={viewer}>
|
||||
<CustomBanner path={$nav.path}/>
|
||||
|
@@ -7,7 +7,7 @@ export let nav: FSNavigator
|
||||
|
||||
<iframe
|
||||
class="container"
|
||||
src={"/res/misc/pdf-viewer/web/viewer.html?file="+encodeURIComponent(fs_path_url($nav.base.path))}
|
||||
src={"/res/misc/pdf-viewer/web/viewer.html?file="+fs_path_url($nav.base.path)}
|
||||
title="PDF viewer">
|
||||
</iframe>
|
||||
|
||||
|
@@ -10,7 +10,7 @@ export type ZipEntry = {
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { formatDataVolume, formatDate } from "util/Formatting"
|
||||
import ZipItem from "file_viewer/viewers/ZipItem.svelte";
|
||||
import ZipItem from "filesystem/viewers/ZipItem.svelte";
|
||||
import IconBlock from "layout/IconBlock.svelte";
|
||||
import TextBlock from "layout/TextBlock.svelte"
|
||||
import { fs_node_icon, fs_path_url } from "filesystem/FilesystemAPI";
|
||||
|
83
svelte/src/filesystem/viewers/ZipItem.svelte
Normal file
83
svelte/src/filesystem/viewers/ZipItem.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script lang="ts">
|
||||
import type { ZipEntry } from "filesystem/viewers/Zip.svelte";
|
||||
import { formatDataVolume } from "util/Formatting";
|
||||
|
||||
export let item: ZipEntry = {} as ZipEntry
|
||||
</script>
|
||||
|
||||
<!-- First get directories and render them as details collapsibles -->
|
||||
{#each Object.entries(item.children) as [name, child]}
|
||||
{#if child.children}
|
||||
<details bind:open={child.details_open}>
|
||||
<summary>
|
||||
<div class="filename">
|
||||
{name}
|
||||
(
|
||||
{formatDataVolume(child.size, 3)}
|
||||
{#if child.download_url}
|
||||
<a href={child.download_url}>download</a>
|
||||
{/if}
|
||||
)
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
<!-- Performance optimization, only render children if details is expanded -->
|
||||
{#if child.details_open}
|
||||
<svelte:self item={child}></svelte:self>
|
||||
{/if}
|
||||
</details>
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
<!-- Then get files and render them as list items -->
|
||||
<ul>
|
||||
{#each Object.entries(item.children) as [name, child]}
|
||||
{#if !child.children}
|
||||
<li>
|
||||
<div class="filename">
|
||||
{name}
|
||||
(
|
||||
{formatDataVolume(child.size, 3)}
|
||||
{#if child.download_url}
|
||||
<a href={child.download_url}>download</a>
|
||||
{/if}
|
||||
)
|
||||
</div>
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<style>
|
||||
details {
|
||||
padding-left: 0.5em;
|
||||
border: none;
|
||||
border-left: 2px solid var(--separator);
|
||||
}
|
||||
details > summary {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
}
|
||||
details > summary::before {
|
||||
font-family: 'Material Icons';
|
||||
content: 'folder';
|
||||
}
|
||||
details[open] > summary::before {
|
||||
font-family: 'Material Icons';
|
||||
content: 'folder_open';
|
||||
}
|
||||
li::before {
|
||||
font-family: 'Material Icons';
|
||||
content: 'description';
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0.5em;
|
||||
margin: 0;
|
||||
border-left: 2px solid var(--separator);
|
||||
}
|
||||
.filename {
|
||||
display: inline;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user