mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-14 23:26:15 -05:00
Fix adding long tier lists as user page widget
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
getNextNthForItem,
|
||||
tierListItemId,
|
||||
tierListMakerPathWithState,
|
||||
tierListSearchParamsHaveItems,
|
||||
} from "./tier-list-maker-utils";
|
||||
|
||||
function makeState(
|
||||
@@ -153,3 +154,42 @@ describe("tierListItemId", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tierListSearchParamsHaveItems", () => {
|
||||
function searchParamsFor(state: TierListState) {
|
||||
return tierListMakerPathWithState({
|
||||
state,
|
||||
title: "Weapons ranked",
|
||||
showTierHeaders: true,
|
||||
}).split("?")[1];
|
||||
}
|
||||
|
||||
test("accepts a tier list that has items", () => {
|
||||
expect(
|
||||
tierListSearchParamsHaveItems(
|
||||
searchParamsFor(makeState({ "tier-a": [splattershot] })),
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects a state param cut short, as a too long URL pasted into a maxLength input is", () => {
|
||||
const params = new URLSearchParams(
|
||||
searchParamsFor(makeState({ "tier-a": [splattershot] })),
|
||||
);
|
||||
const state = params.get(TIER_LIST_SEARCH_PARAM_NAMES.STATE)!;
|
||||
params.set(
|
||||
TIER_LIST_SEARCH_PARAM_NAMES.STATE,
|
||||
state.slice(0, Math.floor(state.length / 2)),
|
||||
);
|
||||
|
||||
expect(tierListSearchParamsHaveItems(params.toString())).toBe(false);
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ why: "no state param at all", searchParams: "title=Weapons+ranked" },
|
||||
{ why: "state param is not decodable", searchParams: "state=notATierList" },
|
||||
{ why: "every tier is empty", searchParams: searchParamsFor(makeState()) },
|
||||
])("rejects when $why", ({ searchParams }) => {
|
||||
expect(tierListSearchParamsHaveItems(searchParams)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,6 +27,14 @@ export function tierListMakerPathWithState({
|
||||
});
|
||||
}
|
||||
|
||||
export function tierListSearchParamsHaveItems(searchParams: string) {
|
||||
const { state } = tierListMakerSearchParams.parse(
|
||||
new URLSearchParams(searchParams),
|
||||
);
|
||||
|
||||
return Array.from(state.tierItems.values()).some((items) => items.length > 0);
|
||||
}
|
||||
|
||||
/** State with the item appended to the tier; unchanged if the tier does not exist. */
|
||||
export function addItemToTier(
|
||||
state: TierListState,
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as v from "valibot";
|
||||
import { ART_SOURCES } from "~/features/art/art-types";
|
||||
import { BADGE } from "~/features/badges/badges-constants";
|
||||
import { TIMEZONES } from "~/features/lfg/lfg-constants";
|
||||
import { tierListSearchParamsHaveItems } from "~/features/tier-list-maker/tier-list-maker-utils";
|
||||
import {
|
||||
array,
|
||||
badges,
|
||||
@@ -152,8 +153,13 @@ export const tierListSchema = v.object({
|
||||
searchParams: textField({
|
||||
label: "labels.tierListUrl",
|
||||
leftAddon: "/tier-list-maker?",
|
||||
maxLength: 500,
|
||||
maxLength: USER.TIER_LIST_WIDGET_MAX_LENGTH,
|
||||
transformValue: pastedTierListUrlToSearchParams,
|
||||
validate: {
|
||||
func: (value) =>
|
||||
tierListSearchParamsHaveItems(pastedTierListUrlToSearchParams(value)),
|
||||
message: "forms:errors.tierListUrlIncomplete",
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export const USER = {
|
||||
WEAPON_POOL_WIDGET_MAX: 7,
|
||||
COUNTDOWN_TITLE_MAX_LENGTH: 50,
|
||||
MARKDOWN_WIDGET_MAX_LENGTH: 2000,
|
||||
TIER_LIST_WIDGET_MAX_LENGTH: 4000,
|
||||
PEAK_XP_MIN: 1000,
|
||||
PEAK_XP_MAX: 6000,
|
||||
};
|
||||
|
||||
5
changelog/2026-09-14-tier-list-widget-url-truncated.md
Normal file
5
changelog/2026-09-14-tier-list-widget-url-truncated.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
navItem: [u, tier-list-maker]
|
||||
type: bug
|
||||
---
|
||||
Fixed long tier list URLs getting cut off when added as a tier list widget, which made the widget open an empty tier list
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "Must be a whole number (no decimals)",
|
||||
"errors.matchNotFound": "No SendouQ match found with this ID",
|
||||
"errors.invalidUrl": "Must be a valid URL",
|
||||
"errors.tierListUrlIncomplete": "Tier list URL is incomplete or the tier list is empty",
|
||||
"errors.imageTooLarge": "Image is too large. Try one with a smaller file size.",
|
||||
"errors.invalidTime": "Must be a valid time, e.g. 18:30",
|
||||
"errors.timeRangeIncomplete": "Both a start and an end time are needed",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "Debe ser un número entero (sin decimales)",
|
||||
"errors.matchNotFound": "No se ha encontrado ninguna partida de SendouQ con esta ID",
|
||||
"errors.invalidUrl": "Debe ser una URL válida",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "La imagen es demasiado grande. Prueba con un archivo más pequeño.",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "Debe ser un número entero (sin decimales)",
|
||||
"errors.matchNotFound": "No se ha encontrado ninguna partida de SendouQ con esta ID",
|
||||
"errors.invalidUrl": "Debe ser una URL válida",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "La imagen es demasiado grande. Prueba con un archivo más pequeño.",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
"errors.mustBeWholeNumber": "",
|
||||
"errors.matchNotFound": "",
|
||||
"errors.invalidUrl": "请输入有效的 URL 地址",
|
||||
"errors.tierListUrlIncomplete": "",
|
||||
"errors.imageTooLarge": "",
|
||||
"errors.invalidTime": "",
|
||||
"errors.timeRangeIncomplete": "",
|
||||
|
||||
Reference in New Issue
Block a user