|
@@ -1,11 +1,29 @@
|
|
|
import { MUSIC_CARD_EMPTY_ARTIST, MUSIC_CARD_EMPTY_TITLE } from './MusicCardConstants'
|
|
import { MUSIC_CARD_EMPTY_ARTIST, MUSIC_CARD_EMPTY_TITLE } from './MusicCardConstants'
|
|
|
|
|
|
|
|
|
|
+const DEFAULT_TIME_TEXT = '00:00'
|
|
|
|
|
+const LYRIC_LINE_PATTERN = /^\[(\d{2}):(\d{2})\.(\d{2})\](.*)$/
|
|
|
|
|
+
|
|
|
|
|
+const isNonEmpty = (value?: string): boolean => {
|
|
|
|
|
+ return !!value && value.trim() !== ''
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
export interface MusicCardSnapshot {
|
|
export interface MusicCardSnapshot {
|
|
|
title: string
|
|
title: string
|
|
|
artist: string
|
|
artist: string
|
|
|
- lyricText: string
|
|
|
|
|
- positionMs: number
|
|
|
|
|
|
|
+ coverPath: string
|
|
|
|
|
+ hasCoverImage: boolean
|
|
|
hasSong: boolean
|
|
hasSong: boolean
|
|
|
|
|
+ isPlaying: boolean
|
|
|
|
|
+ currentPositionMs: number
|
|
|
|
|
+ durationMs: number
|
|
|
|
|
+ currentTimeText: string
|
|
|
|
|
+ durationTimeText: string
|
|
|
|
|
+ lyricLine1: string
|
|
|
|
|
+ lyricLine2: string
|
|
|
|
|
+ hasLyric: boolean
|
|
|
|
|
+ filePath: string
|
|
|
|
|
+ updatedAtMs: number
|
|
|
|
|
+ lyricText: string
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export interface MusicCardLyricLines {
|
|
export interface MusicCardLyricLines {
|
|
@@ -17,34 +35,73 @@ export interface MusicCardLyricLines {
|
|
|
export class MusicCardBindingData {
|
|
export class MusicCardBindingData {
|
|
|
title: string
|
|
title: string
|
|
|
artist: string
|
|
artist: string
|
|
|
|
|
+ coverPath: string
|
|
|
|
|
+ hasCoverImage: boolean
|
|
|
hasSong: boolean
|
|
hasSong: boolean
|
|
|
|
|
+ isPlaying: boolean
|
|
|
|
|
+ currentPositionMs: number
|
|
|
|
|
+ durationMs: number
|
|
|
|
|
+ currentTimeText: string
|
|
|
|
|
+ durationTimeText: string
|
|
|
lyricLine1: string
|
|
lyricLine1: string
|
|
|
lyricLine2: string
|
|
lyricLine2: string
|
|
|
|
|
+ hasLyric: boolean
|
|
|
|
|
+ filePath: string
|
|
|
|
|
+ updatedAtMs: number
|
|
|
|
|
|
|
|
constructor(
|
|
constructor(
|
|
|
title: string,
|
|
title: string,
|
|
|
artist: string,
|
|
artist: string,
|
|
|
|
|
+ coverPath: string,
|
|
|
|
|
+ hasCoverImage: boolean,
|
|
|
hasSong: boolean,
|
|
hasSong: boolean,
|
|
|
|
|
+ isPlaying: boolean,
|
|
|
|
|
+ currentPositionMs: number,
|
|
|
|
|
+ durationMs: number,
|
|
|
|
|
+ currentTimeText: string,
|
|
|
|
|
+ durationTimeText: string,
|
|
|
lyricLine1: string,
|
|
lyricLine1: string,
|
|
|
- lyricLine2: string
|
|
|
|
|
|
|
+ lyricLine2: string,
|
|
|
|
|
+ hasLyric: boolean,
|
|
|
|
|
+ filePath: string,
|
|
|
|
|
+ updatedAtMs: number
|
|
|
) {
|
|
) {
|
|
|
this.title = title
|
|
this.title = title
|
|
|
this.artist = artist
|
|
this.artist = artist
|
|
|
|
|
+ this.coverPath = coverPath
|
|
|
|
|
+ this.hasCoverImage = hasCoverImage
|
|
|
this.hasSong = hasSong
|
|
this.hasSong = hasSong
|
|
|
|
|
+ this.isPlaying = isPlaying
|
|
|
|
|
+ this.currentPositionMs = currentPositionMs
|
|
|
|
|
+ this.durationMs = durationMs
|
|
|
|
|
+ this.currentTimeText = currentTimeText
|
|
|
|
|
+ this.durationTimeText = durationTimeText
|
|
|
this.lyricLine1 = lyricLine1
|
|
this.lyricLine1 = lyricLine1
|
|
|
this.lyricLine2 = lyricLine2
|
|
this.lyricLine2 = lyricLine2
|
|
|
|
|
+ this.hasLyric = hasLyric
|
|
|
|
|
+ this.filePath = filePath
|
|
|
|
|
+ this.updatedAtMs = updatedAtMs
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const LYRIC_LINE_PATTERN = /^\[(\d{2}):(\d{2})\.(\d{2})\](.*)$/
|
|
|
|
|
-
|
|
|
|
|
export function createEmptyMusicCardSnapshot(): MusicCardSnapshot {
|
|
export function createEmptyMusicCardSnapshot(): MusicCardSnapshot {
|
|
|
return {
|
|
return {
|
|
|
title: '',
|
|
title: '',
|
|
|
artist: '',
|
|
artist: '',
|
|
|
- lyricText: '',
|
|
|
|
|
- positionMs: 0,
|
|
|
|
|
- hasSong: false
|
|
|
|
|
|
|
+ coverPath: '',
|
|
|
|
|
+ hasCoverImage: false,
|
|
|
|
|
+ hasSong: false,
|
|
|
|
|
+ isPlaying: false,
|
|
|
|
|
+ currentPositionMs: 0,
|
|
|
|
|
+ durationMs: 0,
|
|
|
|
|
+ currentTimeText: DEFAULT_TIME_TEXT,
|
|
|
|
|
+ durationTimeText: DEFAULT_TIME_TEXT,
|
|
|
|
|
+ lyricLine1: MUSIC_CARD_EMPTY_TITLE,
|
|
|
|
|
+ lyricLine2: MUSIC_CARD_EMPTY_ARTIST,
|
|
|
|
|
+ hasLyric: false,
|
|
|
|
|
+ filePath: '',
|
|
|
|
|
+ updatedAtMs: 0,
|
|
|
|
|
+ lyricText: ''
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -121,21 +178,46 @@ export function resolveMusicCardLyricLines(
|
|
|
|
|
|
|
|
export function buildMusicCardBindingData(snapshot: MusicCardSnapshot): MusicCardBindingData {
|
|
export function buildMusicCardBindingData(snapshot: MusicCardSnapshot): MusicCardBindingData {
|
|
|
const source = snapshot || createEmptyMusicCardSnapshot()
|
|
const source = snapshot || createEmptyMusicCardSnapshot()
|
|
|
|
|
+ const lyricLines = resolveMusicCardLyricLines(source.lyricText, source.currentPositionMs)
|
|
|
const hasSong = Boolean(source.hasSong)
|
|
const hasSong = Boolean(source.hasSong)
|
|
|
- const lyricLines = resolveMusicCardLyricLines(source.lyricText, source.positionMs)
|
|
|
|
|
-
|
|
|
|
|
const title =
|
|
const title =
|
|
|
- hasSong && source.title && source.title.trim() !== ''
|
|
|
|
|
- ? source.title
|
|
|
|
|
- : MUSIC_CARD_EMPTY_TITLE
|
|
|
|
|
|
|
+ hasSong && isNonEmpty(source.title) ? source.title : MUSIC_CARD_EMPTY_TITLE
|
|
|
const artist =
|
|
const artist =
|
|
|
- hasSong && source.artist && source.artist.trim() !== ''
|
|
|
|
|
- ? source.artist
|
|
|
|
|
- : MUSIC_CARD_EMPTY_ARTIST
|
|
|
|
|
|
|
+ hasSong && isNonEmpty(source.artist) ? source.artist : MUSIC_CARD_EMPTY_ARTIST
|
|
|
const lyricLine1 =
|
|
const lyricLine1 =
|
|
|
- lyricLines.hasLyric && lyricLines.line1 ? lyricLines.line1 : MUSIC_CARD_EMPTY_TITLE
|
|
|
|
|
|
|
+ lyricLines.hasLyric && isNonEmpty(lyricLines.line1) ? lyricLines.line1 : title
|
|
|
const lyricLine2 =
|
|
const lyricLine2 =
|
|
|
- lyricLines.hasLyric && lyricLines.line2 ? lyricLines.line2 : MUSIC_CARD_EMPTY_ARTIST
|
|
|
|
|
-
|
|
|
|
|
- return new MusicCardBindingData(title, artist, hasSong, lyricLine1, lyricLine2)
|
|
|
|
|
|
|
+ lyricLines.hasLyric && isNonEmpty(lyricLines.line2) ? lyricLines.line2 : artist
|
|
|
|
|
+ const hasLyric = lyricLines.hasLyric || Boolean(source.hasLyric)
|
|
|
|
|
+ const currentTimeText = isNonEmpty(source.currentTimeText)
|
|
|
|
|
+ ? source.currentTimeText
|
|
|
|
|
+ : DEFAULT_TIME_TEXT
|
|
|
|
|
+ const durationTimeText = isNonEmpty(source.durationTimeText)
|
|
|
|
|
+ ? source.durationTimeText
|
|
|
|
|
+ : DEFAULT_TIME_TEXT
|
|
|
|
|
+ const coverPath = source.coverPath ?? ''
|
|
|
|
|
+ const hasCoverImage = Boolean(source.hasCoverImage)
|
|
|
|
|
+ const isPlaying = Boolean(source.isPlaying)
|
|
|
|
|
+ const currentPositionMs = source.currentPositionMs ?? 0
|
|
|
|
|
+ const durationMs = source.durationMs ?? 0
|
|
|
|
|
+ const filePath = source.filePath ?? ''
|
|
|
|
|
+ const updatedAtMs = source.updatedAtMs ?? 0
|
|
|
|
|
+
|
|
|
|
|
+ return new MusicCardBindingData(
|
|
|
|
|
+ title,
|
|
|
|
|
+ artist,
|
|
|
|
|
+ coverPath,
|
|
|
|
|
+ hasCoverImage,
|
|
|
|
|
+ hasSong,
|
|
|
|
|
+ isPlaying,
|
|
|
|
|
+ currentPositionMs,
|
|
|
|
|
+ durationMs,
|
|
|
|
|
+ currentTimeText,
|
|
|
|
|
+ durationTimeText,
|
|
|
|
|
+ lyricLine1,
|
|
|
|
|
+ lyricLine2,
|
|
|
|
|
+ hasLyric,
|
|
|
|
|
+ filePath,
|
|
|
|
|
+ updatedAtMs
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|