feat: release version 1.0.7
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
export type SongSort = 'title' | 'difficulty-asc' | 'difficulty-desc';
|
||||
|
||||
export type SongChartSummary = {
|
||||
songId: string;
|
||||
title: string;
|
||||
difficulty: string;
|
||||
difficultyLevel?: number | null;
|
||||
scoreCalibrationSource?: 'measured' | 'local-estimated-v1' | string;
|
||||
};
|
||||
|
||||
export type SongOption = {
|
||||
id: string;
|
||||
title: string;
|
||||
difficultyLevel: number | null;
|
||||
};
|
||||
|
||||
const englishTitleCollator = new Intl.Collator('en', {
|
||||
sensitivity: 'base',
|
||||
numeric: true
|
||||
});
|
||||
|
||||
function normalizedSearch(value: string): string {
|
||||
return value.normalize('NFKD').toLocaleLowerCase('en').replace(/[^a-z0-9]+/g, ' ').trim();
|
||||
}
|
||||
|
||||
export function songOptions(
|
||||
charts: readonly SongChartSummary[],
|
||||
difficulty: string,
|
||||
query = '',
|
||||
sort: SongSort = 'title'
|
||||
): SongOption[] {
|
||||
const levelBySongId = new Map(charts
|
||||
.filter((chart) => chart.difficulty === difficulty)
|
||||
.map((chart) => [chart.songId, chart.difficultyLevel ?? null]));
|
||||
const options = Array.from(new Map(charts.map((chart) => [chart.songId, {
|
||||
id: chart.songId,
|
||||
title: chart.title,
|
||||
difficultyLevel: levelBySongId.get(chart.songId) ?? null
|
||||
}])).values());
|
||||
const search = normalizedSearch(query);
|
||||
const filtered = search
|
||||
? options.filter((song) => normalizedSearch(`${song.title} ${song.id}`).includes(search))
|
||||
: options;
|
||||
const titleOrder = (left: SongOption, right: SongOption) =>
|
||||
englishTitleCollator.compare(left.title, right.title) || left.id.localeCompare(right.id);
|
||||
|
||||
return filtered.sort((left, right) => {
|
||||
if (sort === 'title') return titleOrder(left, right);
|
||||
if (left.difficultyLevel === null) return right.difficultyLevel === null ? titleOrder(left, right) : 1;
|
||||
if (right.difficultyLevel === null) return -1;
|
||||
const leftLevel = left.difficultyLevel;
|
||||
const rightLevel = right.difficultyLevel;
|
||||
const levelOrder = sort === 'difficulty-desc' ? rightLevel - leftLevel : leftLevel - rightLevel;
|
||||
return levelOrder || titleOrder(left, right);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user