mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-14 00:31:25 +10:00
Store overhaul (#142)
* feat: small library tweaks + company page * feat: new store view * fix: ci merge error * feat: add genres to store page * feat: sorting * feat: lock game/version imports while their tasks are running * feat: feature games * feat: tag based filtering * fix: make tags alphabetical * refactor: move a bunch of i18n to common * feat: add localizations for everything * fix: title description on panel * fix: feature carousel text * fix: i18n footer strings * feat: add tag page * fix: develop merge * feat: offline games support (don't error out if provider throws) * feat: tag management * feat: show library next to game import + small fixes * feat: most of the company and tag managers * feat: company text field editing * fix: small fixes + tsgo experiemental * feat: upload icon and banner * feat: store infinite scrolling and bulk import mode * fix: lint * fix: add drop-base to prettier ignore
This commit is contained in:
@ -6,6 +6,9 @@ export default defineEventHandler(async (h3) => {
|
||||
if (!userId) throw createError({ statusCode: 403 });
|
||||
|
||||
const games = await prisma.game.findMany({
|
||||
where: {
|
||||
featured: true,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
mName: true,
|
||||
@ -28,7 +31,6 @@ export default defineEventHandler(async (h3) => {
|
||||
orderBy: {
|
||||
created: "desc",
|
||||
},
|
||||
take: 8,
|
||||
});
|
||||
|
||||
return games;
|
||||
122
server/api/v1/store/index.get.ts
Normal file
122
server/api/v1/store/index.get.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import { ArkErrors, type } from "arktype";
|
||||
import type { Prisma } from "~/prisma/client/client";
|
||||
import aclManager from "~/server/internal/acls";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
import { parsePlatform } from "~/server/internal/utils/parseplatform";
|
||||
|
||||
const StoreRead = type({
|
||||
skip: type("string")
|
||||
.pipe((s) => Number.parseInt(s))
|
||||
.default("0"),
|
||||
take: type("string")
|
||||
.pipe((s) => Number.parseInt(s))
|
||||
.default("10"),
|
||||
|
||||
tags: "string?",
|
||||
platform: "string?",
|
||||
|
||||
company: "string?",
|
||||
companyActions: "string = 'published,developed'",
|
||||
|
||||
sort: "'default' | 'newest' | 'recent' = 'default'",
|
||||
});
|
||||
|
||||
export default defineEventHandler(async (h3) => {
|
||||
const userId = await aclManager.getUserIdACL(h3, ["store:read"]);
|
||||
if (!userId) throw createError({ statusCode: 403 });
|
||||
|
||||
const query = getQuery(h3);
|
||||
const options = StoreRead(query);
|
||||
if (options instanceof ArkErrors)
|
||||
throw createError({ statusCode: 400, statusMessage: options.summary });
|
||||
|
||||
/**
|
||||
* Generic filters
|
||||
*/
|
||||
const tagFilter = options.tags
|
||||
? {
|
||||
tags: {
|
||||
some: {
|
||||
id: {
|
||||
in: options.tags.split(","),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
const platformFilter = options.platform
|
||||
? {
|
||||
versions: {
|
||||
some: {
|
||||
platform: {
|
||||
in: options.platform
|
||||
.split(",")
|
||||
.map(parsePlatform)
|
||||
.filter((e) => e !== undefined),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
|
||||
/**
|
||||
* Company filtering
|
||||
*/
|
||||
const companyActions = options.companyActions.split(",");
|
||||
const developedFilter = companyActions.includes("developed")
|
||||
? {
|
||||
developers: {
|
||||
some: {
|
||||
id: options.company!,
|
||||
},
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
const publishedFilter = companyActions.includes("published")
|
||||
? {
|
||||
publishers: {
|
||||
some: {
|
||||
id: options.company!,
|
||||
},
|
||||
},
|
||||
}
|
||||
: undefined;
|
||||
const companyFilter = options.company
|
||||
? ({
|
||||
OR: [developedFilter, publishedFilter].filter((e) => e !== undefined),
|
||||
} satisfies Prisma.GameWhereInput)
|
||||
: undefined;
|
||||
|
||||
/**
|
||||
* Query
|
||||
*/
|
||||
|
||||
const finalFilter: Prisma.GameWhereInput = {
|
||||
...tagFilter,
|
||||
...platformFilter,
|
||||
...companyFilter,
|
||||
};
|
||||
|
||||
const sort: Prisma.GameOrderByWithRelationInput = {};
|
||||
switch (options.sort) {
|
||||
case "default":
|
||||
case "newest":
|
||||
sort.mReleased = "desc";
|
||||
break;
|
||||
case "recent":
|
||||
sort.created = "desc";
|
||||
break;
|
||||
}
|
||||
|
||||
const [results, count] = await prisma.$transaction([
|
||||
prisma.game.findMany({
|
||||
skip: options.skip,
|
||||
take: Math.min(options.take, 50),
|
||||
where: finalFilter,
|
||||
orderBy: sort,
|
||||
}),
|
||||
prisma.game.count({ where: finalFilter }),
|
||||
]);
|
||||
|
||||
return { results, count };
|
||||
});
|
||||
@ -2,15 +2,9 @@ import aclManager from "~/server/internal/acls";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineEventHandler(async (h3) => {
|
||||
const userId = await aclManager.getUserACL(h3, ["store:read"]);
|
||||
const userId = await aclManager.getUserIdACL(h3, ["store:read"]);
|
||||
if (!userId) throw createError({ statusCode: 403 });
|
||||
|
||||
const games = await prisma.game.findMany({
|
||||
orderBy: {
|
||||
mReleased: "desc",
|
||||
},
|
||||
take: 12,
|
||||
});
|
||||
|
||||
return games;
|
||||
const tags = await prisma.gameTag.findMany({ orderBy: { name: "asc" } });
|
||||
return tags;
|
||||
});
|
||||
@ -1,28 +0,0 @@
|
||||
import aclManager from "~/server/internal/acls";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineEventHandler(async (h3) => {
|
||||
const userId = await aclManager.getUserACL(h3, ["store:read"]);
|
||||
if (!userId) throw createError({ statusCode: 403 });
|
||||
|
||||
const versions = await prisma.gameVersion.findMany({
|
||||
where: {
|
||||
versionIndex: {
|
||||
gte: 1,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
game: true,
|
||||
},
|
||||
orderBy: {
|
||||
created: "desc",
|
||||
},
|
||||
take: 12,
|
||||
});
|
||||
|
||||
const games = versions
|
||||
.map((e) => e.game)
|
||||
.filter((v, i, a) => a.findIndex((e) => e.id === v.id) === i);
|
||||
|
||||
return games;
|
||||
});
|
||||
Reference in New Issue
Block a user