38 lines
1.6 KiB
TypeScript
38 lines
1.6 KiB
TypeScript
import type { MediaAsset, MediaRole } from "./api";
|
||
|
||
const mediaRoleLabels: Record<MediaRole, string> = {
|
||
waterbody_cover: "Заставка водоёма",
|
||
waterbody_map: "Карта водоёма",
|
||
waterbody_depth_map: "Карта глубин",
|
||
waterbody_screenshot: "Скриншот водоёма",
|
||
tackle_card: "Карточка снасти",
|
||
tackle_detail: "Деталь снасти",
|
||
rig_diagram: "Схема монтажа",
|
||
tackle_screenshot: "Скриншот снасти",
|
||
};
|
||
|
||
export const mediaRoleLabel = (role: string): string => mediaRoleLabels[role as MediaRole] ?? role;
|
||
|
||
const tokens = (value: string) => value
|
||
.toLocaleLowerCase("ru")
|
||
.replaceAll("ё", "е")
|
||
.replace(/^(оз\.|р\.)\s*/, "")
|
||
.replace(/[^a-zа-я0-9]+/giu, " ")
|
||
.trim()
|
||
.split(/\s+/)
|
||
.filter(Boolean);
|
||
|
||
export const findMediaByLabel = (assets: MediaAsset[], label: string, allowedRoles?: readonly MediaRole[]): MediaAsset | undefined => {
|
||
const filtered = allowedRoles ? assets.filter((asset) => asset.media_role && allowedRoles.includes(asset.media_role)) : assets;
|
||
const wanted = tokens(label);
|
||
const exact = filtered.filter((asset) => tokens(asset.label ?? "").join(" ") === wanted.join(" "));
|
||
if (exact.length === 1) return exact[0];
|
||
|
||
const wantedSet = new Set(wanted);
|
||
const candidates = filtered.filter((asset) => {
|
||
const available = new Set(tokens(asset.label ?? ""));
|
||
return wanted.every((token) => available.has(token)) || [...available].every((token) => wantedSet.has(token));
|
||
});
|
||
return candidates.length === 1 ? candidates[0] : undefined;
|
||
};
|