mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-09 20:12:10 +10:00
Compare commits
6 Commits
d7ca0b080e
...
d92957f450
| Author | SHA1 | Date | |
|---|---|---|---|
| d92957f450 | |||
| a201b62c04 | |||
| 9bf164ab77 | |||
| 97c6f3490c | |||
| f5cb856d3d | |||
| 67de1f6c02 |
@ -3,9 +3,10 @@
|
|||||||
<button
|
<button
|
||||||
v-for="(_, i) in amount"
|
v-for="(_, i) in amount"
|
||||||
:key="i"
|
:key="i"
|
||||||
|
@click="slideTo(i)"
|
||||||
:class="[
|
:class="[
|
||||||
carousel.currentSlide == i ? 'bg-blue-600 w-6' : 'bg-zinc-700 w-3',
|
carousel.currentSlide === i ? 'bg-blue-600 w-6' : 'bg-zinc-700 w-3',
|
||||||
'transition-all cursor-pointer h-2 rounded-full',
|
'transition-all cursor-pointer h-2 rounded-full'
|
||||||
]"
|
]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -18,8 +19,8 @@ const carousel = inject(injectCarousel)!;
|
|||||||
|
|
||||||
const amount = carousel.maxSlide - carousel.minSlide + 1;
|
const amount = carousel.maxSlide - carousel.minSlide + 1;
|
||||||
|
|
||||||
// function slideTo(index: number) {
|
function slideTo(index: number) {
|
||||||
// const offsetIndex = index + carousel.minSlide;
|
const offsetIndex = index + carousel.minSlide;
|
||||||
// carousel.nav.slideTo(offsetIndex);
|
carousel.nav.slideTo(offsetIndex);
|
||||||
// }
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -176,9 +176,12 @@
|
|||||||
active ? 'bg-zinc-900 outline-hidden' : '',
|
active ? 'bg-zinc-900 outline-hidden' : '',
|
||||||
'w-full text-left block px-4 py-2 text-sm',
|
'w-full text-left block px-4 py-2 text-sm',
|
||||||
]"
|
]"
|
||||||
@click="() => (currentSort = option.param)"
|
@click.prevent="handleSortClick(option, $event)"
|
||||||
>
|
>
|
||||||
{{ option.name }}
|
{{ option.name }}
|
||||||
|
<span v-if="currentSort === option.param">
|
||||||
|
{{ sortOrder === 'asc' ? '↑' : '↓' }}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</div>
|
</div>
|
||||||
@ -292,7 +295,7 @@
|
|||||||
<div
|
<div
|
||||||
v-if="games?.length ?? 0 > 0"
|
v-if="games?.length ?? 0 > 0"
|
||||||
ref="product-grid"
|
ref="product-grid"
|
||||||
class="relative lg:col-span-4 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4 xl:grid-cols-6 2xl:grid-cols-7 gap-4"
|
class="relative lg:col-span-4 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 gap-4"
|
||||||
>
|
>
|
||||||
<!-- Your content -->
|
<!-- Your content -->
|
||||||
<GamePanel
|
<GamePanel
|
||||||
@ -389,8 +392,13 @@ const sorts: Array<StoreSortOption> = [
|
|||||||
name: "Recently Added",
|
name: "Recently Added",
|
||||||
param: "recent",
|
param: "recent",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Name",
|
||||||
|
param: "name",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const currentSort = ref(sorts[0].param);
|
const currentSort = ref(sorts[0].param);
|
||||||
|
const sortOrder = ref<"asc" | "desc">("desc");
|
||||||
|
|
||||||
const options: Array<StoreFilterOption> = [
|
const options: Array<StoreFilterOption> = [
|
||||||
...(tags.length > 0
|
...(tags.length > 0
|
||||||
@ -466,7 +474,7 @@ async function updateGames(query: string, resetGames: boolean) {
|
|||||||
results: Array<SerializeObject<GameModel>>;
|
results: Array<SerializeObject<GameModel>>;
|
||||||
count: number;
|
count: number;
|
||||||
}>(
|
}>(
|
||||||
`/api/v1/store?take=50&skip=${resetGames ? 0 : games.value?.length || 0}&sort=${currentSort.value}${query ? "&" + query : ""}`,
|
`/api/v1/store?take=50&skip=${resetGames ? 0 : games.value?.length || 0}&sort=${currentSort.value}&order=${sortOrder.value}${query ? "&" + query : ""}`,
|
||||||
);
|
);
|
||||||
if (resetGames) {
|
if (resetGames) {
|
||||||
games.value = newValues.results;
|
games.value = newValues.results;
|
||||||
@ -483,6 +491,20 @@ watch(filterQuery, (newUrl) => {
|
|||||||
watch(currentSort, (_) => {
|
watch(currentSort, (_) => {
|
||||||
updateGames(filterQuery.value, true);
|
updateGames(filterQuery.value, true);
|
||||||
});
|
});
|
||||||
|
watch(sortOrder, (_) => {
|
||||||
|
updateGames(filterQuery.value, true);
|
||||||
|
});
|
||||||
|
|
||||||
await updateGames(filterQuery.value, true);
|
await updateGames(filterQuery.value, true);
|
||||||
</script>
|
|
||||||
|
function handleSortClick(option: StoreSortOption, event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
if (currentSort.value === option.param) {
|
||||||
|
sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc';
|
||||||
|
} else {
|
||||||
|
currentSort.value = option.param;
|
||||||
|
sortOrder.value = option.param === 'name' ? 'asc' : 'desc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -256,6 +256,7 @@ export default defineNuxtConfig({
|
|||||||
"https://www.giantbomb.com",
|
"https://www.giantbomb.com",
|
||||||
"https://images.pcgamingwiki.com",
|
"https://images.pcgamingwiki.com",
|
||||||
"https://images.igdb.com",
|
"https://images.igdb.com",
|
||||||
|
"https://*.steamstatic.com",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
strictTransportSecurity: false,
|
strictTransportSecurity: false,
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
"@vueuse/nuxt": "13.6.0",
|
"@vueuse/nuxt": "13.6.0",
|
||||||
"argon2": "^0.43.0",
|
"argon2": "^0.43.0",
|
||||||
"arktype": "^2.1.10",
|
"arktype": "^2.1.10",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.12.0",
|
||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"cheerio": "^1.0.0",
|
"cheerio": "^1.0.0",
|
||||||
"cookie-es": "^2.0.0",
|
"cookie-es": "^2.0.0",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"luxon": "^3.6.1",
|
"luxon": "^3.6.1",
|
||||||
"micromark": "^4.0.1",
|
"micromark": "^4.0.1",
|
||||||
"normalize-url": "^8.0.2",
|
"normalize-url": "^8.0.2",
|
||||||
"nuxt": "^3.17.4",
|
"nuxt": "^3.19.0",
|
||||||
"nuxt-security": "2.2.0",
|
"nuxt-security": "2.2.0",
|
||||||
"pino": "^9.7.0",
|
"pino": "^9.7.0",
|
||||||
"pino-pretty": "^13.0.0",
|
"pino-pretty": "^13.0.0",
|
||||||
|
|||||||
@ -72,7 +72,7 @@
|
|||||||
{{ $t("store.images") }}
|
{{ $t("store.images") }}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<VueCarousel :items-to-show="1">
|
<VueCarousel :items-to-show="1" :wrap-around="true">
|
||||||
<VueSlide
|
<VueSlide
|
||||||
v-for="image in game.mImageCarouselObjectIds"
|
v-for="image in game.mImageCarouselObjectIds"
|
||||||
:key="image"
|
:key="image"
|
||||||
|
|||||||
@ -183,7 +183,7 @@
|
|||||||
{{ game.mShortDescription }}
|
{{ game.mShortDescription }}
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6 py-4 rounded">
|
<div class="mt-6 py-4 rounded">
|
||||||
<VueCarousel :items-to-show="1">
|
<VueCarousel :items-to-show="1" :wrap-around="true">
|
||||||
<VueSlide
|
<VueSlide
|
||||||
v-for="image in game.mImageCarouselObjectIds"
|
v-for="image in game.mImageCarouselObjectIds"
|
||||||
:key="image"
|
:key="image"
|
||||||
|
|||||||
2976
pnpm-lock.yaml
generated
2976
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
|||||||
|
-- AlterEnum
|
||||||
|
ALTER TYPE "MetadataSource" ADD VALUE 'Steam';
|
||||||
|
|
||||||
|
-- DropIndex
|
||||||
|
DROP INDEX "GameTag_name_idx";
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "GameTag_name_idx" ON "GameTag" USING GIST ("name" gist_trgm_ops(siglen=32));
|
||||||
@ -1,6 +1,7 @@
|
|||||||
enum MetadataSource {
|
enum MetadataSource {
|
||||||
Manual
|
Manual
|
||||||
GiantBomb
|
GiantBomb
|
||||||
|
Steam
|
||||||
PCGamingWiki
|
PCGamingWiki
|
||||||
IGDB
|
IGDB
|
||||||
Metacritic
|
Metacritic
|
||||||
|
|||||||
@ -18,7 +18,8 @@ const StoreRead = type({
|
|||||||
company: "string?",
|
company: "string?",
|
||||||
companyActions: "string = 'published,developed'",
|
companyActions: "string = 'published,developed'",
|
||||||
|
|
||||||
sort: "'default' | 'newest' | 'recent' = 'default'",
|
sort: "'default' | 'newest' | 'recent' | 'name' = 'default'",
|
||||||
|
order: "'asc' | 'desc' = 'desc'",
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defineEventHandler(async (h3) => {
|
export default defineEventHandler(async (h3) => {
|
||||||
@ -101,10 +102,13 @@ export default defineEventHandler(async (h3) => {
|
|||||||
switch (options.sort) {
|
switch (options.sort) {
|
||||||
case "default":
|
case "default":
|
||||||
case "newest":
|
case "newest":
|
||||||
sort.mReleased = "desc";
|
sort.mReleased = options.order;
|
||||||
break;
|
break;
|
||||||
case "recent":
|
case "recent":
|
||||||
sort.created = "desc";
|
sort.created = options.order;
|
||||||
|
break;
|
||||||
|
case "name":
|
||||||
|
sort.mName = options.order;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,4 +123,4 @@ export default defineEventHandler(async (h3) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return { results, count };
|
return { results, count };
|
||||||
});
|
});
|
||||||
1022
server/internal/metadata/steam.ts
Normal file
1022
server/internal/metadata/steam.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,11 +5,13 @@ import { GiantBombProvider } from "../internal/metadata/giantbomb";
|
|||||||
import { IGDBProvider } from "../internal/metadata/igdb";
|
import { IGDBProvider } from "../internal/metadata/igdb";
|
||||||
import { ManualMetadataProvider } from "../internal/metadata/manual";
|
import { ManualMetadataProvider } from "../internal/metadata/manual";
|
||||||
import { PCGamingWikiProvider } from "../internal/metadata/pcgamingwiki";
|
import { PCGamingWikiProvider } from "../internal/metadata/pcgamingwiki";
|
||||||
|
import { SteamProvider } from "../internal/metadata/steam";
|
||||||
import { logger } from "~/server/internal/logging";
|
import { logger } from "~/server/internal/logging";
|
||||||
|
|
||||||
export default defineNitroPlugin(async (_nitro) => {
|
export default defineNitroPlugin(async (_nitro) => {
|
||||||
const metadataProviders = [
|
const metadataProviders = [
|
||||||
GiantBombProvider,
|
GiantBombProvider,
|
||||||
|
SteamProvider,
|
||||||
PCGamingWikiProvider,
|
PCGamingWikiProvider,
|
||||||
IGDBProvider,
|
IGDBProvider,
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user