diff --git a/src/clients/i18n/commonText.ts b/src/clients/i18n/commonText.ts index 32751ff..253e5f7 100644 --- a/src/clients/i18n/commonText.ts +++ b/src/clients/i18n/commonText.ts @@ -1,6 +1,7 @@ import { fetchI18n } from './fetch.js' export type CommonTextI18n = { + music: string character: string rarity: string attribute: string diff --git a/src/sonolus/background/info.ts b/src/sonolus/background/info.ts index f91b317..0e503a2 100644 --- a/src/sonolus/background/info.ts +++ b/src/sonolus/background/info.ts @@ -6,9 +6,9 @@ import { hideSpoilers } from '../utils/spoiler.js' import { backgroundSearches } from './search.js' export const installBackgroundInfo = () => { - sonolus.background.infoHandler = ({ options }) => { + sonolus.background.infoHandler = ({ options: { spoilers } }) => { const cardBackgrounds = hideSpoilers( - options.spoilers, + spoilers[1], sonolus.background.items.filter( (item): item is BackgroundItemModel & { meta: object } => item.meta !== undefined, ), diff --git a/src/sonolus/background/list.ts b/src/sonolus/background/list.ts index 36e3304..cdf66ab 100644 --- a/src/sonolus/background/list.ts +++ b/src/sonolus/background/list.ts @@ -8,11 +8,11 @@ export const installBackgroundList = () => { sonolus.background.listHandler = ({ search: { type, options }, page, - options: serverOptions, + options: { spoilers }, }) => { const filteredBackgrounds = [ ...hideSpoilers( - serverOptions.spoilers, + spoilers[1], sonolus.background.items.filter( (item): item is BackgroundItemModel & { meta: object } => item.meta !== undefined, @@ -20,6 +20,7 @@ export const installBackgroundList = () => { ), ...sonolus.background.items.filter(({ meta }) => !meta), ] + if (type === 'quick') return { ...paginateItems(filterBackgrounds(filteredBackgrounds, options.keywords), page), diff --git a/src/sonolus/configuration/option.ts b/src/sonolus/configuration/option.ts index 606990c..67d7485 100644 --- a/src/sonolus/configuration/option.ts +++ b/src/sonolus/configuration/option.ts @@ -1,15 +1,19 @@ -import { ServerOptionsModel } from '@sonolus/express' +import { ServerMultiOptionValueModel, ServerOptionsModel } from '@sonolus/express' import { Repository } from '../../repository/index.js' export const configurationOptions = { spoilers: { name: {}, required: false, - type: 'toggle', - def: false, + type: 'multi', + values: [] as ServerMultiOptionValueModel[], }, } satisfies ServerOptionsModel export const updateConfigurationOptions = (repository: Repository) => { configurationOptions.spoilers.name = repository.commonTexts.spoilerContent + configurationOptions.spoilers.values = [ + { title: repository.commonTexts.music, def: false }, + { title: repository.commonTexts.card, def: false }, + ] } diff --git a/src/sonolus/level/info.ts b/src/sonolus/level/info.ts index 7f1621b..9d303ef 100644 --- a/src/sonolus/level/info.ts +++ b/src/sonolus/level/info.ts @@ -6,13 +6,13 @@ import { hideSpoilers } from '../utils/spoiler.js' import { levelSearches } from './search.js' export const installLevelInfo = () => { - sonolus.level.infoHandler = ({ options }) => { + sonolus.level.infoHandler = ({ options: { spoilers } }) => { const randomLevels: Record = {} const newestMusicIds = new Set() const newestLevels: LevelItemModel[] = [] - for (const level of hideSpoilers(options.spoilers, sonolus.level.items)) { + for (const level of hideSpoilers(spoilers[0], sonolus.level.items)) { randomLevels[`${level.meta.musicId}-${level.meta.musicVocalId}`] ??= level if (newestLevels.length >= 5) continue diff --git a/src/sonolus/level/list.ts b/src/sonolus/level/list.ts index 4f92184..494321c 100644 --- a/src/sonolus/level/list.ts +++ b/src/sonolus/level/list.ts @@ -5,8 +5,9 @@ import { hideSpoilers } from '../utils/spoiler.js' import { levelSearches } from './search.js' export const installLevelList = () => { - sonolus.level.listHandler = ({ search: { type, options }, page, options: serverOptions }) => { - const filteredLevels = hideSpoilers(serverOptions.spoilers, sonolus.level.items) + sonolus.level.listHandler = ({ search: { type, options }, page, options: { spoilers } }) => { + const filteredLevels = hideSpoilers(spoilers[0], sonolus.level.items) + if (type === 'quick') return { ...paginateItems(filterLevels(filteredLevels, options.keywords), page), diff --git a/src/sonolus/playlist/details.ts b/src/sonolus/playlist/details.ts index 31bce4a..80b23c5 100644 --- a/src/sonolus/playlist/details.ts +++ b/src/sonolus/playlist/details.ts @@ -8,7 +8,7 @@ import { nonEmpty } from '../utils/section.js' import { hideSpoilers, hideSpoilersFromPlaylist } from '../utils/spoiler.js' export const installPlaylistDetails = () => { - sonolus.playlist.detailsHandler = ({ itemName, options }) => { + sonolus.playlist.detailsHandler = ({ itemName, options: { spoilers } }) => { if (itemName.startsWith(`${config.sonolus.prefix}-random-`)) { const [, , , min, max] = itemName.split('-') const minRating = +(min ?? '') || 0 @@ -23,7 +23,7 @@ export const installPlaylistDetails = () => { author: databaseEngineItem.subtitle, tags: [{ title: { en: Text.Random } }], levels: randomize( - hideSpoilers(options.spoilers, sonolus.level.items) + hideSpoilers(spoilers[0], sonolus.level.items) .filter(({ rating }) => rating >= minRating && rating <= maxRating) .map(({ name }) => name), 20, @@ -45,7 +45,7 @@ export const installPlaylistDetails = () => { if (!item) return 404 return { - item: hideSpoilersFromPlaylist(options.spoilers, item), + item: hideSpoilersFromPlaylist(spoilers[0], item), description: item.description, actions: {}, hasCommunity: false, diff --git a/src/sonolus/playlist/info.ts b/src/sonolus/playlist/info.ts index ff0679d..90e9ad3 100644 --- a/src/sonolus/playlist/info.ts +++ b/src/sonolus/playlist/info.ts @@ -5,11 +5,9 @@ import { hideSpoilersFromPlaylists } from '../utils/spoiler.js' import { playlistSearches } from './search.js' export const installPlaylistInfo = () => { - sonolus.playlist.infoHandler = ({ options }) => { - const filteredPlaylists = hideSpoilersFromPlaylists( - options.spoilers, - sonolus.playlist.items, - ) + sonolus.playlist.infoHandler = ({ options: { spoilers } }) => { + const filteredPlaylists = hideSpoilersFromPlaylists(spoilers[0], sonolus.playlist.items) + return { searches: playlistSearches, sections: [ diff --git a/src/sonolus/playlist/list.ts b/src/sonolus/playlist/list.ts index bb8658c..411e2d3 100644 --- a/src/sonolus/playlist/list.ts +++ b/src/sonolus/playlist/list.ts @@ -8,15 +8,9 @@ import { hideSpoilersFromPlaylists } from '../utils/spoiler.js' import { playlistSearches } from './search.js' export const installPlaylistList = () => { - sonolus.playlist.listHandler = ({ - search: { type, options }, - page, - options: serverOptions, - }) => { - const filteredPlaylists = hideSpoilersFromPlaylists( - serverOptions.spoilers, - sonolus.playlist.items, - ) + sonolus.playlist.listHandler = ({ search: { type, options }, page, options: { spoilers } }) => { + const filteredPlaylists = hideSpoilersFromPlaylists(spoilers[0], sonolus.playlist.items) + if (type === 'quick') return { ...paginateItems(filterPlaylists(filteredPlaylists, options.keywords), page), diff --git a/src/sonolus/utils/spoiler.ts b/src/sonolus/utils/spoiler.ts index 0d233a3..1155f40 100644 --- a/src/sonolus/utils/spoiler.ts +++ b/src/sonolus/utils/spoiler.ts @@ -2,30 +2,30 @@ import { PlaylistItemModel } from '@sonolus/express' import { sonolus } from '../index.js' export const hideSpoilers = ( - passThrough: boolean, + passThrough: boolean | undefined, items: T[], -): T[] => { - if (passThrough) { - return items - } +) => { + if (passThrough) return items + return items.filter((item) => item.meta.publishedAt <= Date.now()) } export const hideSpoilersFromPlaylist = ( - passThrough: boolean, + passThrough: boolean | undefined, playlist: PlaylistItemModel, -): PlaylistItemModel => { - if (passThrough) { - return playlist - } +) => { + if (passThrough) return playlist + return { ...playlist, levels: hideSpoilers( false, playlist.levels.map((levelNameOrItem) => { if (typeof levelNameOrItem === 'object') return levelNameOrItem + const level = sonolus.level.items.find((level) => level.name === levelNameOrItem) if (!level) throw new Error(`Level not found: ${levelNameOrItem}`) + return level }), ), @@ -33,7 +33,10 @@ export const hideSpoilersFromPlaylist = ( } export const hideSpoilersFromPlaylists = ( - passThrough: boolean, + passThrough: boolean | undefined, playlists: PlaylistItemModel[], -): PlaylistItemModel[] => - playlists.map((playlist) => hideSpoilersFromPlaylist(passThrough, playlist)) +) => { + if (passThrough) return playlists + + return playlists.map((playlist) => hideSpoilersFromPlaylist(false, playlist)) +}