Add zip previewer
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
## File Methods
|
||||
|
||||
<details class="request_post">
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
|
||||
@@ -75,7 +75,7 @@ HTTP 413: Payload Too Large
|
||||
</div>
|
||||
</details>
|
||||
|
||||
<details class="request_put">
|
||||
<details class="api_doc_details request_put">
|
||||
<summary><span class="method">PUT</span>/file/{name}</summary>
|
||||
<div>
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
## File Methods
|
||||
|
||||
<details class="request_post">
|
||||
<details class="api_doc_details request_post">
|
||||
<summary><span class="method">POST</span>/file</summary>
|
||||
<div>
|
||||
|
||||
|
@@ -401,47 +401,47 @@ pre {
|
||||
|
||||
/* API documentation markup */
|
||||
|
||||
details {
|
||||
.api_doc_details {
|
||||
border-top: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
margin: 15px 0 15px 0;
|
||||
}
|
||||
|
||||
details>summary {
|
||||
.api_doc_details>summary {
|
||||
padding: 2px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
details>summary>.method {
|
||||
.api_doc_details>summary>.method {
|
||||
display: inline-block;
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
details>div {
|
||||
.api_doc_details>div {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
details.request_get {
|
||||
.api_doc_details.request_get {
|
||||
border-color: #3636ff;
|
||||
background-color: rgba(32, 32, 255, 0.2);
|
||||
}
|
||||
|
||||
details.request_post {
|
||||
.api_doc_details.request_post {
|
||||
border-color: #00d000;
|
||||
background-color: rgba(0, 255, 0, 0.05);
|
||||
}
|
||||
|
||||
details.request_delete {
|
||||
.api_doc_details.request_delete {
|
||||
border-color: #B00000;
|
||||
background-color: rgba(255, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
details.request_put {
|
||||
.api_doc_details.request_put {
|
||||
border-color: #B06000;
|
||||
background-color: rgba(255, 128, 0, 0.05);
|
||||
}
|
||||
|
||||
details.request_patch {
|
||||
.api_doc_details.request_patch {
|
||||
border-color: #6000B0;
|
||||
background-color: rgba(128, 0, 255, 0.1);
|
||||
}
|
||||
|
@@ -37,6 +37,8 @@ export const file_set_href = file => {
|
||||
export const file_type = file => {
|
||||
if (file.mime_type === "application/bittorrent" || file.mime_type === "application/x-bittorrent") {
|
||||
return "torrent"
|
||||
} else if (file.mime_type === "application/zip") {
|
||||
return "zip"
|
||||
} else if (file.mime_type.startsWith("image")) {
|
||||
return "image"
|
||||
} else if (
|
||||
|
@@ -13,6 +13,7 @@ import RateLimit from "./RateLimit.svelte";
|
||||
import Torrent from "./Torrent.svelte";
|
||||
import SpeedLimit from "./SpeedLimit.svelte";
|
||||
import { download_limits } from "../DownloadLimitStore";
|
||||
import Zip from "./Zip.svelte";
|
||||
|
||||
let viewer
|
||||
let viewer_type = "loading"
|
||||
@@ -68,7 +69,9 @@ export const set_file = async file => {
|
||||
{:else if viewer_type === "text"}
|
||||
<Text bind:this={viewer}></Text>
|
||||
{:else if viewer_type === "torrent"}
|
||||
<Torrent bind:this={viewer} on:loading on:download></Torrent>
|
||||
<Torrent bind:this={viewer} on:loading on:download />
|
||||
{:else if viewer_type === "zip"}
|
||||
<Zip bind:this={viewer} on:loading on:download />
|
||||
{:else if viewer_type === "file"}
|
||||
<File bind:this={viewer} on:download on:reload></File>
|
||||
{/if}
|
||||
|
100
svelte/src/file_viewer/viewers/Zip.svelte
Normal file
100
svelte/src/file_viewer/viewers/Zip.svelte
Normal file
@@ -0,0 +1,100 @@
|
||||
<script>
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import { formatDataVolume, formatDate } from "../../util/Formatting.svelte"
|
||||
import TextBlock from "./TextBlock.svelte";
|
||||
import ZipItem from "./ZipItem.svelte";
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
let status = "loading"
|
||||
|
||||
let file = {
|
||||
name: "",
|
||||
mime_type: "",
|
||||
size: 0,
|
||||
date_upload: "",
|
||||
icon_href: ""
|
||||
}
|
||||
let zip = {
|
||||
size: 0,
|
||||
children: null,
|
||||
}
|
||||
let uncomp_size = 0
|
||||
|
||||
export const set_file = async f => {
|
||||
file = f
|
||||
|
||||
dispatch("loading", true)
|
||||
|
||||
try {
|
||||
let resp = await fetch(f.info_href+"/zip")
|
||||
|
||||
if (resp.status >= 400) {
|
||||
status = "parse_failed"
|
||||
return
|
||||
}
|
||||
|
||||
zip = await resp.json()
|
||||
|
||||
uncomp_size = recursive_size(zip)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
} finally {
|
||||
dispatch("loading", false)
|
||||
}
|
||||
|
||||
status = "finished"
|
||||
}
|
||||
|
||||
const recursive_size = (file) => {
|
||||
let size = file.size
|
||||
|
||||
// If the file has children (array is iterable) we call this function on all
|
||||
// the children and add the size to our size accumulator
|
||||
if (file.children.forEach) {
|
||||
file.children.forEach(child => {
|
||||
size += recursive_size(child)
|
||||
});
|
||||
}
|
||||
|
||||
// Return the total size of this file and all its children
|
||||
return size
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>{file.name}</h1>
|
||||
|
||||
<img src={file.icon_href} alt="File icon" class="icon">
|
||||
<TextBlock width="600px">
|
||||
Compressed size: {formatDataVolume(file.size, 3)}<br/>
|
||||
Uncompressed size: {formatDataVolume(uncomp_size, 3)}<br/>
|
||||
Uploaded on: {formatDate(file.date_upload, true, true, true)}
|
||||
<br/>
|
||||
<button class="button_highlight" on:click={() => {dispatch("download")}}>
|
||||
<i class="icon">download</i>
|
||||
<span>Download</span>
|
||||
</button>
|
||||
</TextBlock>
|
||||
<br/><br/>
|
||||
|
||||
{#if status === "parse_failed"}
|
||||
<TextBlock width="650px">
|
||||
<p>
|
||||
Zip archive could not be parsed. It may be corrupted.
|
||||
</p>
|
||||
</TextBlock>
|
||||
{/if}
|
||||
|
||||
{#if status === "finished"}
|
||||
<TextBlock width="1000px">
|
||||
<h2>Files in this zip archive</h2>
|
||||
<ZipItem item={zip} />
|
||||
</TextBlock>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
text-shadow: 1px 1px 3px var(--shadow_color);
|
||||
line-break: anywhere;
|
||||
}
|
||||
</style>
|
44
svelte/src/file_viewer/viewers/ZipItem.svelte
Normal file
44
svelte/src/file_viewer/viewers/ZipItem.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<script>
|
||||
import { formatDataVolume } from "../../util/Formatting.svelte";
|
||||
|
||||
export let item = {
|
||||
size: 0,
|
||||
children: null,
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- First get directories and render them as details collapsibles -->
|
||||
{#each Object.entries(item.children) as [name, child]}
|
||||
{#if child.children}
|
||||
<details>
|
||||
<summary>
|
||||
{name} ({formatDataVolume(child.size, 3)})
|
||||
</summary>
|
||||
<svelte:self item={child}></svelte:self>
|
||||
</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>
|
||||
{name} ({formatDataVolume(child.size, 3)})<br/>
|
||||
</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ul>
|
||||
|
||||
<style>
|
||||
details {
|
||||
padding-left: 12px;
|
||||
border: none;
|
||||
border-left: 2px solid var(--separator);
|
||||
}
|
||||
ul {
|
||||
margin: 0;
|
||||
padding-left: 30px;
|
||||
border-left: 2px solid var(--separator);
|
||||
}
|
||||
</style>
|
@@ -53,7 +53,7 @@ onMount(() => {
|
||||
Data transfer limit
|
||||
</div>
|
||||
<div class="feat_normal">
|
||||
<span class="text_highlight">20 GB</span> data transfer per week
|
||||
Download limit of <span class="text_highlight">20 GB</span> per week
|
||||
(168 hours). When this threshold is reached your download speed will
|
||||
be reduced
|
||||
</div>
|
||||
@@ -153,7 +153,7 @@ onMount(() => {
|
||||
<p>
|
||||
Unlike most other sharing sites pixeldrain uses a postponing system for
|
||||
expiring files. When a file is freshly uploaded it gets 60 days by
|
||||
default (120 days if you have the pro plan). After these 60 days we will
|
||||
default (240 days if you have the pro plan). After these 60 days we will
|
||||
check when the file was last viewed. Files which are regularly viewed
|
||||
could still bring new users to the platform, it would be rude to show
|
||||
these people a File Not Found page. So if the file was viewed in the
|
||||
|
@@ -13,7 +13,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell round_tr">
|
||||
<div><span class="text_highlight">20 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">50 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">4 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">4 TB</span> storage space</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell">
|
||||
<div><span class="text_highlight">20 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">50 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">8 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">8 TB</span> storage space</div>
|
||||
@@ -60,7 +60,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell">
|
||||
<div><span class="text_highlight">20 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">50 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">16 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">16 TB</span> storage space</div>
|
||||
@@ -81,7 +81,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="feat_pro features_cell round_br">
|
||||
<div><span class="text_highlight">20 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">50 GB</span> max file size</div>
|
||||
<div><span class="text_highlight">Files never expire</span></div>
|
||||
<div><span class="text_highlight">32 TB</span> transfer limit</div>
|
||||
<div><span class="text_highlight">32 TB</span> storage space</div>
|
||||
|
Reference in New Issue
Block a user