Add menu button to filesystem

This commit is contained in:
2024-03-12 17:53:53 +01:00
parent 8d61e9d4cd
commit 6376e67cd7
10 changed files with 162 additions and 61 deletions

12
go.mod
View File

@@ -1,6 +1,8 @@
module fornaxian.tech/pixeldrain_web
go 1.18
go 1.21
toolchain go1.22.0
replace (
fornaxian.tech/pixeldrain_api_client => ../pixeldrain_api_client
@@ -13,7 +15,7 @@ require (
fornaxian.tech/pixeldrain_api_client v0.0.0-20221207191816-6872676df741
fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7
github.com/julienschmidt/httprouter v1.3.0
github.com/microcosm-cc/bluemonday v1.0.25
github.com/microcosm-cc/bluemonday v1.0.26
github.com/russross/blackfriday/v2 v2.1.0
)
@@ -22,9 +24,9 @@ require (
github.com/aymerick/douceur v0.2.0 // indirect
github.com/gocql/gocql v1.6.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/css v1.0.1 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/net v0.15.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.22.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
)

28
go.sum
View File

@@ -2,10 +2,6 @@ fornaxian.tech/config v0.0.0-20211108212237-6133aed90586 h1:/4a0Iq3cYeyTWcPHsN9p
fornaxian.tech/config v0.0.0-20211108212237-6133aed90586/go.mod h1:ULIXF4J1DbBw4EsIPRNQDf6J3hl4P/jlihjy6UCm9FM=
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640 h1:UPDxJwLRCfh/cv80UMSanzmZ0jIcfS1mcd0Y06HYuLw=
fornaxian.tech/log v0.0.0-20211102185326-552e9b1f8640/go.mod h1:sN82qMToeHhP2u3ehvrcE8y1IudRZJAZO9yG5OBYblo=
fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7 h1:8I/BQQYO/cjREsGP+1fUqaXXM4dQ3BWfARnaUScLIec=
fornaxian.tech/util v0.0.0-20230520114728-bd827686fec7/go.mod h1:lCmtcb4/SVt2ol55/EHDWGySY7o0ONbj97RR9CdsN4M=
github.com/BurntSushi/toml v1.3.0 h1:Ws8e5YmnrGEHzZEzg0YvK/7COGYtTC5PbaH9oSSbgfA=
github.com/BurntSushi/toml v1.3.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
@@ -15,15 +11,13 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gocql/gocql v1.4.0 h1:NIlXAJXsjzjGvVn36njh9OLYWzS3D7FdvsifLj4eDEY=
github.com/gocql/gocql v1.4.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
github.com/gocql/gocql v1.6.0 h1:IdFdOTbnpbd0pDhl4REKQDM+Q0SzKXQ1Yh+YZZ8T/qU=
github.com/gocql/gocql v1.6.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
@@ -33,22 +27,16 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw=
github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8=
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=

View File

@@ -150,7 +150,7 @@ client in memory until the client acknowledges (ACK) that it has been properly
received. The acknowledgment takes one round trip to the client and back.
Let's say you want to send a file from Amsterdam to Tokyo. The server sends the
first packet, 130ms later the client on Tokyo receives the data packet. The
first packet, 130ms later the client in Tokyo receives the data packet. The
client then sends ACK to tell the server that the packet was properly received,
the ACK takes 130ms to arrive back in Amsterdam. Only now can the server remove
the packet from memory. The whole exchange took 260ms.

View File

@@ -1,4 +1,5 @@
<script>
import { flip } from "svelte/animate";
import { formatDataVolume } from "../util/Formatting.svelte";
import SortButton from "./SortButton.svelte";
@@ -66,11 +67,12 @@ let sort = (field) => {
</tr>
</thead>
<tbody>
{#each peers as peer}
{#each peers as peer (peer.address)}
<tr style="border: none;"
class:highlight_red={peer.free_space < peer.min_free_space / 2 || !peer.reachable}
class:highlight_yellow={peer.free_space < peer.min_free_space}
class:highlight_green={peer.reachable}
animate:flip={{duration: 1000}}
>
<td>{peer.address}</td>
<td>{peer.unreachable_count}</td>

View File

@@ -9,9 +9,9 @@ import Navigator from './Navigator.svelte';
import FilePreview from './viewers/FilePreview.svelte';
import SearchView from './SearchView.svelte';
import UploadWidget from './upload_widget/UploadWidget.svelte';
import HomeButton from '../file_viewer/HomeButton.svelte';
import { fs_path_url } from './FilesystemUtil.js';
import { branding_from_path } from './edit_window/Branding.js'
import Menu from './Menu.svelte';
let loading = true
let toolbar
@@ -44,6 +44,7 @@ const keydown = e => {
return // Prevent shortcuts from interfering with input fields
}
let action_performed = true
switch (e.key) {
case "c":
toolbar.copy_link()
@@ -76,9 +77,13 @@ const keydown = e => {
case "ArrowRight":
fs_navigator.open_sibling(1)
break;
default:
action_performed = false
}
e.preventDefault()
if (action_performed) {
e.preventDefault()
}
};
const download = () => {
@@ -116,10 +121,7 @@ const update_css = path => document.documentElement.style = branding_from_path(p
<div class="file_viewer">
<div class="headerbar">
<div>
<HomeButton nobg/>
</div>
<Menu/>
<Breadcrumbs state={state} fs_navigator={fs_navigator}/>
</div>
@@ -158,10 +160,6 @@ const update_css = path => document.documentElement.style = branding_from_path(p
</div>
</div>
<div class="highlight_yellow">
The filesystem is experimental! <a href="/filesystem">Please read the guide</a>
</div>
<!-- This frame will load the download URL when a download button is pressed -->
<iframe
bind:this={download_frame}
@@ -228,13 +226,6 @@ const update_css = path => document.documentElement.style = branding_from_path(p
padding: 4px;
}
/* Headerbar components */
.headerbar > * {
flex-grow: 0;
flex-shrink: 0;
display: inline;
align-self: center;
}
/* File preview area (row 2) */
.viewer_area {
flex: 1 1 0;

View File

@@ -0,0 +1,103 @@
<script>
import PixeldrainLogo from "../util/PixeldrainLogo.svelte";
import Button from "../layout/Button.svelte";
import Euro from "../util/Euro.svelte";
import { formatDataVolume } from "../util/Formatting.svelte";
let button
let dialog
const open = () => {
dialog.showModal()
let rect = button.getBoundingClientRect()
dialog.style.top = Math.round(rect.bottom) + "px"
dialog.style.left = Math.round(rect.left) + "px"
}
// Close the dialog when the user clicks the background
const click = e => {
if (e.target === dialog) {
dialog.close()
}
}
</script>
<div class="wrapper">
<button bind:this={button} on:click={open} href="/user" class="button round" title="Menu">
<PixeldrainLogo style="height: 1.6em; width: 1.6em; margin: 0;"></PixeldrainLogo>
<span>
{window.user.username === "" ? "Pixeldrain" : window.user.username}
</span>
</button>
</div>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<dialog bind:this={dialog} on:click={click}>
<div class="menu">
{#if window.user.username !== ""}
<div class="stats_table">
<div>Subscription</div>
<div>{window.user.subscription.name}</div>
{#if window.user.subscription.type === "prepaid"}
<div>Credit</div>
<div><Euro amount={window.user.balance_micro_eur}/></div>
{/if}
<div>Storage used</div>
<div>{formatDataVolume(window.user.filesystem_storage_used, 3)}</div>
<div>Transfer used</div>
<div>{formatDataVolume(window.user.monthly_transfer_used, 3)}</div>
</div>
<Button link_href="/d/me" icon="folder" label="My Filesystem"/>
<Button link_href="/user" icon="person" label="Profile"/>
<Button link_href="/user/settings" icon="settings" label="Settings"/>
<Button link_href="/user/subscription" icon="shopping_cart" label="Subscription"/>
<Button link_href="/user/prepaid/transactions" icon="receipt" label="Transactions"/>
{:else}
<Button link_href="/" icon="home" label="Home"/>
<Button link_href="/#pro" icon="star" label="Get Premium"/>
<Button link_href="/login" icon="person" label="Log in"/>
<Button link_href="/register" icon="person" label="Register"/>
{/if}
</div>
</dialog>
<style>
.wrapper {
flex-grow: 0;
flex-shrink: 0;
display: inline;
align-self: center;
}
.button {
flex: 0 0 content;
background: none;
margin: 0;
color: var(--body_text_color);
box-shadow: none;
}
dialog {
background-color: var(--card_color);
color: var(--body_text_color);
border-radius: 8px;
border: none;
padding: 4px;
margin: 0;
box-shadow: 2px 2px 10px var(--shadow_color);
}
.menu {
display: flex;
flex-direction: column;
}
.stats_table {
display: grid;
grid-template-columns: auto auto;
gap: 0.2em 1em;
margin: 3px;
}
</style>

View File

@@ -350,6 +350,13 @@ onMount(() => {
on:loading
/>
{/if}
{#if state.base.path === "/me"}
<div class="highlight_shaded" style="background-color: rgba(255, 255, 0, 0.05); border-radius: 0;">
The filesystem is experimental!
<a href="/filesystem">Please read the guide</a>
</div>
{/if}
</div>
<slot></slot>

View File

@@ -10,7 +10,7 @@ export let icon_small = false;
export let label = ""
export let title = ""
export let link_href = ""
export let link_target = ""
export let link_target = "_self"
export let click = e => {}
export let style = ""
export let type = ""
@@ -31,7 +31,7 @@ let click_int = e => {
}
</script>
{#if link_target === ""}
{#if link_href === ""}
<button
on:click={click_int}
class="button"

View File

@@ -29,21 +29,28 @@ onMount(() => {
{#if patreon_result !== ""}
{#if patreon_result === "error"}
<div class="highlight_red">
An error occurred while linking Patreon subscription. Please try
again later.
{#if patreon_error === "patreon_authentication_denied"}
<div class="highlight_yellow">
Please press "Allow" when asked if pixeldrain can access your
profile.
</div>
{:else if patreon_result === "error"}
<div class="highlight_red">
<p>
An error occurred while linking Patreon subscription. Please try
again later.
</p>
<p>
If it has been more than 30 minutes, your payment is complete and
the upgrade still fails please contact me on Patreon or through
e-mail at support@pixeldrain.com.
<p/>
<p>
When contacting support please provide the following information:<br/>
Server response: {patreon_message}<br/>
Server error code: {patreon_error}
</p>
</div>
<p>
If it has been more than 30 minutes, your payment is complete and
the upgrade still fails please contact me on Patreon or through
e-mail at support@pixeldrain.com.
<p/>
<p>
When contacting support please provide the following information:<br/>
Server response: {patreon_message}<br/>
Server error code: {patreon_error}
</p>
{:else if patreon_result === "pledge_not_found"}
<div class="highlight_yellow">
<p>

View File

@@ -128,9 +128,10 @@ onMount(() => {
</p>
<ul>
<li>€4 per month</li>
<li>2 TB storage limit (higher plans available)</li>
<li>No storage limit for file sharing</li>
<li>4 TB transfer limit (higher plans available)</li>
<li>Access to the <a href="/filesystem">filesystem</a></li>
<li>2 TB filesytem storage limit (higher plans available)</li>
<li>File expire after 240 days for Pro, and never on the other plans</li>
</ul>
</div>