mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-22 04:11:12 +00:00
Store manifest in memory so it does not need to be generated for every page request (#1433)
Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
638ab2c462
commit
3db4fdddcd
4 changed files with 72 additions and 56 deletions
28
src/server/handlers/manifest-handler.ts
Normal file
28
src/server/handlers/manifest-handler.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import type { Request, Response } from "express";
|
||||
import { LemmyHttp } from "lemmy-js-client";
|
||||
import { getHttpBaseInternal } from "../../shared/env";
|
||||
import { wrapClient } from "../../shared/services/HttpService";
|
||||
import generateManifestJson from "../utils/generate-manifest-json";
|
||||
import { setForwardedHeaders } from "../utils/set-forwarded-headers";
|
||||
|
||||
let manifest: Awaited<ReturnType<typeof generateManifestJson>> | undefined =
|
||||
undefined;
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
if (!manifest) {
|
||||
const headers = setForwardedHeaders(req.headers);
|
||||
const client = wrapClient(new LemmyHttp(getHttpBaseInternal(), headers));
|
||||
const site = await client.getSite({});
|
||||
|
||||
if (site.state === "success") {
|
||||
manifest = await generateManifestJson(site.data);
|
||||
} else {
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
res.setHeader("content-type", "application/manifest+json");
|
||||
|
||||
res.send(manifest);
|
||||
};
|
|
@ -2,6 +2,7 @@ import express from "express";
|
|||
import path from "path";
|
||||
import process from "process";
|
||||
import CatchAllHandler from "./handlers/catch-all-handler";
|
||||
import ManifestHandler from "./handlers/manifest-handler";
|
||||
import RobotsHandler from "./handlers/robots-handler";
|
||||
import ServiceWorkerHandler from "./handlers/service-worker-handler";
|
||||
import ThemeHandler from "./handlers/theme-handler";
|
||||
|
@ -24,6 +25,7 @@ if (!process.env["LEMMY_UI_DISABLE_CSP"] && !process.env["LEMMY_UI_DEBUG"]) {
|
|||
|
||||
server.get("/robots.txt", RobotsHandler);
|
||||
server.get("/service-worker.js", ServiceWorkerHandler);
|
||||
server.get("/manifest", ManifestHandler);
|
||||
server.get("/css/themes/:name", ThemeHandler);
|
||||
server.get("/css/themelist", ThemesListHandler);
|
||||
server.get("/*", CatchAllHandler);
|
||||
|
|
|
@ -5,32 +5,35 @@ import sharp from "sharp";
|
|||
import { ILemmyConfig, IsoDataOptionalSite } from "../../shared/interfaces";
|
||||
import { favIconPngUrl, favIconUrl } from "../../shared/utils";
|
||||
import { fetchIconPng } from "./fetch-icon-png";
|
||||
import { generateManifestBase64 } from "./generate-manifest-base64";
|
||||
|
||||
const customHtmlHeader = process.env["LEMMY_UI_CUSTOM_HTML_HEADER"] || "";
|
||||
|
||||
let appleTouchIcon: string | undefined = undefined;
|
||||
|
||||
export async function createSsrHtml(
|
||||
root: string,
|
||||
isoData: IsoDataOptionalSite
|
||||
) {
|
||||
const site = isoData.site_res;
|
||||
|
||||
const appleTouchIcon = site?.site_view.site.icon
|
||||
? `data:image/png;base64,${sharp(
|
||||
await fetchIconPng(site.site_view.site.icon)
|
||||
)
|
||||
.resize(180, 180)
|
||||
.extend({
|
||||
bottom: 20,
|
||||
top: 20,
|
||||
left: 20,
|
||||
right: 20,
|
||||
background: "#222222",
|
||||
})
|
||||
.png()
|
||||
.toBuffer()
|
||||
.then(buf => buf.toString("base64"))}`
|
||||
: favIconPngUrl;
|
||||
if (!appleTouchIcon) {
|
||||
appleTouchIcon = site?.site_view.site.icon
|
||||
? `data:image/png;base64,${sharp(
|
||||
await fetchIconPng(site.site_view.site.icon)
|
||||
)
|
||||
.resize(180, 180)
|
||||
.extend({
|
||||
bottom: 20,
|
||||
top: 20,
|
||||
left: 20,
|
||||
right: 20,
|
||||
background: "#222222",
|
||||
})
|
||||
.png()
|
||||
.toBuffer()
|
||||
.then(buf => buf.toString("base64"))}`
|
||||
: favIconPngUrl;
|
||||
}
|
||||
|
||||
const erudaStr =
|
||||
process.env["LEMMY_UI_DEBUG"] === "true"
|
||||
|
@ -74,15 +77,7 @@ export async function createSsrHtml(
|
|||
/>
|
||||
|
||||
<!-- Web app manifest -->
|
||||
${
|
||||
site &&
|
||||
`<link
|
||||
rel="manifest"
|
||||
href=${`data:application/manifest+json;base64,${await generateManifestBase64(
|
||||
site
|
||||
)}`}
|
||||
/>`
|
||||
}
|
||||
<link rel="manifest" href="/manifest" />
|
||||
<link rel="apple-touch-icon" href=${appleTouchIcon} />
|
||||
<link rel="apple-touch-startup-image" href=${appleTouchIcon} />
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import sharp from "sharp";
|
|||
import { getHttpBaseExternal } from "../../shared/env";
|
||||
import { fetchIconPng } from "./fetch-icon-png";
|
||||
|
||||
const iconSizes = [72, 96, 144, 192, 512];
|
||||
const iconSizes = [72, 96, 128, 144, 152, 192, 384, 512];
|
||||
|
||||
const defaultLogoPathDirectory = path.join(
|
||||
process.cwd(),
|
||||
|
@ -14,7 +14,7 @@ const defaultLogoPathDirectory = path.join(
|
|||
"icons"
|
||||
);
|
||||
|
||||
export async function generateManifestBase64({
|
||||
export default async function ({
|
||||
my_user,
|
||||
site_view: {
|
||||
site,
|
||||
|
@ -25,7 +25,7 @@ export async function generateManifestBase64({
|
|||
|
||||
const icon = site.icon ? await fetchIconPng(site.icon) : null;
|
||||
|
||||
const manifest = {
|
||||
return {
|
||||
name: site.name,
|
||||
description: site.description ?? "A link aggregator for the fediverse",
|
||||
start_url: url,
|
||||
|
@ -69,31 +69,24 @@ export async function generateManifestBase64({
|
|||
short_name: "Communities",
|
||||
description: "Browse communities",
|
||||
},
|
||||
]
|
||||
.concat(
|
||||
my_user
|
||||
? [
|
||||
{
|
||||
name: "Create Post",
|
||||
url: "/create_post",
|
||||
short_name: "Create Post",
|
||||
description: "Create a post.",
|
||||
},
|
||||
]
|
||||
: []
|
||||
)
|
||||
.concat(
|
||||
my_user?.local_user_view.person.admin || !community_creation_admin_only
|
||||
? [
|
||||
{
|
||||
name: "Create Community",
|
||||
url: "/create_community",
|
||||
short_name: "Create Community",
|
||||
description: "Create a community",
|
||||
},
|
||||
]
|
||||
: []
|
||||
),
|
||||
{
|
||||
name: "Create Post",
|
||||
url: "/create_post",
|
||||
short_name: "Create Post",
|
||||
description: "Create a post.",
|
||||
},
|
||||
].concat(
|
||||
my_user?.local_user_view.person.admin || !community_creation_admin_only
|
||||
? [
|
||||
{
|
||||
name: "Create Community",
|
||||
url: "/create_community",
|
||||
short_name: "Create Community",
|
||||
description: "Create a community",
|
||||
},
|
||||
]
|
||||
: []
|
||||
),
|
||||
related_applications: [
|
||||
{
|
||||
platform: "f-droid",
|
||||
|
@ -102,6 +95,4 @@ export async function generateManifestBase64({
|
|||
},
|
||||
],
|
||||
};
|
||||
|
||||
return Buffer.from(JSON.stringify(manifest)).toString("base64");
|
||||
}
|
Loading…
Reference in a new issue