Simplified the frontend serving part of the backend
This commit is contained in:
parent
1975a21c80
commit
d47566626a
|
@ -49,8 +49,6 @@ gulp.task("build:backend:script", () => {
|
|||
return gulp
|
||||
.src([
|
||||
"./packages/backend/src/server/web/boot.js",
|
||||
"./packages/backend/src/server/web/bios.js",
|
||||
"./packages/backend/src/server/web/cli.js",
|
||||
])
|
||||
.pipe(replace("LANGS", JSON.stringify(Object.keys(locales))))
|
||||
.pipe(
|
||||
|
@ -65,8 +63,6 @@ gulp.task("build:backend:style", () => {
|
|||
return gulp
|
||||
.src([
|
||||
"./packages/backend/src/server/web/style.css",
|
||||
"./packages/backend/src/server/web/bios.css",
|
||||
"./packages/backend/src/server/web/cli.css",
|
||||
])
|
||||
.pipe(
|
||||
cssnano({
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
window.onload = async () => {
|
||||
const account = JSON.parse(localStorage.getItem("account"));
|
||||
const i = account.token;
|
||||
|
||||
const api = (endpoint, data = {}) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// Append a credential
|
||||
if (i) data.i = i;
|
||||
|
||||
// Send request
|
||||
fetch(endpoint.indexOf("://") > -1 ? endpoint : `/api/${endpoint}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
credentials: "omit",
|
||||
cache: "no-cache",
|
||||
})
|
||||
.then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
const content = document.getElementById("content");
|
||||
|
||||
document.getElementById("ls").addEventListener("click", () => {
|
||||
content.innerHTML = "";
|
||||
|
||||
const lsEditor = document.createElement("div");
|
||||
lsEditor.id = "lsEditor";
|
||||
|
||||
const adder = document.createElement("div");
|
||||
adder.classList.add("adder");
|
||||
const addKeyInput = document.createElement("input");
|
||||
const addValueTextarea = document.createElement("textarea");
|
||||
const addButton = document.createElement("button");
|
||||
addButton.textContent = "Add";
|
||||
addButton.addEventListener("click", () => {
|
||||
localStorage.setItem(addKeyInput.value, addValueTextarea.value);
|
||||
location.reload();
|
||||
});
|
||||
|
||||
adder.appendChild(addKeyInput);
|
||||
adder.appendChild(addValueTextarea);
|
||||
adder.appendChild(addButton);
|
||||
lsEditor.appendChild(adder);
|
||||
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const k = localStorage.key(i);
|
||||
const record = document.createElement("div");
|
||||
record.classList.add("record");
|
||||
const header = document.createElement("header");
|
||||
header.textContent = k;
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.textContent = localStorage.getItem(k);
|
||||
const saveButton = document.createElement("button");
|
||||
saveButton.textContent = "Save";
|
||||
saveButton.addEventListener("click", () => {
|
||||
localStorage.setItem(k, textarea.value);
|
||||
location.reload();
|
||||
});
|
||||
const removeButton = document.createElement("button");
|
||||
removeButton.textContent = "Remove";
|
||||
removeButton.addEventListener("click", () => {
|
||||
localStorage.removeItem(k);
|
||||
location.reload();
|
||||
});
|
||||
record.appendChild(header);
|
||||
record.appendChild(textarea);
|
||||
record.appendChild(saveButton);
|
||||
record.appendChild(removeButton);
|
||||
lsEditor.appendChild(record);
|
||||
}
|
||||
|
||||
content.appendChild(lsEditor);
|
||||
});
|
||||
};
|
|
@ -144,25 +144,13 @@
|
|||
</button>
|
||||
<p class="dont-worry">Don't worry, it's (probably) not your fault.</p>
|
||||
<p>Please make sure your browser is up-to-date and any AdBlockers are off.</p>
|
||||
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try the following options:</p>
|
||||
<p>If the problem persists after refreshing, please contact your instance's administrator.<br>You may also try:</p>
|
||||
<a href="/flush">
|
||||
<button class="button-small">
|
||||
<span class="button-label-small">Clear preferences and cache</span>
|
||||
</button>
|
||||
</a>
|
||||
<br>
|
||||
<a href="/cli">
|
||||
<button class="button-small">
|
||||
<span class="button-label-small">Start the simple client</span>
|
||||
</button>
|
||||
</a>
|
||||
<br>
|
||||
<a href="/bios">
|
||||
<button class="button-small">
|
||||
<span class="button-label-small">Start the repair tool</span>
|
||||
</button>
|
||||
</a>
|
||||
<br>
|
||||
<div id="errors"></div>
|
||||
`;
|
||||
errorsElement = document.getElementById("errors");
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
html {
|
||||
background: #191724;
|
||||
}
|
||||
main {
|
||||
background: #1f1d2e;
|
||||
border-radius: 10px;
|
||||
}
|
||||
#tl > div {
|
||||
border: 1px solid #908caa;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
width: fit-content;
|
||||
}
|
||||
#tl > div > header {
|
||||
font-weight: 700;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#form {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#calckey_app {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
font-family: BIZ UDGothic, Roboto, HelveticaNeue, Arial, sans-serif;
|
||||
background-color: #191724;
|
||||
color: #e0def4;
|
||||
justify-content: center;
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
button {
|
||||
border-radius:999px;
|
||||
padding:0 40px;
|
||||
margin-top: 1rem;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
margin-bottom:12px;
|
||||
background:linear-gradient(90deg,#9ccfd8,#31748f);
|
||||
line-height:50px;
|
||||
color:#191724;
|
||||
font-weight:700;
|
||||
font-size:20px;
|
||||
}
|
||||
button:hover {
|
||||
background: rgb(156, 207, 216);
|
||||
}
|
||||
a {
|
||||
color: rgb(156, 207, 216);
|
||||
text-decoration: none;
|
||||
}
|
||||
p,
|
||||
li {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
}
|
||||
code {
|
||||
font-family: Fira, FiraCode, monospace;
|
||||
}
|
||||
#text {
|
||||
background-color: #444;
|
||||
border: solid #aaa;
|
||||
border-radius: 10px;
|
||||
color: #e0def4;
|
||||
margin-top: 3rem;
|
||||
width: 20rem;
|
||||
height: 5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
#text:focus {
|
||||
border: solid #eee;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
#text {
|
||||
width: 80%
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
window.onload = async () => {
|
||||
const account = JSON.parse(localStorage.getItem("account"));
|
||||
const i = account.token;
|
||||
|
||||
const api = (endpoint, data = {}) => {
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
// Append a credential
|
||||
if (i) data.i = i;
|
||||
|
||||
// Send request
|
||||
fetch(endpoint.indexOf("://") > -1 ? endpoint : `/api/${endpoint}`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
credentials: "omit",
|
||||
cache: "no-cache",
|
||||
})
|
||||
.then(async (res) => {
|
||||
const body = res.status === 204 ? null : await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
resolve(body);
|
||||
} else if (res.status === 204) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(body.error);
|
||||
}
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
document.getElementById("submit").addEventListener("click", () => {
|
||||
api("notes/create", {
|
||||
text: document.getElementById("text").value,
|
||||
}).then(() => {
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
api("notes/timeline").then((notes) => {
|
||||
const tl = document.getElementById("tl");
|
||||
for (const note of notes) {
|
||||
const el = document.createElement("div");
|
||||
const header = document.createElement("header");
|
||||
const name = document.createElement("p");
|
||||
const avatar = document.createElement("img");
|
||||
name.textContent = `${note.user.name} @${note.user.username}`;
|
||||
avatar.src = note.user.avatarUrl;
|
||||
avatar.style = "height: 40px";
|
||||
const text = document.createElement("div");
|
||||
text.textContent = `${note.text}`;
|
||||
el.appendChild(header);
|
||||
header.appendChild(avatar);
|
||||
header.appendChild(name);
|
||||
if (note.text) {
|
||||
el.appendChild(text);
|
||||
}
|
||||
if (note.files) {
|
||||
for (const file of note.files) {
|
||||
const img = document.createElement("img");
|
||||
img.src = file.properties.thumbnailUrl;
|
||||
el.appendChild(img);
|
||||
}
|
||||
}
|
||||
tl.appendChild(el);
|
||||
}
|
||||
});
|
||||
};
|
|
@ -10,7 +10,6 @@ import Router from "@koa/router";
|
|||
import send from "koa-send";
|
||||
import favicon from "koa-favicon";
|
||||
import views from "koa-views";
|
||||
import sharp from "sharp";
|
||||
import {createBullBoard} from "@bull-board/api";
|
||||
import {BullAdapter} from "@bull-board/api/bullAdapter.js";
|
||||
import {KoaAdapter} from "@bull-board/koa";
|
||||
|
@ -18,15 +17,7 @@ import { KoaAdapter } from "@bull-board/koa";
|
|||
import {In, IsNull} from "typeorm";
|
||||
import {fetchMeta, metaToPugArgs} from "@/misc/fetch-meta.js";
|
||||
import config from "@/config/index.js";
|
||||
import {
|
||||
Users,
|
||||
Notes,
|
||||
UserProfiles,
|
||||
Pages,
|
||||
Channels,
|
||||
Clips,
|
||||
GalleryPosts,
|
||||
} from "@/models/index.js";
|
||||
import {Channels, Clips, GalleryPosts, Notes, Pages, UserProfiles, Users,} from "@/models/index.js";
|
||||
import * as Acct from "@/misc/acct.js";
|
||||
import {getNoteSummary} from "@/misc/get-note-summary.js";
|
||||
import {queues} from "@/queue/queues.js";
|
||||
|
@ -34,7 +25,7 @@ import { genOpenapiSpec } from "../api/openapi/gen-spec.js";
|
|||
import {urlPreviewHandler} from "./url-preview.js";
|
||||
import {manifestHandler} from "./manifest.js";
|
||||
import packFeed from "./feed.js";
|
||||
import { MINUTE, DAY } from "@/const.js";
|
||||
import {DAY, MINUTE} from "@/const.js";
|
||||
|
||||
const _filename = fileURLToPath(import.meta.url);
|
||||
const _dirname = dirname(_filename);
|
||||
|
@ -160,60 +151,6 @@ router.get("/twemoji/(.*)", async (ctx) => {
|
|||
});
|
||||
});
|
||||
|
||||
router.get("/twemoji-badge/(.*)", async (ctx) => {
|
||||
const path = ctx.path.replace("/twemoji-badge/", "");
|
||||
|
||||
if (!path.match(/^[0-9a-f-]+\.png$/)) {
|
||||
ctx.status = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
const mask = await sharp(
|
||||
`${_dirname}/../../../node_modules/@discordapp/twemoji/dist/svg/${path.replace(
|
||||
".png",
|
||||
"",
|
||||
)}.svg`,
|
||||
{ density: 1000 },
|
||||
)
|
||||
.resize(488, 488)
|
||||
.greyscale()
|
||||
.normalise()
|
||||
.linear(1.75, -(128 * 1.75) + 128) // 1.75x contrast
|
||||
.flatten({ background: "#000" })
|
||||
.extend({
|
||||
top: 12,
|
||||
bottom: 12,
|
||||
left: 12,
|
||||
right: 12,
|
||||
background: "#000",
|
||||
})
|
||||
.toColorspace("b-w")
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
const buffer = await sharp({
|
||||
create: {
|
||||
width: 512,
|
||||
height: 512,
|
||||
channels: 4,
|
||||
background: { r: 0, g: 0, b: 0, alpha: 0 },
|
||||
},
|
||||
})
|
||||
.pipelineColorspace("b-w")
|
||||
.boolean(mask, "eor")
|
||||
.resize(96, 96)
|
||||
.png()
|
||||
.toBuffer();
|
||||
|
||||
ctx.set(
|
||||
"Content-Security-Policy",
|
||||
"default-src 'none'; style-src 'unsafe-inline'",
|
||||
);
|
||||
ctx.set("Cache-Control", "max-age=2592000");
|
||||
ctx.set("Content-Type", "image/png");
|
||||
ctx.body = buffer;
|
||||
});
|
||||
|
||||
// ServiceWorker
|
||||
router.get("/sw.js", async (ctx) => {
|
||||
await send(ctx as any, "/sw.js", {
|
||||
|
@ -573,18 +510,6 @@ router.get("/channels/:channel", async (ctx, next) => {
|
|||
});
|
||||
//#endregion
|
||||
|
||||
router.get("/bios", async (ctx) => {
|
||||
await ctx.render("bios", {
|
||||
version: config.version,
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/cli", async (ctx) => {
|
||||
await ctx.render("cli", {
|
||||
version: config.version,
|
||||
});
|
||||
});
|
||||
|
||||
const override = (source: string, target: string, depth = 0) =>
|
||||
[
|
||||
undefined,
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
doctype html
|
||||
|
||||
html
|
||||
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='application-name' content='Calckey')
|
||||
meta(name='viewport' content='width=device-width, initial-scale=1.0')
|
||||
title Calckey Repair Tool
|
||||
style
|
||||
include ../bios.css
|
||||
script
|
||||
include ../bios.js
|
||||
|
||||
body
|
||||
header
|
||||
h1 Calckey Repair Tool v#{version}
|
||||
main
|
||||
div.tabs
|
||||
button#ls Edit local storage
|
||||
div#content
|
|
@ -1,23 +0,0 @@
|
|||
doctype html
|
||||
|
||||
html
|
||||
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='application-name' content='Calckey')
|
||||
meta(name='viewport' content='width=device-width, initial-scale=1.0')
|
||||
title Calckey Cli
|
||||
style
|
||||
include ../cli.css
|
||||
script
|
||||
include ../cli.js
|
||||
|
||||
body
|
||||
header
|
||||
h1 Calckey Simple Client v#{version}
|
||||
main
|
||||
div#form
|
||||
textarea#text
|
||||
br
|
||||
button#submit Post
|
||||
div#tl
|
|
@ -9,7 +9,6 @@ import { pushNotificationDataMap } from "@/types";
|
|||
import getUserName from "@/scripts/get-user-name";
|
||||
import {I18n} from "@/scripts/i18n";
|
||||
import {getAccountFromId} from "@/scripts/get-account-from-id";
|
||||
import { char2fileName } from "@/scripts/twemoji-base";
|
||||
import * as url from "@/scripts/url";
|
||||
|
||||
const iconUrl = (name: string) =>
|
||||
|
@ -185,9 +184,6 @@ async function composeNotification<K extends keyof pushNotificationDataMap>(
|
|||
})}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Unicode絵文字の場合
|
||||
badge = `/twemoji-badge/${char2fileName(reaction)}.png`;
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
export const twemojiSvgBase = "/twemoji";
|
||||
|
||||
export function char2fileName(char: string): string {
|
||||
let codes = Array.from(char).map((x) => x.codePointAt(0)?.toString(16));
|
||||
if (!codes.includes("200d")) codes = codes.filter((x) => x !== "fe0f");
|
||||
codes = codes.filter((x) => x?.length);
|
||||
return codes.join("-");
|
||||
}
|
||||
|
||||
export function char2filePath(char: string): string {
|
||||
return `${twemojiSvgBase}/${char2fileName(char)}.svg`;
|
||||
}
|
Loading…
Reference in New Issue