Fork pd_web, remove everything we don't need

This commit is contained in:
2025-09-24 15:37:57 +02:00
parent 9dcdd94b3a
commit fd5cd0bfd1
415 changed files with 146269 additions and 120786 deletions

View File

@@ -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}>

View File

@@ -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) {

View File

@@ -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"

View File

@@ -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 () => {

View File

@@ -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
}
}

View File

@@ -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})}

View File

@@ -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>

View File

@@ -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%;

View File

@@ -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})}

View File

@@ -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}/>

View File

@@ -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>

View File

@@ -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";

View 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>