Add header image to branding options

This commit is contained in:
2024-02-16 14:50:34 +01:00
parent b4f6bbb4c8
commit a4c5b97cdf
21 changed files with 298 additions and 154 deletions

View File

@@ -4,9 +4,10 @@ import { formatDataVolume, formatDate, formatThousands } from "../util/Formattin
import Modal from "../util/Modal.svelte"; import Modal from "../util/Modal.svelte";
import { fs_timeseries } from "./FilesystemAPI"; import { fs_timeseries } from "./FilesystemAPI";
import { fs_path_url } from "./FilesystemUtil"; import { fs_path_url } from "./FilesystemUtil";
import { generate_share_url } from "./Sharebar.svelte"; import { generate_share_path, generate_share_url } from "./Sharebar.svelte";
import { color_by_name } from "../util/Util.svelte"; import { color_by_name, copy_text } from "../util/Util.svelte";
import { tick } from "svelte"; import { tick } from "svelte";
import Button from "../layout/Button.svelte";
export let state export let state
export let visible = false export let visible = false
@@ -21,6 +22,7 @@ const visibility_change = visible => {
$: direct_url = window.location.origin+fs_path_url(state.base.path) $: direct_url = window.location.origin+fs_path_url(state.base.path)
$: share_url = generate_share_url(state.path) $: share_url = generate_share_url(state.path)
$: direct_share_url = window.location.origin+fs_path_url(generate_share_path(state.path))
let chart let chart
let chart_timespan = 0 let chart_timespan = 0
@@ -171,9 +173,28 @@ let update_chart = async (base, timespan, interval) => {
</tr> </tr>
<tr><td>SHA256 sum</td><td>{state.base.sha256_sum}</td></tr> <tr><td>SHA256 sum</td><td>{state.base.sha256_sum}</td></tr>
{/if} {/if}
<tr><td>Direct URL</td><td><a href="{direct_url}">{direct_url}</a></td></tr> <tr>
<td>Direct link</td>
<td>
<Button highlight_on_click icon="content_copy" label="Copy" click={e => copy_text(direct_url)}/>
<a href="{direct_url}">{direct_url}</a>
</td>
</tr>
{#if share_url !== ""} {#if share_url !== ""}
<tr><td>Share URL</td><td><a href="{share_url}">{share_url}</a></td></tr> <tr>
<td>Sharing link</td>
<td>
<Button highlight_on_click icon="content_copy" label="Copy" click={e => copy_text(share_url)}/>
<a href="{share_url}">{share_url}</a>
</td>
</tr>
<tr>
<td>Direct sharing link</td>
<td>
<Button highlight_on_click icon="content_copy" label="Copy" click={e => copy_text(direct_share_url)}/>
<a href="{direct_share_url}">{direct_share_url}</a>
</td>
</tr>
{/if} {/if}
</table> </table>

View File

@@ -1,7 +1,7 @@
<script> <script>
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import LoadingIndicator from '../util/LoadingIndicator.svelte'; import LoadingIndicator from '../util/LoadingIndicator.svelte';
import EditWindow from './EditWindow.svelte'; import EditWindow from './edit_window/EditWindow.svelte';
import Toolbar from './Toolbar.svelte'; import Toolbar from './Toolbar.svelte';
import Breadcrumbs from './Breadcrumbs.svelte'; import Breadcrumbs from './Breadcrumbs.svelte';
import DetailsWindow from './DetailsWindow.svelte'; import DetailsWindow from './DetailsWindow.svelte';
@@ -10,8 +10,8 @@ import FilePreview from './viewers/FilePreview.svelte';
import SearchView from './SearchView.svelte'; import SearchView from './SearchView.svelte';
import UploadWidget from './upload_widget/UploadWidget.svelte'; import UploadWidget from './upload_widget/UploadWidget.svelte';
import HomeButton from '../file_viewer/HomeButton.svelte'; import HomeButton from '../file_viewer/HomeButton.svelte';
import { fs_path_url } from './FilesystemUtil'; import { fs_path_url } from './FilesystemUtil.js';
import { branding_from_node, branding_from_path } from './BrandingOptions.svelte'; import { branding_from_path } from './edit_window/Branding.js'
let loading = true let loading = true
let toolbar let toolbar
@@ -179,7 +179,6 @@ const update_css = path => document.documentElement.style = branding_from_path(p
bind:visible={edit_visible} bind:visible={edit_visible}
fs_navigator={fs_navigator} fs_navigator={fs_navigator}
on:loading={loading_evt} on:loading={loading_evt}
on:style_change={e => document.documentElement.style = branding_from_node(e.detail)}
/> />
<UploadWidget <UploadWidget

View File

@@ -13,6 +13,9 @@ export const fs_encode_path = path => {
} }
export const fs_path_url = path => { export const fs_path_url = path => {
if (path[0] !== "/") {
path = "/" + path
}
return window.api_endpoint + "/filesystem" + fs_encode_path(path) return window.api_endpoint + "/filesystem" + fs_encode_path(path)
} }

View File

@@ -1,5 +1,12 @@
<script context="module"> <script context="module">
export const generate_share_url = path => { export const generate_share_url = path => {
let share_path = generate_share_path(path)
if (share_path !== "") {
share_path = window.location.protocol+"//"+window.location.host+"/d/"+share_path
}
return share_path
}
export const generate_share_path = path => {
let share_url = "" let share_url = ""
let bucket_idx = -1 let bucket_idx = -1
@@ -11,9 +18,7 @@ export const generate_share_url = path => {
} }
} }
if (bucket_idx !== -1) { if (bucket_idx !== -1) {
share_url = window.location.protocol+"//"+ share_url = path[bucket_idx].id
window.location.host+"/d/"+
path[bucket_idx].id
// Construct the path starting from the bucket // Construct the path starting from the bucket
for (let i = bucket_idx+1; i < path.length; i++) { for (let i = bucket_idx+1; i < path.length; i++) {

View File

@@ -106,10 +106,12 @@ let expand = e => {
</button> </button>
{/if} {/if}
<button on:click={share}> {#if state.base.id !== "me"}
<i class="icon">share</i> <button on:click={share}>
<span>Share</span> <i class="icon">share</i>
</button> <span>Share</span>
</button>
{/if}
<button on:click={() => details_visible = !details_visible} class:button_highlight={details_visible}> <button on:click={() => details_visible = !details_visible} class:button_highlight={details_visible}>
<i class="icon">help</i> <i class="icon">help</i>

View File

@@ -0,0 +1,101 @@
import parse from "pure-color/parse"
import rgb2hsl from "pure-color/convert/rgb2hsl";
import hsl2rgb from "pure-color/convert/hsl2rgb";
import rgb2hex from "pure-color/convert/rgb2hex";
// Generate a branding style from a file's properties map
export const branding_from_path = path => {
let style = {}
for (let node of path) {
add_styles(style, node.properties)
}
last_generated_style = style
return gen_css(style)
}
// The last style which was generated is cached, when we don't have a complete
// path to generate the style with we will use the cached style as a basis
let last_generated_style = {}
export const branding_from_node = node => {
add_styles(last_generated_style, node.properties)
return gen_css(last_generated_style)
}
const gen_css = style => {
return Object.entries(style).map(([key, value]) => `--${key}:${value}`).join(';');
}
// add_styles adds the styles configured in the properties struct to the
// existing style which is passed as the first argument. When navigating to a
// path this function is executed on every member of the path so all the styles
// get combined
const add_styles = (style, properties) => {
if (!properties || !properties.branding_enabled || properties.branding_enabled !== "true") {
return
}
if (properties.brand_input_color) {
style.input_background = properties.brand_input_color
style.input_hover_background = properties.brand_input_color
style.input_text = add_light(properties.brand_input_color, 70)
}
if (properties.brand_highlight_color) {
style.highlight_color = properties.brand_highlight_color
style.highlight_background = properties.brand_highlight_color
style.highlight_text_color = add_light(properties.brand_highlight_color, 70)
style.link_color = properties.brand_highlight_color
}
if (properties.brand_danger_color) {
style.danger_color = properties.brand_danger_color
style.danger_text_color = add_light(properties.brand_danger_color, 70)
}
if (properties.brand_background_color) {
style.background_color = properties.brand_background_color
style.background = properties.brand_background_color
style.background_text_color = add_light(properties.brand_background_color, 70)
style.background_pattern_color = properties.brand_background_color
}
if (properties.brand_body_color) {
style.body_color = properties.brand_body_color
style.body_background = properties.brand_body_color
style.body_text_color = add_light(properties.brand_body_color, 70)
style.shaded_background = set_alpha(properties.brand_body_color, 0.8)
style.separator = add_light(properties.brand_body_color, 5)
style.shadow_color = darken(properties.brand_body_color, 0.8)
}
if (properties.brand_card_color) {
style.card_color = properties.brand_card_color
}
if (properties.brand_background_image) {
style.background_image = "url('/api/filesystem/" + properties.brand_background_image + "')"
style.background_image_size = "cover"
style.background_image_position = "center"
style.background_image_repeat = "no-repeat"
}
}
const add_light = (color, amt) => {
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
// If the lightness is less than 40 it is considered a dark colour. This
// threshold is 40 instead of 50 because overall dark text is more legible
if (hsl[2] < 40) {
hsl[2] = hsl[2] + amt // Dark color, add lightness
} else {
hsl[2] = hsl[2] - amt // Light color, remove lightness
}
return rgb2hex(hsl2rgb(hsl)) // Convert back to hex
}
// Darken and desaturate. Only used for shadows
const darken = (color, percent) => {
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
hsl[1] = hsl[1] * percent
hsl[2] = hsl[2] * percent
return rgb2hex(hsl2rgb(hsl)) // Convert back to hex
}
const set_alpha = (color, amt) => {
let rgb = parse(color)
rgb.push(amt)
return "rgba(" + rgb.join(", ") + ")"
}

View File

@@ -1,124 +1,21 @@
<script context="module">
import parse from "pure-color/parse"
import rgb2hsl from "pure-color/convert/rgb2hsl";
import hsl2rgb from "pure-color/convert/hsl2rgb";
import rgb2hex from "pure-color/convert/rgb2hex";
// Generate a branding style from a file's properties map
export const branding_from_path = path => {
let style = {}
for (let node of path) {
add_styles(style, node.properties)
}
last_generated_style = style
return gen_css(style)
}
// The last style which was generated is cached, when we don't have a complete
// path to generate the style with we will use the cached style as a basis
let last_generated_style = {}
export const branding_from_node = node => {
add_styles(last_generated_style, node.properties)
return gen_css(last_generated_style)
}
const gen_css = style => {
return Object.entries(style).map(([key, value]) => `--${key}:${value}`).join(';');
}
// add_styles adds the styles configured in the properties struct to the
// existing style which is passed as the first argument. When navigating to a
// path this function is executed on every member of the path so all the styles
// get combined
const add_styles = (style, properties) => {
if (!properties || !properties.branding_enabled || properties.branding_enabled !== "true") {
return
}
if (properties.brand_input_color) {
style.input_background = properties.brand_input_color
style.input_hover_background = properties.brand_input_color
style.input_text = add_light(properties.brand_input_color, 70)
}
if (properties.brand_highlight_color) {
style.highlight_color = properties.brand_highlight_color
style.highlight_background = properties.brand_highlight_color
style.highlight_text_color = add_light(properties.brand_highlight_color, 70)
style.link_color = properties.brand_highlight_color
}
if (properties.brand_danger_color) {
style.danger_color = properties.brand_danger_color
style.danger_text_color = add_light(properties.brand_danger_color, 70)
}
if (properties.brand_background_color) {
style.background_color = properties.brand_background_color
style.background = properties.brand_background_color
style.background_text_color = add_light(properties.brand_background_color, 70)
style.background_pattern_color = properties.brand_background_color
}
if (properties.brand_body_color) {
style.body_color = properties.brand_body_color
style.body_background = properties.brand_body_color
style.body_text_color = add_light(properties.brand_body_color, 70)
style.shaded_background = set_alpha(properties.brand_body_color, 0.8)
style.separator = add_light(properties.brand_body_color, 5)
style.shadow_color = darken(properties.brand_body_color, 0.8)
}
if (properties.brand_card_color) {
style.card_color = properties.brand_card_color
}
if (properties.brand_background_image) {
style.background_image = "url('/api/filesystem/"+properties.brand_background_image+"')"
style.background_image_size = "cover"
style.background_image_position = "center"
style.background_image_repeat = "no-repeat"
}
}
const add_light = (color, amt) => {
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
// If the lightness is less than 30 it is considered a dark colour. This
// threshold is 30 instead of 50 because overall dark text is more legible
if (hsl[2] < 30) {
hsl[2] = hsl[2]+amt // Dark color, add lightness
} else {
hsl[2] = hsl[2]-amt // Light color, remove lightness
}
return rgb2hex(hsl2rgb(hsl)) // Convert back to hex
}
// Darken and desaturate. Only used for shadows
const darken = (color, percent) => {
let hsl = rgb2hsl(parse(color)) // Convert hex to hsl
hsl[1] = hsl[1]*percent
hsl[2] = hsl[2]*percent
return rgb2hex(hsl2rgb(hsl)) // Convert back to hex
}
const set_alpha = (color, amt) => {
let rgb = parse(color)
rgb.push(amt)
return "rgba("+rgb.join(", ")+")"
}
</script>
<script> <script>
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import FilePicker from "./filemanager/FilePicker.svelte"; import FilePicker from "../filemanager/FilePicker.svelte";
import { fs_update } from "./FilesystemAPI"; import { fs_update } from "../FilesystemAPI";
import { fs_node_type } from "./FilesystemUtil"; import { fs_node_type } from "../FilesystemUtil";
import CustomBanner from "../viewers/CustomBanner.svelte";
let dispatch = createEventDispatcher() let dispatch = createEventDispatcher()
export let file = { export let file = {
properties: { properties: {
branding_enabled: "false", branding_enabled: "",
brand_input_color: "#2d2d2d", brand_input_color: "",
brand_highlight_color: "#75b72d", brand_highlight_color: "",
brand_danger_color: "#bd5f69", brand_danger_color: "",
brand_background_color: "#141414", brand_background_color: "",
brand_body_color: "#1e1e1e", brand_body_color: "",
brand_card_color: "#282828", brand_card_color: "",
brand_header_image: "", brand_header_image: "",
brand_header_link: "", brand_header_link: "",
brand_footer_image: "", brand_footer_image: "",
@@ -133,7 +30,7 @@ $: update_colors(file)
const update_colors = file => { const update_colors = file => {
if (enabled) { if (enabled) {
file.properties.branding_enabled = "true" file.properties.branding_enabled = "true"
dispatch("style_change", file) dispatch("style_change")
} else { } else {
file.properties.branding_enabled = "" file.properties.branding_enabled = ""
} }
@@ -208,15 +105,13 @@ const handle_picker = async e => {
<div>Card</div> <div>Card</div>
<input type="color" bind:value={file.properties.brand_card_color}/> <input type="color" bind:value={file.properties.brand_card_color}/>
<input type="text" bind:value={file.properties.brand_card_color}/> <input type="text" bind:value={file.properties.brand_card_color}/>
<div class="span3"> <p class="span3">
<hr/>
You can choose an image to show above or behind the files in this You can choose an image to show above or behind the files in this
directory. The image will be picked from your filesystem. The image will directory. The image will be picked from your filesystem. The image will
get a shared file link. You can move and rename the file like normal, get a shared file link. You can move and rename the file like normal,
but if you remove the shared file property your branding will stop but if you remove the shared file property your branding will stop
working. working. Recommended dimensions for the header image are 1000x90 px.
</div> </p>
<div>Header image ID</div> <div>Header image ID</div>
<button on:click={() => pick_image("brand_header_image")}> <button on:click={() => pick_image("brand_header_image")}>
<i class="icon">folder_open</i> <i class="icon">folder_open</i>
@@ -243,7 +138,9 @@ const handle_picker = async e => {
<div class="example example_body"> <div class="example example_body">
<div>The content body. <a href="/">A link</a>!</div> <div>The content body. <a href="/">A link</a>!</div>
<hr/>
<div>Below is your custom header image, if you chose one.</div>
<CustomBanner path={[file]}/>
<hr/> <hr/>
<div class="example_button_row"> <div class="example_button_row">

View File

@@ -1,10 +1,11 @@
<script> <script>
import { fs_delete_all, fs_rename, fs_update } from "./FilesystemAPI"; import { fs_delete_all, fs_rename, fs_update } from "../FilesystemAPI";
import Modal from "../util/Modal.svelte"; import Modal from "../../util/Modal.svelte";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import Button from "../layout/Button.svelte"; import Button from "../../layout/Button.svelte";
import BrandingOptions from "./BrandingOptions.svelte"; import BrandingOptions from "./BrandingOptions.svelte";
import PathLink from "./util/PathLink.svelte"; import PathLink from "../util/PathLink.svelte";
import { branding_from_node } from "./Branding";
let dispatch = createEventDispatcher() let dispatch = createEventDispatcher()
@@ -17,6 +18,7 @@ let file = {
properties: {}, properties: {},
}; };
let custom_css = ""
$: is_root_dir = file.path === "/"+file.id $: is_root_dir = file.path === "/"+file.id
export let visible export let visible
@@ -33,7 +35,14 @@ export const edit = (f, oae = false, t = "file") => {
if (file.properties === undefined) { if (file.properties === undefined) {
file.properties = {} file.properties = {}
} }
branding_enabled = file.properties.branding_enabled === "true" branding_enabled = file.properties.branding_enabled === "true"
if (branding_enabled) {
custom_css = branding_from_node(file)
} else {
custom_css = ""
}
visible = true visible = true
} }
@@ -127,7 +136,7 @@ const delete_file = async e => {
} }
</script> </script>
<Modal bind:visible={visible} title="Edit {file.name}" width="700px" form="edit_form"> <Modal bind:visible={visible} title="Edit {file.name}" width="700px" form="edit_form" style="color: var(--body_text_color); {custom_css}">
<div class="tab_bar"> <div class="tab_bar">
<button class:button_highlight={tab === "file"} on:click={() => tab = "file"}> <button class:button_highlight={tab === "file"} on:click={() => tab = "file"}>
<i class="icon">edit</i> <i class="icon">edit</i>
@@ -184,7 +193,12 @@ const delete_file = async e => {
</div> </div>
{:else if tab === "branding"} {:else if tab === "branding"}
<div class="tab_content"> <div class="tab_content">
<BrandingOptions bind:enabled={branding_enabled} bind:colors={branding_colors} file={file} on:style_change/> <BrandingOptions
bind:enabled={branding_enabled}
bind:colors={branding_colors}
file={file}
on:style_change={e => custom_css = branding_from_node(file)}
/>
</div> </div>
{/if} {/if}
</Modal> </Modal>

View File

@@ -71,9 +71,9 @@ const node_select = e => {
state.children[index].fm_selected = !state.children[index].fm_selected state.children[index].fm_selected = !state.children[index].fm_selected
} }
const node_settings = e => { const node_settings = e => edit_window.edit(state.children[e.detail], false)
edit_window.edit(state.children[e.detail], false) const node_branding = e => edit_window.edit(state.children[e.detail], false, "branding")
}
const navigate_up = () => { const navigate_up = () => {
creating_dir = false creating_dir = false
@@ -352,6 +352,8 @@ onMount(() => {
{/if} {/if}
</div> </div>
<slot></slot>
{#if directory_view === "list"} {#if directory_view === "list"}
<ListView <ListView
state={state} state={state}
@@ -361,6 +363,7 @@ onMount(() => {
on:node_context={node_context} on:node_context={node_context}
on:node_share_click={node_share_click} on:node_share_click={node_share_click}
on:node_settings={node_settings} on:node_settings={node_settings}
on:node_branding={node_branding}
on:node_select={node_select} on:node_select={node_select}
/> />
{:else if directory_view === "gallery"} {:else if directory_view === "gallery"}

View File

@@ -5,6 +5,7 @@ import GalleryView from './GalleryView.svelte'
import Modal from '../../util/Modal.svelte'; import Modal from '../../util/Modal.svelte';
import Navigator from '../Navigator.svelte'; import Navigator from '../Navigator.svelte';
import LoadingIndicator from '../../util/LoadingIndicator.svelte'; import LoadingIndicator from '../../util/LoadingIndicator.svelte';
import Breadcrumbs from '../Breadcrumbs.svelte'
let fs_navigator let fs_navigator
let state let state
@@ -172,6 +173,9 @@ onMount(() => {
<i class="icon">done</i> Pick <i class="icon">done</i> Pick
</button> </button>
</div> </div>
<Breadcrumbs state={state} fs_navigator={fs_navigator}/>
{#if directory_view === "list"} {#if directory_view === "list"}
<ListView <ListView
state={state} state={state}

View File

@@ -47,8 +47,13 @@ export let large_icons = false
<i class="icon" title="This file / directory is shared. Click to open public link">share</i> <i class="icon" title="This file / directory is shared. Click to open public link">share</i>
</a> </a>
{/if} {/if}
{#if child.properties && child.properties.branding_enabled}
<button class="action_button" on:click|preventDefault|stopPropagation={() => dispatch("node_branding", index)}>
<i class="icon">palette</i>
</button>
{/if}
{#if state.permissions.update} {#if state.permissions.update}
<button class="action_button" on:click|preventDefault|stopPropagation={() => {dispatch("node_settings", index)}}> <button class="action_button" on:click|preventDefault|stopPropagation={() => dispatch("node_settings", index)}>
<i class="icon">edit</i> <i class="icon">edit</i>
</button> </button>
{/if} {/if}

View File

@@ -1,6 +1,7 @@
<script> <script>
import { createEventDispatcher, onMount } from 'svelte' import { createEventDispatcher, onMount } from 'svelte'
import { fs_path_url } from '../FilesystemUtil'; import { fs_path_url } from '../FilesystemUtil';
import FileTitle from '../../file_viewer/viewers/FileTitle.svelte';
let dispatch = createEventDispatcher() let dispatch = createEventDispatcher()
export let state export let state
@@ -37,7 +38,9 @@ onMount(() => {
}) })
</script> </script>
<slot></slot>
<div class="container"> <div class="container">
<FileTitle title={state.base.name}/>
<button on:click={() => dispatch("open_sibling", -1) }><i class="icon">skip_previous</i></button> <button on:click={() => dispatch("open_sibling", -1) }><i class="icon">skip_previous</i></button>
<button on:click={() => player.currentTime -= 10 }><i class="icon">replay_10</i></button> <button on:click={() => player.currentTime -= 10 }><i class="icon">replay_10</i></button>
<button on:click={toggle_play}> <button on:click={toggle_play}>
@@ -65,7 +68,6 @@ onMount(() => {
<style> <style>
.container { .container {
margin: 50px 0 0 0;
padding: 0; padding: 0;
overflow-y: auto; overflow-y: auto;
text-align: center; text-align: center;

View File

@@ -0,0 +1,50 @@
<script>
export let path = []
let image_uri
let image_link
$: update_links(path)
const update_links = (path) => {
image_uri = null
image_link = null
for (let node of path) {
if (node.properties && node.properties.branding_enabled === "true") {
if (node.properties.brand_header_image) {
image_uri = "/api/filesystem/"+node.properties.brand_header_image
}
if (node.properties.brand_header_link) {
image_link = node.properties.brand_header_link
}
}
}
}
</script>
{#if image_uri}
<div class="container">
{#if image_link}
<a class="link" href={image_link} target="_blank" rel="noreferrer">
<img class="image" src="{image_uri}" alt="User-provided banner"/>
</a>
{:else}
<img class="image" src="{image_uri}" alt="User-provided banner"/>
{/if}
</div>
{/if}
<style>
.container {
margin: 6px 0;
text-align: center;
}
.link {
display: inline-block;
}
.image {
display: inline-block;
margin: auto;
max-height: 90px;
max-width: 100%;
border-radius: 6px;
}
</style>

View File

@@ -7,6 +7,8 @@ let dispatch = createEventDispatcher()
export let state export let state
</script> </script>
<slot></slot>
<h1>{state.base.name}</h1> <h1>{state.base.name}</h1>
<IconBlock icon_href={fs_thumbnail_url(state.base.path, 256, 256)}> <IconBlock icon_href={fs_thumbnail_url(state.base.path, 256, 256)}>

View File

@@ -11,6 +11,7 @@ import Text from "./Text.svelte";
import Video from "./Video.svelte"; import Video from "./Video.svelte";
import Torrent from "./Torrent.svelte"; import Torrent from "./Torrent.svelte";
import Zip from "./Zip.svelte"; import Zip from "./Zip.svelte";
import CustomBanner from "./CustomBanner.svelte";
export let fs_navigator export let fs_navigator
export let edit_window export let edit_window
@@ -51,9 +52,13 @@ const state_update = async (base) => {
edit_window={edit_window} edit_window={edit_window}
on:loading on:loading
on:upload_picker on:upload_picker
/> >
<CustomBanner path={state.path}/>
</FileManager>
{:else if viewer_type === "audio"} {:else if viewer_type === "audio"}
<Audio state={state} on:open_sibling/> <Audio state={state} on:open_sibling>
<CustomBanner path={state.path}/>
</Audio>
{:else if viewer_type === "image"} {:else if viewer_type === "image"}
<Image state={state} on:open_sibling/> <Image state={state} on:open_sibling/>
{:else if viewer_type === "video"} {:else if viewer_type === "video"}
@@ -61,13 +66,21 @@ const state_update = async (base) => {
{:else if viewer_type === "pdf"} {:else if viewer_type === "pdf"}
<Pdf state={state}/> <Pdf state={state}/>
{:else if viewer_type === "text"} {:else if viewer_type === "text"}
<Text state={state}/> <Text state={state}>
<CustomBanner path={state.path}/>
</Text>
{:else if viewer_type === "torrent"} {:else if viewer_type === "torrent"}
<Torrent state={state} bind:this={viewer} on:loading on:download/> <Torrent state={state} bind:this={viewer} on:loading on:download>
<CustomBanner path={state.path}/>
</Torrent>
{:else if viewer_type === "zip"} {:else if viewer_type === "zip"}
<Zip state={state} bind:this={viewer} on:loading on:download /> <Zip state={state} bind:this={viewer} on:loading on:download>
<CustomBanner path={state.path}/>
</Zip>
{:else} {:else}
<File state={state} on:download/> <File state={state} on:download>
<CustomBanner path={state.path}/>
</File>
{/if} {/if}
<style> <style>

View File

@@ -75,6 +75,7 @@ const mouseup = (e) => {
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
cursor: pointer; cursor: pointer;
box-shadow: 1px 1px 4px 0px var(--shadow_color);
} }
.image.zoom { .image.zoom {
max-width: none; max-width: none;

View File

@@ -27,6 +27,7 @@ export const set_file = file => {
<div class="container"> <div class="container">
<slot></slot>
<pre bind:this={text_pre}> <pre bind:this={text_pre}>
Loading... Loading...
</pre> </pre>

View File

@@ -73,6 +73,8 @@ const copy_magnet = () => {
} }
</script> </script>
<slot></slot>
<h1>{state.base.name}</h1> <h1>{state.base.name}</h1>
<IconBlock icon_href={fs_node_icon(state.base, 256, 256)}> <IconBlock icon_href={fs_node_icon(state.base, 256, 256)}>

View File

@@ -59,6 +59,8 @@ const recursive_size = (file) => {
} }
</script> </script>
<slot></slot>
<h1>{state.base.name}</h1> <h1>{state.base.name}</h1>
<IconBlock icon_href={fs_node_icon(state.base, 256, 256)}> <IconBlock icon_href={fs_node_icon(state.base, 256, 256)}>

View File

@@ -1,5 +1,6 @@
<script> <script>
export let highlight = false; export let highlight = false;
export let highlight_on_click = false
export let red = false; export let red = false;
export let round = false; export let round = false;
export let flat = false; export let flat = false;
@@ -14,11 +15,25 @@ export let click = e => {}
export let style = "" export let style = ""
export let type = "" export let type = ""
export let form = "" export let form = ""
let click_int = e => {
if (highlight_on_click) {
try {
click(e)
highlight = true
} catch (err) {
red = true
throw err
}
} else {
click(e)
}
}
</script> </script>
{#if link_target === ""} {#if link_target === ""}
<button <button
on:click={click} on:click={click_int}
class="button" class="button"
class:button_highlight={highlight} class:button_highlight={highlight}
class:button_red={red} class:button_red={red}

View File

@@ -18,6 +18,7 @@ export let width = "800px";
export let height = "auto"; export let height = "auto";
export let padding = false; export let padding = false;
export let visible = false; export let visible = false;
export let style = "";
const load_bg = background => { const load_bg = background => {
background.style.zIndex = global_index.valueOf(); background.style.zIndex = global_index.valueOf();
@@ -53,6 +54,7 @@ const keydown = e => {
<!-- svelte-ignore a11y-no-noninteractive-element-interactions --> <!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
<div <div
class="background" class="background"
style={style}
use:load_bg use:load_bg
on:click={hide} on:click={hide}
transition:fade={{duration: 200}} transition:fade={{duration: 200}}