mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-08-28 19:47:49 +08:00
Format season episodes in calendar tags
This commit is contained in:
@@ -66,6 +66,43 @@ export const prefixWithPlus = (value: number) => (value > 0 ? `+${value}` : valu
|
||||
// 格式化为Sxx
|
||||
export const formatSeason = (value: string) => (value ? `S${value.padStart(2, '0')}` : '')
|
||||
|
||||
/**
|
||||
* 格式化为 SxxExx 季集标识,多个连续集会合并为范围。
|
||||
*/
|
||||
export function formatSeasonEpisode(
|
||||
season: number | string | null | undefined,
|
||||
episodeNumbers: number[],
|
||||
): string {
|
||||
const seasonText = season === null || season === undefined || season === '' ? '' : formatSeason(String(season))
|
||||
const normalizedNumbers = [...new Set(episodeNumbers)]
|
||||
.map(number => Number(number))
|
||||
.filter(number => Number.isFinite(number) && number > 0)
|
||||
.sort((first, second) => first - second)
|
||||
|
||||
if (!normalizedNumbers.length) return seasonText
|
||||
|
||||
const formatEpisode = (number: number) => `E${String(number).padStart(2, '0')}`
|
||||
const ranges: string[] = []
|
||||
let start = normalizedNumbers[0]
|
||||
let end = normalizedNumbers[0]
|
||||
|
||||
for (let index = 1; index < normalizedNumbers.length; index++) {
|
||||
const currentNumber = normalizedNumbers[index]
|
||||
|
||||
if (currentNumber === end + 1) {
|
||||
end = currentNumber
|
||||
} else {
|
||||
ranges.push(start === end ? `${seasonText}${formatEpisode(start)}` : `${seasonText}${formatEpisode(start)}-${formatEpisode(end)}`)
|
||||
start = currentNumber
|
||||
end = currentNumber
|
||||
}
|
||||
}
|
||||
|
||||
ranges.push(start === end ? `${seasonText}${formatEpisode(start)}` : `${seasonText}${formatEpisode(start)}-${formatEpisode(end)}`)
|
||||
|
||||
return ranges.join('、')
|
||||
}
|
||||
|
||||
// 格式化为xx[TGMK]B
|
||||
export function formatFileSize(bytes: number, decimals = 2, prefix = false) {
|
||||
// 负数标记
|
||||
|
||||
@@ -7,7 +7,7 @@ import FullCalendar from '@fullcalendar/vue3'
|
||||
import type { Ref } from 'vue'
|
||||
import type { MediaInfo, Subscribe, TmdbEpisode } from '@/api/types'
|
||||
import api from '@/api'
|
||||
import { formatDateDifference, formatEp, parseDate } from '@/@core/utils/formatters'
|
||||
import { formatDateDifference, formatEp, formatSeasonEpisode, parseDate } from '@/@core/utils/formatters'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import { getCurrentLocale } from '@/plugins/i18n'
|
||||
@@ -526,12 +526,9 @@ function getMobileEventSubtitle(event: CalendarEventInfo) {
|
||||
// 获取移动端集季标识。
|
||||
function getMobileEventEpisodeTag(event: CalendarEventInfo) {
|
||||
if (event.mediaType === '电影') return t('calendar.movie')
|
||||
if (!event.subtitle && !event.season) return ''
|
||||
if (!event.episodeNumbers.length && !event.season) return ''
|
||||
|
||||
const seasonText = event.season ? `S${event.season}` : ''
|
||||
const episodeText = event.subtitle ? `E${event.subtitle}` : ''
|
||||
|
||||
return `${seasonText}${episodeText}`
|
||||
return formatSeasonEpisode(event.season, event.episodeNumbers)
|
||||
}
|
||||
|
||||
// 获取移动端时长标识。
|
||||
@@ -829,8 +826,8 @@ onActivated(() => {
|
||||
</template>
|
||||
</VImg>
|
||||
|
||||
<span v-if="calendarEvent.subtitle" class="mobile-calendar-poster-episode">
|
||||
EP {{ calendarEvent.subtitle }}
|
||||
<span v-if="getMobileEventEpisodeTag(calendarEvent)" class="mobile-calendar-poster-episode">
|
||||
{{ getMobileEventEpisodeTag(calendarEvent) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user