mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-05-13 13:17:45 +00:00
refactor: remove random sort
This commit is contained in:
parent
8ebc480233
commit
c72dab1962
5 changed files with 23 additions and 80 deletions
|
|
@ -32,7 +32,6 @@
|
||||||
"react-image-crop": "^11.0.10",
|
"react-image-crop": "^11.0.10",
|
||||||
"redis": "^5.11.0",
|
"redis": "^5.11.0",
|
||||||
"satori": "^0.26.0",
|
"satori": "^0.26.0",
|
||||||
"seedrandom": "^3.0.5",
|
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"sjcl-with-all": "1.0.8",
|
"sjcl-with-all": "1.0.8",
|
||||||
"swr": "^2.4.1",
|
"swr": "^2.4.1",
|
||||||
|
|
@ -46,7 +45,6 @@
|
||||||
"@types/node": "^25.6.0",
|
"@types/node": "^25.6.0",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/seedrandom": "^3.0.8",
|
|
||||||
"@types/sjcl": "^1.0.34",
|
"@types/sjcl": "^1.0.34",
|
||||||
"eslint": "^10.2.0",
|
"eslint": "^10.2.0",
|
||||||
"eslint-config-next": "16.2.3",
|
"eslint-config-next": "16.2.3",
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,6 @@ importers:
|
||||||
satori:
|
satori:
|
||||||
specifier: ^0.26.0
|
specifier: ^0.26.0
|
||||||
version: 0.26.0
|
version: 0.26.0
|
||||||
seedrandom:
|
|
||||||
specifier: ^3.0.5
|
|
||||||
version: 3.0.5
|
|
||||||
sharp:
|
sharp:
|
||||||
specifier: ^0.34.5
|
specifier: ^0.34.5
|
||||||
version: 0.34.5
|
version: 0.34.5
|
||||||
|
|
@ -108,9 +105,6 @@ importers:
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^19.2.3
|
specifier: ^19.2.3
|
||||||
version: 19.2.3(@types/react@19.2.14)
|
version: 19.2.3(@types/react@19.2.14)
|
||||||
'@types/seedrandom':
|
|
||||||
specifier: ^3.0.8
|
|
||||||
version: 3.0.8
|
|
||||||
'@types/sjcl':
|
'@types/sjcl':
|
||||||
specifier: ^1.0.34
|
specifier: ^1.0.34
|
||||||
version: 1.0.34
|
version: 1.0.34
|
||||||
|
|
@ -797,9 +791,6 @@ packages:
|
||||||
'@types/react@19.2.14':
|
'@types/react@19.2.14':
|
||||||
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
|
resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
|
||||||
|
|
||||||
'@types/seedrandom@3.0.8':
|
|
||||||
resolution: {integrity: sha512-TY1eezMU2zH2ozQoAFAQFOPpvP15g+ZgSfTZt31AUUH/Rxtnz3H+A/Sv1Snw2/amp//omibc+AEkTaA8KUeOLQ==}
|
|
||||||
|
|
||||||
'@types/sjcl@1.0.34':
|
'@types/sjcl@1.0.34':
|
||||||
resolution: {integrity: sha512-bQHEeK5DTQRunIfQeUMgtpPsNNCcZyQ9MJuAfW1I7iN0LDunTc78Fu17STbLMd7KiEY/g2zHVApippa70h6HoQ==}
|
resolution: {integrity: sha512-bQHEeK5DTQRunIfQeUMgtpPsNNCcZyQ9MJuAfW1I7iN0LDunTc78Fu17STbLMd7KiEY/g2zHVApippa70h6HoQ==}
|
||||||
|
|
||||||
|
|
@ -2252,9 +2243,6 @@ packages:
|
||||||
schema-dts@2.0.0:
|
schema-dts@2.0.0:
|
||||||
resolution: {integrity: sha512-t7NoCy3Rn5GHGx6p7s1qIYK/AeIb8ZxJNR9WUNFkwMv2CiiGZBmqqYWc2FlZVm5ZbiHMY4OvBWhj7QtyrFO2Jw==}
|
resolution: {integrity: sha512-t7NoCy3Rn5GHGx6p7s1qIYK/AeIb8ZxJNR9WUNFkwMv2CiiGZBmqqYWc2FlZVm5ZbiHMY4OvBWhj7QtyrFO2Jw==}
|
||||||
|
|
||||||
seedrandom@3.0.5:
|
|
||||||
resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==}
|
|
||||||
|
|
||||||
semver@6.3.1:
|
semver@6.3.1:
|
||||||
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
@ -3111,8 +3099,6 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.2.3
|
csstype: 3.2.3
|
||||||
|
|
||||||
'@types/seedrandom@3.0.8': {}
|
|
||||||
|
|
||||||
'@types/sjcl@1.0.34': {}
|
'@types/sjcl@1.0.34': {}
|
||||||
|
|
||||||
'@types/use-sync-external-store@0.0.6': {}
|
'@types/use-sync-external-store@0.0.6': {}
|
||||||
|
|
@ -4701,8 +4687,6 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- typescript
|
- typescript
|
||||||
|
|
||||||
seedrandom@3.0.5: {}
|
|
||||||
|
|
||||||
semver@6.3.1: {}
|
semver@6.3.1: {}
|
||||||
|
|
||||||
semver@7.7.4: {}
|
semver@7.7.4: {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
|
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import seedrandom from "seedrandom";
|
|
||||||
|
|
||||||
import { searchSchema } from "@/lib/schemas";
|
import { searchSchema } from "@/lib/schemas";
|
||||||
import { auth } from "@/lib/auth";
|
import { auth } from "@/lib/auth";
|
||||||
|
|
@ -23,7 +22,7 @@ export default async function MiiList({ searchParams, userId, parentPage }: Prop
|
||||||
const parsed = searchSchema.safeParse(searchParams);
|
const parsed = searchSchema.safeParse(searchParams);
|
||||||
if (!parsed.success) return <h1>{parsed.error.issues[0].message}</h1>;
|
if (!parsed.success) return <h1>{parsed.error.issues[0].message}</h1>;
|
||||||
|
|
||||||
const { q: query, sort, tags, exclude, platform, gender, makeup, allowCopying, quarantined, page = 1, limit = 24, seed } = parsed.data;
|
const { q: query, sort, tags, exclude, platform, gender, makeup, allowCopying, quarantined, page = 1, limit = 24 } = parsed.data;
|
||||||
|
|
||||||
// My Likes page
|
// My Likes page
|
||||||
let miiIdsLiked: number[] | undefined = undefined;
|
let miiIdsLiked: number[] | undefined = undefined;
|
||||||
|
|
@ -110,37 +109,6 @@ export default async function MiiList({ searchParams, userId, parentPage }: Prop
|
||||||
let totalCount: number;
|
let totalCount: number;
|
||||||
let miis: Prisma.MiiGetPayload<{ select: typeof select }>[];
|
let miis: Prisma.MiiGetPayload<{ select: typeof select }>[];
|
||||||
|
|
||||||
if (sort === "random") {
|
|
||||||
// Get all IDs that match the where conditions
|
|
||||||
const matchingIds = await prisma.mii.findMany({
|
|
||||||
where,
|
|
||||||
select: { id: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
totalCount = matchingIds.length;
|
|
||||||
|
|
||||||
if (matchingIds.length === 0) return;
|
|
||||||
|
|
||||||
// Use seed for consistent random results
|
|
||||||
const randomSeed = seed || crypto.randomInt(0, 1_000_000_000);
|
|
||||||
const rng = seedrandom(randomSeed.toString());
|
|
||||||
|
|
||||||
// Randomize all IDs using the Durstenfeld algorithm
|
|
||||||
for (let i = matchingIds.length - 1; i > 0; i--) {
|
|
||||||
const j = Math.floor(rng() * (i + 1));
|
|
||||||
[matchingIds[i], matchingIds[j]] = [matchingIds[j], matchingIds[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to number[] array
|
|
||||||
const selectedIds = matchingIds.slice(skip, skip + limit).map((i) => i.id);
|
|
||||||
|
|
||||||
miis = await prisma.mii.findMany({
|
|
||||||
where: {
|
|
||||||
id: { in: selectedIds },
|
|
||||||
},
|
|
||||||
select,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Sorting by likes, newest, or oldest
|
// Sorting by likes, newest, or oldest
|
||||||
let orderBy: Prisma.MiiOrderByWithRelationInput[];
|
let orderBy: Prisma.MiiOrderByWithRelationInput[];
|
||||||
|
|
||||||
|
|
@ -163,7 +131,6 @@ export default async function MiiList({ searchParams, userId, parentPage }: Prop
|
||||||
take: limit,
|
take: limit,
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
|
||||||
|
|
||||||
const lastPage = Math.ceil(totalCount / limit);
|
const lastPage = Math.ceil(totalCount / limit);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import { useTransition } from "react";
|
||||||
import { useSelect } from "downshift";
|
import { useSelect } from "downshift";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
|
|
||||||
type Sort = "likes" | "newest" | "oldest" | "random";
|
type Sort = "likes" | "newest" | "oldest";
|
||||||
|
|
||||||
const items = ["likes", "newest", "oldest", "random"];
|
const items = ["likes", "newest", "oldest"];
|
||||||
|
|
||||||
export default function SortSelect() {
|
export default function SortSelect() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -26,10 +26,6 @@ export default function SortSelect() {
|
||||||
params.set("page", "1");
|
params.set("page", "1");
|
||||||
params.set("sort", selectedItem);
|
params.set("sort", selectedItem);
|
||||||
|
|
||||||
if (selectedItem == "random") {
|
|
||||||
params.set("seed", Math.floor(Math.random() * 1_000_000_000).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
router.push(`?${params.toString()}`, { scroll: false });
|
router.push(`?${params.toString()}`, { scroll: false });
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export const idSchema = z.coerce.number({ error: "ID must be a number" }).int({
|
||||||
|
|
||||||
export const searchSchema = z.object({
|
export const searchSchema = z.object({
|
||||||
q: querySchema.optional(),
|
q: querySchema.optional(),
|
||||||
sort: z.enum(["likes", "newest", "oldest", "random"], { error: "Sort must be either 'likes', 'newest', 'oldest', or 'random'" }).default("newest"),
|
sort: z.enum(["likes", "newest", "oldest"], { error: "Sort must be either 'likes', 'newest', or 'oldest'" }).default("newest"),
|
||||||
tags: z
|
tags: z
|
||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
|
|
@ -72,8 +72,6 @@ export const searchSchema = z.object({
|
||||||
.max(100, { error: "Limit cannot be more than 100" })
|
.max(100, { error: "Limit cannot be more than 100" })
|
||||||
.optional(),
|
.optional(),
|
||||||
page: z.coerce.number({ error: "Page must be a number" }).int({ error: "Page must be an integer" }).min(1, { error: "Page must be at least 1" }).optional(),
|
page: z.coerce.number({ error: "Page must be a number" }).int({ error: "Page must be an integer" }).min(1, { error: "Page must be at least 1" }).optional(),
|
||||||
// Random sort
|
|
||||||
seed: z.coerce.number({ error: "Seed must be a number" }).int({ error: "Seed must be an integer" }).optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const userNameSchema = z
|
export const userNameSchema = z
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue