Add configurable theme colours to filesystem

This commit is contained in:
2024-09-05 14:58:26 +02:00
parent 41a157ae9e
commit 04efcb6505
9 changed files with 81 additions and 18 deletions

View File

@@ -20,7 +20,6 @@
<link rel="apple-touch-icon" sizes="152x152" href="/res/img/pixeldrain_152.png" /> <link rel="apple-touch-icon" sizes="152x152" href="/res/img/pixeldrain_152.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/res/img/pixeldrain_180.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/res/img/pixeldrain_180.png" />
<link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" /> <link rel="shortcut icon" sizes="196x196" href="/res/img/pixeldrain_196.png" />
<meta name="theme-color" content="#220735"/>
{{ template "opengraph" .OGData }} {{ template "opengraph" .OGData }}
<script> <script>

View File

@@ -50,8 +50,6 @@ $: {
background: var(--highlight_background); background: var(--highlight_background);
height: 100%; height: 100%;
width: 0; width: 0;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
transition: width 5s linear; transition: width 5s linear;
/* Welcome to Hacktown! What's happening here is that the text in the /* Welcome to Hacktown! What's happening here is that the text in the

View File

@@ -149,6 +149,11 @@ export class FSNavigator {
cached_siblings: Array<FSNode> | null = null cached_siblings: Array<FSNode> | null = null
async get_siblings() { async get_siblings() {
// If this node is a filesystem root then there are no siblings
if (this.path.length < 2) {
return []
}
// Check if we already have siblings cached // Check if we already have siblings cached
if ( if (
this.cached_siblings === null || this.cached_siblings === null ||

View File

@@ -27,7 +27,7 @@ export const copy_link = () => {
setTimeout(() => {link_copied = false}, 60000) setTimeout(() => {link_copied = false}, 60000)
} }
let share = async () => { let share = async () => {
if (share_url === "") { if (share_url === "" || navigator.share === undefined) {
edit_window.edit(nav.base, true, "share") edit_window.edit(nav.base, true, "share")
return return
} }
@@ -114,7 +114,8 @@ let expand = e => {
</button> </button>
{/if} {/if}
{#if $nav.base.id !== "me"} <!-- Share button is enabled when: The browser has a sharing API, or the user can edit the file (to enable sharing)-->
{#if $nav.base.id !== "me" && (navigator.share !== undefined || $nav.permissions.update === true)}
<button on:click={share}> <button on:click={share}>
<i class="icon">share</i> <i class="icon">share</i>
<span>Share</span> <span>Share</span>

View File

@@ -3,7 +3,7 @@ import { createEventDispatcher } from "svelte";
import FilePicker from "../filemanager/FilePicker.svelte"; import FilePicker from "../filemanager/FilePicker.svelte";
import { fs_update, fs_node_type } from "../FilesystemAPI"; import { fs_update, fs_node_type } from "../FilesystemAPI";
import CustomBanner from "../viewers/CustomBanner.svelte"; import CustomBanner from "../viewers/CustomBanner.svelte";
import HelpButton from "../../layout/HelpButton.svelte";
let dispatch = createEventDispatcher() let dispatch = createEventDispatcher()
export let file = { export let file = {
@@ -52,6 +52,9 @@ const handle_picker = async e => {
if (fs_node_type(f) !== "image") { if (fs_node_type(f) !== "image") {
alert("Please select an image file") alert("Please select an image file")
return return
} else if (f.file_size > 5e6) {
alert("Please pick a file smaller than 5 MB. You can use WebP to achieve a better compression rate")
return
} }
// If this image is not public, it will be made public // If this image is not public, it will be made public
@@ -70,6 +73,8 @@ const handle_picker = async e => {
file.properties.brand_background_image = file_id file.properties.brand_background_image = file_id
} }
} }
let highlight_info = false
</script> </script>
<p> <p>
@@ -86,13 +91,24 @@ const handle_picker = async e => {
<hr/> <hr/>
<div class="grid" class:disabled={!enabled}> <div class="grid" class:disabled={!enabled}>
<div>Button</div> <div>
<input type="color" bind:value={file.properties.brand_input_color}/> <div style="display: inline-block">Highlight</div>
<input type="text" bind:value={file.properties.brand_input_color}/> <HelpButton bind:toggle={highlight_info}/>
<div>Highlighted button</div> </div>
<input type="color" bind:value={file.properties.brand_highlight_color}/> <input type="color" bind:value={file.properties.brand_highlight_color}/>
<input type="text" bind:value={file.properties.brand_highlight_color}/> <input type="text" bind:value={file.properties.brand_highlight_color}/>
<div>Danger button</div> {#if highlight_info}
<p class="span3">
The highlight colour is used for highlighting selected buttons and
other elements. It's also used as the page's theme colour, this
affects things like the embed colour in Discord and the colour of
the address bar in some web browsers.
</p>
{/if}
<div>Button and input</div>
<input type="color" bind:value={file.properties.brand_input_color}/>
<input type="text" bind:value={file.properties.brand_input_color}/>
<div>Delete button</div>
<input type="color" bind:value={file.properties.brand_danger_color}/> <input type="color" bind:value={file.properties.brand_danger_color}/>
<input type="text" bind:value={file.properties.brand_danger_color}/> <input type="text" bind:value={file.properties.brand_danger_color}/>
<div>Background</div> <div>Background</div>

View File

@@ -125,7 +125,7 @@ const save = async (keep_editing = false) => {
} }
</script> </script>
<Modal bind:visible={visible} title="Edit {file.name}" width="700px" form="edit_form" style="color: var(--body_text_color); {custom_css}"> <Modal bind:visible={visible} title="Edit {file.name}" width="800px" 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>

View File

@@ -0,0 +1,20 @@
<script>
export let toggle = false;
</script>
<button class="button small_button round"
class:button_highlight={toggle}
style="margin: 0;"
on:click={() => toggle = !toggle}
>
<i class="icon">help</i>
</button>
<style>
.button {
flex: 0 0 content;
background: none;
color: var(--body_text_color);
box-shadow: none;
}
</style>

View File

@@ -12,6 +12,8 @@ import (
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
) )
const defaultThemeColour = "#220735"
func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request, p httprouter.Params) { func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
var err error var err error
var td = wc.newTemplateData(w, r) var td = wc.newTemplateData(w, r)
@@ -51,15 +53,35 @@ func (wc *WebController) serveDirectory(w http.ResponseWriter, r *http.Request,
} }
} }
func urlEncodePath(path string) string {
var split = strings.Split(path, "/")
for i := range split {
split[i] = url.PathEscape(split[i])
}
return strings.Join(split, "/")
}
func findThemeColour(f pixelapi.FilesystemPath) string {
// We walk the patch backward because lower entries can override the
// properties of higher entries
for i := len(f.Path) - 1; i >= 0; i-- {
if f.Path[i].Properties["branding_enabled"] != "true" &&
f.Path[i].Properties["brand_highlight_color"] != "" {
return f.Path[i].Properties["brand_highlight_color"]
}
}
return defaultThemeColour
}
func (wc *WebController) metadataFromFilesystem(f pixelapi.FilesystemPath) (og ogData) { func (wc *WebController) metadataFromFilesystem(f pixelapi.FilesystemPath) (og ogData) {
var ( var (
base = f.Path[f.BaseIndex] base = f.Path[f.BaseIndex]
name = base.Name name = base.Name
filetype = base.Type filetype = base.FileType
filepath = url.PathEscape(f.Path[0].ID + base.Path) filepath = urlEncodePath(base.Path)
pageurl = wc.config.WebsiteAddress + "/d/" + filepath pageurl = wc.config.WebsiteAddress + "/d" + filepath
fileurl = wc.config.WebsiteAddress + "/api/filesystem/" + filepath fileurl = wc.config.WebsiteAddress + "/api/filesystem" + filepath
thumbnailurl = wc.config.WebsiteAddress + "/api/filesystem/" + filepath + "?thumbnail" thumbnailurl = wc.config.WebsiteAddress + "/api/filesystem" + filepath + "?thumbnail"
) )
og.addProp("og:title", name) og.addProp("og:title", name)
@@ -72,6 +94,7 @@ func (wc *WebController) metadataFromFilesystem(f pixelapi.FilesystemPath) (og o
og.addName("twitter:title", name) og.addName("twitter:title", name)
og.addName("twitter:site", "@Fornax96") og.addName("twitter:site", "@Fornax96")
og.addName("twitter:domain", "pixeldrain.com") og.addName("twitter:domain", "pixeldrain.com")
og.addName("theme-color", findThemeColour(f))
if strings.HasPrefix(filetype, "image") { if strings.HasPrefix(filetype, "image") {
og.addProp("og:type", "article") og.addProp("og:type", "article")

View File

@@ -36,7 +36,8 @@ func (wc *WebController) serveShareXConfig(w http.ResponseWriter, r *http.Reques
"Body": "MultipartFormData", "Body": "MultipartFormData",
"FileFormName": "file", "FileFormName": "file",
"URL": "https://pixeldrain.com/u/$json:id$", "URL": "https://pixeldrain.com/u/$json:id$",
"ThumbnailURL": "https://pixeldrain.com/api/file/$json:id$/thumbnail" "ThumbnailURL": "https://pixeldrain.com/api/file/$json:id$/thumbnail",
"DeletionURL": "https://pixeldrain.com/u/$json:id$"
} }
`, `,
base64.StdEncoding.EncodeToString([]byte( base64.StdEncoding.EncodeToString([]byte(