fix(icons): local icon repository does not work with medias (#1765)

This commit is contained in:
Meier Lukas
2024-12-24 14:15:18 +01:00
committed by GitHub
parent f127c9325c
commit e220087e96
6 changed files with 49 additions and 13 deletions

View File

@@ -27,6 +27,7 @@
"@homarr/cron-jobs": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/icons": "workspace:^0.1.0",
"@homarr/integrations": "workspace:^0.1.0",
"@homarr/log": "workspace:^",
"@homarr/old-import": "workspace:^0.1.0",

View File

@@ -1,7 +1,9 @@
import { TRPCError } from "@trpc/server";
import type { InferInsertModel } from "@homarr/db";
import { and, createId, desc, eq, like } from "@homarr/db";
import { medias } from "@homarr/db/schema";
import { iconRepositories, icons, medias } from "@homarr/db/schema";
import { createLocalImageUrl, LOCAL_ICON_REPOSITORY_SLUG, mapMediaToIcon } from "@homarr/icons/local";
import { validation, z } from "@homarr/validation";
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure } from "../../trpc";
@@ -52,13 +54,29 @@ export const mediaRouter = createTRPCRouter({
.mutation(async ({ ctx, input }) => {
const content = Buffer.from(await input.file.arrayBuffer());
const id = createId();
await ctx.db.insert(medias).values({
const media = {
id,
creatorId: ctx.session.user.id,
content,
size: input.file.size,
contentType: input.file.type,
name: input.file.name,
} satisfies InferInsertModel<typeof medias>;
await ctx.db.insert(medias).values(media);
const localIconRepository = await ctx.db.query.iconRepositories.findFirst({
where: eq(iconRepositories.slug, LOCAL_ICON_REPOSITORY_SLUG),
});
if (!localIconRepository) return id;
const icon = mapMediaToIcon(media);
await ctx.db.insert(icons).values({
id: createId(),
checksum: icon.checksum,
name: icon.fileNameWithExtension,
url: icon.imageUrl,
iconRepositoryId: localIconRepository.id,
});
return id;
@@ -67,6 +85,7 @@ export const mediaRouter = createTRPCRouter({
const dbMedia = await ctx.db.query.medias.findFirst({
where: eq(medias.id, input.id),
columns: {
id: true,
creatorId: true,
},
});
@@ -87,5 +106,6 @@ export const mediaRouter = createTRPCRouter({
}
await ctx.db.delete(medias).where(eq(medias.id, input.id));
await ctx.db.delete(icons).where(eq(icons.url, createLocalImageUrl(input.id)));
}),
});

View File

@@ -5,7 +5,8 @@
"license": "MIT",
"type": "module",
"exports": {
".": "./index.ts"
".": "./index.ts",
"./local": "./src/local.ts"
},
"typesVersions": {
"*": {

View File

@@ -0,0 +1 @@
export { createLocalImageUrl, mapMediaToIcon, LOCAL_ICON_REPOSITORY_SLUG } from "./repositories/local.icon-repository";

View File

@@ -1,26 +1,36 @@
import { createHash } from "crypto";
import type { InferSelectModel } from "@homarr/db";
import { db } from "@homarr/db";
import type { medias } from "@homarr/db/schema";
import type { RepositoryIconGroup } from "../types";
import type { RepositoryIcon, RepositoryIconGroup } from "../types";
import { IconRepository } from "./icon-repository";
export const LOCAL_ICON_REPOSITORY_SLUG = "local";
export class LocalIconRepository extends IconRepository {
constructor() {
super("Local", "local", undefined, undefined, undefined, undefined);
super("Local", LOCAL_ICON_REPOSITORY_SLUG, undefined, undefined, undefined, undefined);
}
protected async getAllIconsInternalAsync(): Promise<RepositoryIconGroup> {
const medias = await db.query.medias.findMany();
return {
success: true,
icons: medias.map((media) => ({
local: true,
fileNameWithExtension: media.name,
imageUrl: `/api/user-medias/${media.id}`,
checksum: createHash("md5").update(media.content).digest("hex"),
sizeInBytes: media.size,
})),
slug: "local",
icons: medias.map(mapMediaToIcon),
slug: LOCAL_ICON_REPOSITORY_SLUG,
};
}
}
export const createLocalImageUrl = (id: string) => `/api/user-medias/${id}`;
export const mapMediaToIcon = (
media: Pick<InferSelectModel<typeof medias>, "name" | "id" | "content" | "size">,
): RepositoryIcon => ({
local: true,
fileNameWithExtension: media.name,
imageUrl: createLocalImageUrl(media.id),
checksum: createHash("md5").update(media.content).digest("hex"),
sizeInBytes: media.size,
});

3
pnpm-lock.yaml generated
View File

@@ -509,6 +509,9 @@ importers:
'@homarr/definitions':
specifier: workspace:^0.1.0
version: link:../definitions
'@homarr/icons':
specifier: workspace:^0.1.0
version: link:../icons
'@homarr/integrations':
specifier: workspace:^0.1.0
version: link:../integrations