add all translations

This commit is contained in:
MathieuG-P
2022-12-11 23:11:23 +01:00
parent 6b724d8040
commit 055d8b2bcc
9 changed files with 323 additions and 46 deletions
+113 -1
View File
@@ -5,6 +5,7 @@
"launch": "Launch",
"mods": "Mods",
"maps": "Maps",
"playlists":"Playlists",
"cancel": "Cancel",
"delete": "Delete"
},
@@ -15,6 +16,32 @@
"desktop": "Desktop Mod",
"debug": "Debug Mod"
},
"maps":{
"search-bar":{
"search-placeholder": "Search a map",
"filters-btn":"Filters",
"dropdown":{
"export-maps": "Export maps",
"delete-maps": "Delete maps"
}
},
"tabs":{
"maps":{
"actions":{
"add-maps":{
"text": "Add"
},
"link-maps":{
"tooltips":{
"link": "Link maps",
"unlink": "Unling maps"
}
}
}
}
}
},
"mods":{
"loading-mods": "Loading mods...",
"buttons":{
@@ -390,8 +417,93 @@
},
"valid-btn":"Unlink maps"
}
},
"download-maps":{
"search-btn": "Search",
"loading-maps": "Loading maps..."
}
},
},
"maps":{
"map-filter-panel":{
"duration": "Duration",
"tags": "tags",
"specificities": "general",
"requirements": "requirements"
},
"map-types":{
"accuracy": "accuracy",
"balanced": "balanced",
"challenge": "challenge",
"dancestyle": "dance",
"fitness": "fitness",
"speed": "speed",
"tech": "tech"
},
"map-styles":{
"dance": "dance",
"swing": "swing",
"nightcore": "nightcore",
"folk": "folk",
"family": "family",
"ambient": "ambient",
"funk": "funk",
"jazz": "jazz",
"soul": "soul",
"speedcore": "speedcore",
"punk": "punk",
"rb": "r&b",
"holiday": "holiday",
"vocaloid": "vocaloid",
"jrock": "j-rock",
"trance": "trance",
"drumbass": "drum & bass",
"comedy": "comedy",
"instrumental": "instrumental",
"hardcore": "hardcore",
"kpop": "k-pop",
"indie": "indie",
"techno": "techno",
"house": "house",
"game": "video game",
"film": "film",
"alt": "alternative",
"dubstep": "dubstep",
"metal": "metal",
"anime": "anime",
"hiphop": "hiphop",
"jpop": "j-pop",
"rock": "rock",
"pop": "pop",
"electronic": "electronic",
"classical-orchestral": "Classical & Orchestral"
},
"map-specificities":{
"automapper": "AI",
"ranked": "ranked",
"curated": "curated",
"verified": "verified",
"fullSpread": "full spread"
},
"difficulties":{
"Easy": "easy",
"Normal": "normal",
"Hard": "hard",
"Expert": "expert",
"ExpertPlus": "expert+"
},
"map-item":{
"by": "By {songAutor}",
"mapped-by":"mapped by"
}
},
"beat-saver":{
"maps-sorts":{
"Latest": "Latest",
"Relevance": "Relevance",
"Rating": "Rating",
"Curated": "Curated"
}
},
"auto-update":{
"checking": "Checking for updates",
"downloading": "Downloading updates"
+114 -2
View File
@@ -4,7 +4,8 @@
"verify": "Verificar",
"launch": "Lanzar",
"mods": "Mods",
"maps": "Maps",
"maps": "Mapas",
"playlists":"Playlists",
"cancel": "Cancelar",
"delete": "Borrar"
},
@@ -15,6 +16,32 @@
"desktop": "Desktop Mod",
"debug": "Debug Mod"
},
"maps":{
"search-bar":{
"search-placeholder": "Buscar en un mapa",
"filters-btn":"Filtros",
"dropdown":{
"export-maps": "Exportar mapas",
"delete-maps": "Borrar mapas"
}
},
"tabs":{
"maps":{
"actions":{
"add-maps":{
"text": "Añadir"
},
"link-maps":{
"tooltips":{
"link": "Vincular los mapas",
"unlink": "Desatar los mapas"
}
}
}
}
}
},
"mods":{
"loading-mods": "Cargando mods...",
"buttons":{
@@ -391,8 +418,93 @@
},
"valid-btn":"Desvincular mapas"
}
},
"download-maps":{
"search-btn": "buscar",
"loading-maps": "Cargando mapas..."
}
},
},
"maps":{
"map-filter-panel":{
"duration": "Duración",
"tags": "tags",
"specificities": "general",
"requirements": "requisitos"
},
"map-types":{
"accuracy": "precisión",
"balanced": "equilibrado",
"challenge": "desafío",
"dancestyle": "baile",
"fitness": "fitness",
"speed": "speed",
"tech": "tec"
},
"map-styles":{
"dance": "baile",
"swing": "swing",
"nightcore": "nightcore",
"folk": "folk",
"family": "familia",
"ambient": "ambiente",
"funk": "funk",
"jazz": "jazz",
"soul": "soul",
"speedcore": "speedcore",
"punk": "punk",
"rb": "r&b",
"holiday": "vacaciones",
"vocaloid": "vocaloid",
"jrock": "j-rock",
"trance": "trance",
"drumbass": "drum & bass",
"comedy": "comedia",
"instrumental": "instrumental",
"hardcore": "hardcore",
"kpop": "k-pop",
"indie": "indie",
"techno": "tecno",
"house": "house",
"game": "videojuego",
"film": "film",
"alt": "alternativa",
"dubstep": "dubstep",
"metal": "metal",
"anime": "anime",
"hiphop": "hiphop",
"jpop": "j-pop",
"rock": "rock",
"pop": "pop",
"electronic": "electrónico",
"classical-orchestral": "Clásico y orquestal"
},
"map-specificities":{
"automapper": "IA",
"ranked": "ranked",
"curated": "recomendado",
"verified": "verificado",
"fullSpread": "panel completo"
},
"difficulties":{
"Easy": "fácil",
"Normal": "normal",
"Hard": "difícil",
"Expert": "experto",
"ExpertPlus": "experto+"
},
"map-item":{
"by": "Por {songAutor}",
"mapped-by":"mapeado por"
}
},
"beat-saver":{
"maps-sorts":{
"Latest": "Última",
"Relevance": "Relevancia",
"Rating": "Notas",
"Curated": "Recomendado"
}
},
"auto-update":{
"checking": "Comprobar las actualizaciones",
"downloading": "Descargar actualizaciones"
+45 -9
View File
@@ -5,6 +5,7 @@
"launch": "Lancer",
"mods": "Mods",
"maps": "Maps",
"playlists":"Playlists",
"cancel": "Annuler",
"delete": "Supprimer"
},
@@ -24,8 +25,21 @@
"delete-maps": "Supprimer les maps"
}
},
"maps-panel":{
"tabs":{
"maps":{
"actions":{
"add-maps":{
"text": "Ajouter"
},
"link-maps":{
"tooltips":{
"link": "Lier les maps",
"unlink": "Délier les maps"
}
}
}
}
}
},
"mods":{
@@ -403,9 +417,13 @@
},
"valid-btn":"délier les maps"
}
},
"download-maps":{
"search-btn": "Rechercher",
"loading-maps": "Chargement des maps..."
}
},
"maps":{
},
"maps":{
"map-filter-panel":{
"duration": "Durée",
"tags": "tags",
@@ -425,8 +443,8 @@
"dance": "dance",
"swing": "swing",
"nightcore": "nightcore",
"folk": "Folk",
"family": "Famille",
"folk": "folk",
"family": "famille",
"ambient": "ambiante",
"funk": "funk",
"jazz": "jazz",
@@ -460,14 +478,32 @@
"classical-orchestral": "Classique & Orchestral"
},
"map-specificities":{
"automapper": "ia",
"automapper": "IA",
"ranked": "classée",
"curated": "recommandée",
"verified": "vérifiée",
"fullSpread": "panel complet"
},
"difficulties":{
"Easy": "facile",
"Normal": "normal",
"Hard": "difficile",
"Expert": "expert",
"ExpertPlus": "expert+"
},
"map-item":{
"by": "Par {songAutor}",
"mapped-by":"mappée par"
}
},
},
"beat-saver":{
"maps-sorts":{
"Latest": "Dernière",
"Relevance": "Pertinence",
"Rating": "Notes",
"Curated": "Recommandée"
}
},
"auto-update":{
"checking": "Vérification des mises à jour",
"downloading": "Téléchargement des mises à jour"
@@ -4,13 +4,13 @@ import { MutableRefObject} from "react"
import { MAP_TYPES } from "renderer/partials/maps/map-tags/map-types"
import { MAP_STYLES } from "renderer/partials/maps/map-tags/map-styles"
import { BsmCheckbox } from "../shared/bsm-checkbox.component"
import { diffColors } from "./map-item.component"
import { min_to_s } from "renderer/helpers/time-utils"
import dateFormat from "dateformat"
import { BsmRange } from "../shared/bsm-range.component"
import { useTranslation } from "renderer/hooks/use-translation.hook"
import { MAP_SPECIFICITIES } from "renderer/partials/maps/map-general/map-specificity"
import { MAP_REQUIREMENTS } from "renderer/partials/maps/map-requirements/map-requirements"
import { MAP_DIFFICULTIES_COLORS } from "renderer/partials/maps/map-difficulties/map-difficulties-colors"
export type Props = {
className?: string,
@@ -136,11 +136,11 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange}
return !playlist ? (
<motion.div ref={ref} className={className} initial={{opacity: 0}} animate={{opacity: 1}} exit={{opacity: 0}}>
<div className="w-full h-6 grid grid-cols-2 gap-x-10 px-4 mb-6 pt-2">
<div className="w-full h-6 grid grid-cols-2 gap-x-12 px-4 mb-6 pt-2">
<BsmRange min={MIN_NPS} max={MAX_NPS} values={npss} onChange={onNpssChange} renderLabel={renderNpsLabel} step={.1}/>
<BsmRange min={MIN_DURATION} max={MAX_DURATION} values={durations} onChange={onDurationsChange} renderLabel={renderDurationLabel} step={5}/>
</div>
<div className="w-full h-full flex gap-x-2"> {/* TODO TRADUIRE */}
<div className="w-full h-full flex gap-x-2">
<section className="shrink-0">
<h2 className="mb-1 uppercase text-sm">{t("maps.map-filter-panel.specificities")}</h2>
@@ -164,12 +164,12 @@ export function FilterPanel({className, ref, playlist = false, filter, onChange}
<h2 className="uppercase text-sm mb-1">{t("maps.map-filter-panel.tags")}</h2>
<div className="w-full flex flex-row flex-wrap items-start justify-start content-start gap-1 mb-2">
{MAP_TYPES.map(tag => (
<span key={tag} onClick={() => handleTagClick(tag)} className={`text-[12.5px] text-black rounded-md px-1 font-bold cursor-pointer ${(!isTagActivated(tag)) && "opacity-40 hover:opacity-90"}`} style={{backgroundColor: isTagExcluded(tag) ? diffColors.Expert : diffColors.Normal}}>{translateMapType(tag)}</span>
<span key={tag} onClick={() => handleTagClick(tag)} className={`text-[12.5px] text-black rounded-md px-1 font-bold cursor-pointer ${(!isTagActivated(tag)) && "opacity-40 hover:opacity-90"}`} style={{backgroundColor: isTagExcluded(tag) ? MAP_DIFFICULTIES_COLORS.Expert : MAP_DIFFICULTIES_COLORS.Normal}}>{translateMapType(tag)}</span>
))}
</div>
<div className="w-full flex flex-row flex-wrap items-start justify-start content-start gap-1">
{MAP_STYLES.map(tag => (
<span key={tag} onClick={() => handleTagClick(tag)} className={`text-[12.5px] text-black rounded-md px-1 font-bold cursor-pointer ${(!isTagActivated(tag)) && "opacity-40 hover:opacity-90"}`} style={{backgroundColor: isTagExcluded(tag) ? diffColors.Expert : diffColors.Easy}}>{translateMapStyle(tag)}</span>
<span key={tag} onClick={() => handleTagClick(tag)} className={`text-[12.5px] text-black rounded-md px-1 font-bold cursor-pointer ${(!isTagActivated(tag)) && "opacity-40 hover:opacity-90"}`} style={{backgroundColor: isTagExcluded(tag) ? MAP_DIFFICULTIES_COLORS.Expert : MAP_DIFFICULTIES_COLORS.Easy}}>{translateMapStyle(tag)}</span>
))}
</div>
@@ -17,6 +17,9 @@ import equal from "fast-deep-equal/es6";
import { getMapZipUrlFromHash } from "renderer/helpers/maps-utils";
import { BsmBasicSpinner } from "../shared/bsm-basic-spinner/bsm-basic-spinner.component";
import defaultImage from '../../../../assets/images/default-version-img.jpg'
import { useTranslation } from "renderer/hooks/use-translation.hook";
import { MAP_DIFFICULTIES } from "renderer/partials/maps/map-difficulties/map-difficulties";
import { MAP_DIFFICULTIES_COLORS } from "renderer/partials/maps/map-difficulties/map-difficulties-colors"
export type ParsedMapDiff = {type: BsvMapDifficultyType, name: string, stars: number}
@@ -51,6 +54,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
const audioPlayer = AudioPlayerService.getInstance();
const color = useThemeColor("first-color");
const t = useTranslation();
const [hovered, setHovered] = useState(false);
const [bottomBarHovered, setBottomBarHovered, cancelBottomBarHovered] = useDelayedState(false);
@@ -73,7 +77,9 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
})();
const parseDiffLabel = (diffLabel: string) => {
if(diffLabel === "ExpertPlus"){ return "Expert+" }
if(MAP_DIFFICULTIES.includes(diffLabel as BsvMapDifficultyType)){
return t(`maps.difficulties.${diffLabel}`);
}
return diffLabel;
}
@@ -115,7 +121,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
<BsmIcon className="h-4 w-4 mr-px" icon="bsMapDifficulty"/>
<div className="flex py-[2px] gap-[1px] h-full">
{diffSet.map(diff => (
<span key={diff.type} className="h-full w-[6px] rounded-full" style={{backgroundColor: diffColors[diff.type]}}/>
<span key={diff.type} className="h-full w-[6px] rounded-full" style={{backgroundColor: MAP_DIFFICULTIES_COLORS[diff.type]}}/>
))}
</div>
</>
@@ -142,16 +148,16 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
{diffSet.map(({type, name, stars}) => (
<li key={`${type}${name}${stars}`} className="w-full h-4 flex items-center gap-1">
<BsmIcon className="h-full w-fit p-px" icon={charac}/>
<span className="h-full px-2 flex items-center text-xs font-bold bg-current rounded-full" style={{color: diffColors[type]}}>
<span className="h-full px-2 flex items-center text-xs font-bold bg-current rounded-full" style={{color: MAP_DIFFICULTIES_COLORS[type]}}>
{
stars ? (
<span className="h-full block brightness-[.25]"> {stars}</span>
) : (
<span className="h-full brightness-[.25] leading-4 pb-[2px]">{parseDiffLabel(type)}</span>
<span className="h-full brightness-[.25] leading-4 pb-[2px] capitalize">{parseDiffLabel(type)}</span>
)
}
</span>
<span className="text-sm leading-4 pb-[2px]">{parseDiffLabel(name)}</span>
<span className="text-sm leading-4 pb-[2px] capitalize">{parseDiffLabel(name)}</span>
</li>
))}
</ol>
@@ -170,8 +176,8 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
<BsmImage className="absolute top-0 left-0 w-full h-full -z-[1] object-cover" image={coverUrl} placeholder={defaultImage} errorImage={defaultImage} loading="lazy"/>
<div className="pt-1 pl-2 pr-7 top-0 left-0 w-full h-full bg-gray-600 bg-opacity-80 flex flex-col justify-between group-hover:bg-main-color-1 group-hover:bg-opacity-80">
<h1 className="font-bold whitespace-nowrap text-ellipsis overflow-hidden w-full leading-5 tracking-wide text-lg" title={title}><BsmLink className="hover:underline" href={mapUrl}>{title}</BsmLink></h1>
<h2 className="font-bold whitespace-nowrap text-ellipsis overflow-hidden w-full text-sm mb-[3px]">par {songAutor}</h2>
<h3 className="font-bold whitespace-nowrap text-ellipsis overflow-hidden w-full text-xs">{autor && (<> mappée par <BsmLink href={authorUrl} className="brightness-150 hover:underline" style={{color}}>{autor}</BsmLink></>)}</h3>
<h2 className="font-bold whitespace-nowrap text-ellipsis overflow-hidden w-full text-sm mb-[3px]">{songAutor && t("maps.map-item.by", {songAutor})}</h2>
<h3 className="font-bold whitespace-nowrap text-ellipsis overflow-hidden w-full text-xs">{autor && (<> {t("maps.map-item.mapped-by")} <BsmLink href={authorUrl} className="brightness-150 hover:underline" style={{color}}>{autor}</BsmLink></>)}</h3>
<div className="w-full h-4 text-xs gap-2 flex opacity-0 group-hover:opacity-100">
{likesText && (
<div className="h-full flex items-center">
@@ -195,7 +201,7 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
<motion.div className="w-full h-5 pb-1 pr-7 flex items-center gap-1" onHoverStart={bottomBarHoverStart} onHoverEnd={bottomBarHoverEnd}>
{ranked && (
<div className="text-yellow-300 bg-current rounded-full px-1 h-full flex items-center justify-center">
<span className="uppercase text-xs font-bold tracking-wide brightness-[.25]">classée</span>
<span className="uppercase text-xs font-bold tracking-wide brightness-[.25]">{t("maps.map-specificities.ranked")}</span>
</div>
)}
<div className="h-full grow flex items-start content-start">
@@ -225,11 +231,3 @@ export const MapItem = memo(({hash, title, autor, songAutor, coverUrl, songUrl,
function areEqual(prevProps: MapItemProps, nextProps: MapItemProps): boolean {
return equal(prevProps, nextProps);
}
export const diffColors: Record<BsvMapDifficultyType, string> = {
Easy: "#00FF9E",
Normal: "#00FFFF",
Hard: "#FFA700",
Expert: "#FF4319",
ExpertPlus: "#FF7EFF"
}
@@ -5,7 +5,6 @@ import { LocalMapsListPanel } from "./local-maps-list-panel.component"
import { BsmDropdownButton, DropDownItem } from "../shared/bsm-dropdown-button.component"
import { FilterPanel } from "./filter-panel.component"
import { MapFilter } from "shared/models/maps/beat-saver.model"
import { BsmButton } from "../shared/bsm-button.component"
import { useThemeColor } from "renderer/hooks/use-theme-color.hook"
import { MapsManagerService } from "renderer/services/maps-manager.service"
import { motion, Variants } from "framer-motion";
@@ -88,11 +87,11 @@ export function MapsPlaylistsPanel({version}: Props) {
<motion.div className="h-full p-0.5" variants={variants}>
<BsmIcon className="block h-full aspect-square brightness-150" icon="add"/>
</motion.div>
<span className="text-sm brightness-150">Ajouter</span>
<span className="text-sm brightness-150">{t("pages.version-viewer.maps.tabs.maps.actions.add-maps.text")}</span>
</motion.div>
)}
{(!!version) && (
<motion.div variants={variants} whileHover="hover" whileTap="tap" initial={{rotate: 0}} className="block p-0.5 h-[calc(100%-5px)] aspect-square blur-0 hover:brightness-75" title={mapsLinked ? "Délier les maps" : "Lier les maps"} onClick={e => {e.stopPropagation(); onClickLink(index)}}>
<motion.div variants={variants} whileHover="hover" whileTap="tap" initial={{rotate: 0}} className="block p-0.5 h-[calc(100%-5px)] aspect-square blur-0 hover:brightness-75" title={t(mapsLinked ? "pages.version-viewer.maps.tabs.maps.actions.link-maps.tooltips.unlink" : "pages.version-viewer.maps.tabs.maps.actions.link-maps.tooltips.link")} onClick={e => {e.stopPropagation(); onClickLink(index)}}>
<span className="absolute top-0 left-0 h-full w-full rounded-full opacity-20" style={{backgroundColor: linkedColor}}/>
<BsmIcon className="p-1 absolute top-0 left-0 h-full w-full !bg-transparent -rotate-45 brightness-150" icon={mapsLinked ? "link" : "unlink"} style={{color: linkedColor}} />
</motion.div>
@@ -119,7 +118,7 @@ export function MapsPlaylistsPanel({version}: Props) {
return (
<div className="w-full h-full flex flex-col items-center justify-center">
<nav className="w-full shrink-0 flex h-[35px] justify-center px-40 gap-2 mb-3">
<nav className="w-full shrink-0 flex h-9 justify-center px-40 gap-2 mb-3">
<div className="h-full rounded-full bg-main-color-2 grow p-[6px]">
<input type="text" className="h-full w-full bg-main-color-1 rounded-full px-2" placeholder={t("pages.version-viewer.maps.search-bar.search-placeholder")} value={tabIndex === 0 ? mapSearch : playlistSearch} onChange={e => handleSearch(e.target.value)}/>
</div>
@@ -129,7 +128,7 @@ export function MapsPlaylistsPanel({version}: Props) {
<BsmDropdownButton className="h-full flex aspect-square relative rounded-full z-[1] bg-main-color-3" buttonClassName="rounded-full h-full w-full p-[6px]" icon="three-dots" withBar={false} items={dropDownItems} menuTranslationY="6px" align="center"/>
</nav>
<div className="w-full h-full flex flex-col bg-main-color-2 rounded-md shadow-black shadow-md overflow-hidden">
<TabNavBar className="!rounded-none shadow-sm" tabsText={["misc.maps", "Playlists"]} onTabChange={setTabIndex} renderTab={renderTab}/>
<TabNavBar className="!rounded-none shadow-sm" tabsText={["misc.maps", "misc.playlists"]} onTabChange={setTabIndex} renderTab={renderTab}/>
<div className="w-full grow min-h-0 flex flex-row items-center transition-transform duration-300" style={{transform: `translate(${-(tabIndex * 100)}%, 0)`}}>
<LocalMapsListPanel ref={mapsRef} className="w-full h-full shrink-0 flex flex-col" version={version} filter={mapFilter} search={mapSearch}/>
<div className="w-full h-full shrink-0 flex flex-col justify-center items-center content-center gap-2 overflow-hidden">
@@ -1,5 +1,5 @@
import { motion } from "framer-motion";
import { Fragment, useCallback, useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { FilterPanel } from "renderer/components/maps-mangement-components/filter-panel.component";
import { MapItem, ParsedMapDiff } from "renderer/components/maps-mangement-components/map-item.component";
import { BsmButton } from "renderer/components/shared/bsm-button.component";
@@ -16,6 +16,7 @@ import { BsvMapCharacteristic, BsvMapDetail, MapFilter, SearchOrder, SearchParam
import BeatWaitingImg from "../../../../../assets/images/apngs/beat-waiting.png";
import equal from "fast-deep-equal/es6";
import { ProgressBarService } from "renderer/services/progress-bar.service";
import { useTranslation } from "renderer/hooks/use-translation.hook";
export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
@@ -26,6 +27,7 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
const currentDownload = useObservable(mapsDownloader.currentMapDownload$);
const mapsInQueue = useObservable(mapsDownloader.mapsInQueue$);
const t = useTranslation();
const [filter, setFilter] = useState<MapFilter>({});
const [query, setQuery] = useState("");
const [maps, setMaps] = useState<BsvMapDetail[]>([]);
@@ -41,7 +43,7 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
const loaderRef = useRef(null);
const sortOptions: BsmSelectOption[] = (() => {
return BSV_SORT_ORDER.map(sort => ({text: sort, value: sort}));
return BSV_SORT_ORDER.map(sort => ({text: `beat-saver.maps-sorts.${sort}`, value: sort}));
})();
useEffect(() => {
@@ -152,19 +154,19 @@ export const DownloadMapsModal: ModalComponent<void, BSVersion> = ({data}) => {
return (
<form className="text-gray-800 dark:text-gray-200 flex flex-col max-w-[95vw] w-[970px] h-[85vh] gap-3" onSubmit={e => {e.preventDefault(); handleSearch()}}>
<div className="flex h-8 gap-2 shrink-0">
<BsmDropdownButton className="shrink-0 h-full relative z-[1] flex justify-start" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1 !bg-main-color-1" icon="search" text="Filtres" withBar={false}>
<div className="flex h-9 gap-2 shrink-0">
<BsmDropdownButton className="shrink-0 h-full relative z-[1] flex justify-start" buttonClassName="flex items-center justify-center h-full rounded-full px-2 py-1 !bg-main-color-1" icon="search" text="pages.version-viewer.maps.search-bar.filters-btn" withBar={false}>
<FilterPanel className="absolute top-[calc(100%+3px)] bg-main-color-3 origin-top w-[450px] h-fit p-2 rounded-md shadow-md shadow-black" filter={filter} onChange={setFilter}/>
</BsmDropdownButton>
<input className="h-full bg-main-color-1 rounded-full px-2 grow pb-0.5" type="text" name="" id="" placeholder="Rechercher une map" value={query} onChange={e => setQuery(e.target.value)}/>
<BsmButton className="shrink-0 rounded-full py-1 px-3 !bg-main-color-1 flex justify-center items-center" icon="search" text="Rechercher" withBar={false} onClick={e => {e.preventDefault(); handleSearch()}}/>
<BsmSelect className="bg-main-color-1 rounded-full px-2 pb-0.5" options={sortOptions} onChange={handleSortChange}/>
<input className="h-full bg-main-color-1 rounded-full px-2 grow pb-0.5" type="text" name="" id="" placeholder={t("pages.version-viewer.maps.search-bar.search-placeholder")} value={query} onChange={e => setQuery(e.target.value)}/>
<BsmButton className="shrink-0 rounded-full py-1 px-3 !bg-main-color-1 flex justify-center items-center capitalize" icon="search" text="modals.download-maps.search-btn" withBar={false} onClick={e => {e.preventDefault(); handleSearch()}}/>
<BsmSelect className="bg-main-color-1 rounded-full px-1 pb-0.5 text-center" options={sortOptions} onChange={handleSortChange}/>
</div>
<ul className="w-full grow flex content-start flex-wrap gap-2 px-2 overflow-y-scroll overflow-x-hidden scrollbar-thin scrollbar-thumb-rounded-full scrollbar-thumb-neutral-900" >
{maps.length === 0 ? (
<div className="w-full h-full flex flex-col items-center justify-center">
<img className="w-32 h-32 spin-loading" src={BeatWaitingImg}></img>
<span className="text-lg">Chargement des maps...</span> {/* TODO TRANSLATE */}
<span className="text-lg">{t("modals.download-maps.loading-maps")}</span>
</div>
) : (
<>
@@ -0,0 +1,9 @@
import { BsvMapDifficultyType } from "shared/models/maps/beat-saver.model";
export const MAP_DIFFICULTIES_COLORS: Record<BsvMapDifficultyType, string> = {
Easy: "#00FF9E",
Normal: "#00FFFF",
Hard: "#FFA700",
Expert: "#FF4319",
ExpertPlus: "#FF7EFF"
}
@@ -0,0 +1,9 @@
import { BsvMapDifficultyType } from "shared/models/maps/beat-saver.model";
export const MAP_DIFFICULTIES: BsvMapDifficultyType[] = [
"Easy",
"Normal",
"Hard",
"Expert",
"ExpertPlus"
];