feat: list logos from the api instead of hardcoding it
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
const baseApiUrl = useBaseApiUrl();
|
||||
const { copy: copyBaseApiUrl, icon: baseApiUrlIcon } = useCopyable(baseApiUrl);
|
||||
const { data: logos } = await useFetch<string[]>("/api/logos");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -10,8 +11,8 @@ const { copy: copyBaseApiUrl, icon: baseApiUrlIcon } = useCopyable(baseApiUrl);
|
||||
<p>
|
||||
You can easily generate QRCodes by using the API, with no rate
|
||||
limitation.
|
||||
<br />
|
||||
<br />
|
||||
<br >
|
||||
<br >
|
||||
If you are not sure how to use the API, you can fill the QRCode form
|
||||
and copy the generated API URL.
|
||||
</p>
|
||||
@@ -58,7 +59,7 @@ const { copy: copyBaseApiUrl, icon: baseApiUrlIcon } = useCopyable(baseApiUrl);
|
||||
<div class="flex pb-4 justify-between gap-x-5">
|
||||
<span class="text-primary font-semibold">logo</span>
|
||||
<span class="text-slate-700 dark:text-slate-200 text-right">{{
|
||||
arrayToUnion(LOGOS)
|
||||
arrayToUnion(logos ?? [])
|
||||
}}</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,10 +11,12 @@ const apiModal = overlay.create(LazyApiModal);
|
||||
|
||||
const isQRCodeEmpty = computed(() => qrCode.value === "/default.webp");
|
||||
|
||||
const { data: logos } = await useFetch<string[]>("/api/logos");
|
||||
|
||||
const formSchema = z
|
||||
.object({
|
||||
hasLogo: z.boolean(),
|
||||
logo: z.enum(LOGOS).optional(),
|
||||
logo: z.string().optional(),
|
||||
format: z.enum(IMAGE_FORMATS).default("png"),
|
||||
content: z
|
||||
.string()
|
||||
@@ -103,7 +105,7 @@ const {
|
||||
<img
|
||||
:src="qrCode"
|
||||
class="w-full max-w-[375px] max-h-[375px] sm:max-w-[315px] sm:max-h-[315px] md:max-w-[375px] md:max-h-[375px] m-auto aspect-square border border-gray-100 dark:border-gray-800"
|
||||
/>
|
||||
>
|
||||
|
||||
<div class="flex-1 flex flex-col justify-center">
|
||||
<UForm
|
||||
@@ -138,7 +140,7 @@ const {
|
||||
<USelectMenu
|
||||
v-model="formState.logo"
|
||||
icon="i-heroicons-photo"
|
||||
:items="unreadonly(LOGOS)"
|
||||
:items="logos ?? []"
|
||||
:disabled="!formState.hasLogo"
|
||||
placeholder="Select logo"
|
||||
class="w-full"
|
||||
|
||||
22
server/api/logos.ts
Normal file
22
server/api/logos.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { readdir } from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { createHash } from "crypto";
|
||||
|
||||
const logosDir = import.meta.dev
|
||||
? join(process.cwd(), "public/logos")
|
||||
: join(process.cwd(), ".output/public/logos");
|
||||
|
||||
export default defineCachedEventHandler(async () => {
|
||||
const files = await readdir(logosDir);
|
||||
return files
|
||||
.filter((f) => f.endsWith(".png"))
|
||||
.map((f) => f.replace(/\.png$/, ""))
|
||||
.sort();
|
||||
}, {
|
||||
maxAge: 60 * 60 * 24,
|
||||
getKey: async () => {
|
||||
const files = await readdir(logosDir);
|
||||
const key = files.filter((f) => f.endsWith(".png")).sort().join(",");
|
||||
return createHash("sha256").update(key).digest("hex");
|
||||
},
|
||||
});
|
||||
@@ -1,60 +1,12 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// TODO: might be better to load these dynamically lol
|
||||
export const LOGOS = [
|
||||
"bereal",
|
||||
"bitcoin",
|
||||
"buymeacoffee",
|
||||
"diaspora",
|
||||
"discord",
|
||||
"dropbox",
|
||||
"ello",
|
||||
"facebook",
|
||||
"flickr",
|
||||
"github",
|
||||
"googlemaps",
|
||||
"googlemeet",
|
||||
"googlemessages",
|
||||
"imessage",
|
||||
"instagram",
|
||||
"kik",
|
||||
"line",
|
||||
"linkedin",
|
||||
"litecoin",
|
||||
"mastodon",
|
||||
"medium",
|
||||
"messenger",
|
||||
"monero",
|
||||
"onlyfans",
|
||||
"patreon",
|
||||
"paypal",
|
||||
"peertube",
|
||||
"pinterest",
|
||||
"reddit",
|
||||
"session",
|
||||
"signal",
|
||||
"snapchat",
|
||||
"spotify",
|
||||
"substack",
|
||||
"telegram",
|
||||
"threema",
|
||||
"twitch",
|
||||
"venmo",
|
||||
"viber",
|
||||
"wechat",
|
||||
"whatsapp",
|
||||
"x",
|
||||
"youtube",
|
||||
"zoom",
|
||||
] as const;
|
||||
|
||||
export const IMAGE_FORMATS = ["png", "jpeg", "webp"] as const;
|
||||
|
||||
export type ImageFormat = (typeof IMAGE_FORMATS)[number];
|
||||
|
||||
export const settingsSchema = z.object({
|
||||
format: z.enum(IMAGE_FORMATS).default("png"),
|
||||
logo: z.enum(LOGOS).optional(),
|
||||
logo: z.string().optional(),
|
||||
content: z.string().min(1, "Required"),
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user