|
|
@@ -1,10 +1,11 @@
|
|
|
+import { SymbolGlyphModifier } from '@kit.ArkUI'
|
|
|
import { PreferencesUtil, StrUtil, ToastUtil } from '@pura/harmony-utils'
|
|
|
import { BusinessError, emitter } from '@kit.BasicServicesKit'
|
|
|
import { common } from '@kit.AbilityKit'
|
|
|
import { CommonConstants } from '../common/constants/CommonConstants'
|
|
|
import { EventConstants } from '../common/constants/EventConstants'
|
|
|
import MediaTable from '../common/util/MediaTable'
|
|
|
-import { SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil'
|
|
|
+import { MenuModifier, SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil'
|
|
|
import { BreakpointType, BreakpointTypeEnum } from '../common/util/BreakpointSystem'
|
|
|
import Logger from '../common/util/Logger'
|
|
|
import { RemoteDriveManager } from '../common/util/RemoteDriveManager'
|
|
|
@@ -21,16 +22,24 @@ import { DeleteComptent } from './DeleteComptent'
|
|
|
import { SettingPage } from '../pages/SettingPage'
|
|
|
import { FindAlbumDetail } from './FindAlbumDetail'
|
|
|
import { PlayingIndicator } from './PlayingIndicator'
|
|
|
-import { setFindPlaylist } from '../common/util/FindPlaylistStore'
|
|
|
+import {
|
|
|
+ getFindPlaylistId,
|
|
|
+ getFindPlaylistName,
|
|
|
+ getFindVideoItems,
|
|
|
+ setFindPlaylist
|
|
|
+} from '../common/util/FindPlaylistStore'
|
|
|
import { PlaylistPlayRequest, savePendingPlaylistPlay } from '../common/util/PlaylistPlayRequestStore'
|
|
|
import PlaylistTable from '../common/util/PlaylistTable'
|
|
|
import { convertPlaylistSongsToVideoItems } from '../pages/PlaylistDetailPage'
|
|
|
+import { getWebdavVideoItems, setWebdavPlaylist } from '../pages/WebDavMainPage'
|
|
|
+import { getNavidromeVideoItems, setNavidromePlaylist } from '../common/util/NavidromePlaylistStore'
|
|
|
import {
|
|
|
buildPreferredRemotePlaybackPool,
|
|
|
buildSortedDiscoverySongs,
|
|
|
FindCollectionSortType,
|
|
|
resolveQueueStartIndex
|
|
|
} from '../common/util/FindDiscoveryHelper'
|
|
|
+import { insertSongToNextPlayQueue, QueueInsertStatus } from '../common/util/PlayQueueHelper'
|
|
|
|
|
|
@Builder
|
|
|
export function FindViewBuilder() {
|
|
|
@@ -322,6 +331,11 @@ export struct FindView {
|
|
|
if (uniqueRemoteSongs.length === 0) {
|
|
|
void this.bootstrapRemoteDiscoverySongsIfNeeded()
|
|
|
}
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] loadDiscoveryContent rawRemote=${remoteSongs.length}, uniqueRemote=${uniqueRemoteSongs.length}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(uniqueRemoteSongs)}`
|
|
|
+ )
|
|
|
|
|
|
Logger.info(
|
|
|
TAG,
|
|
|
@@ -396,6 +410,11 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
const remoteSongs = this.filterUniqueSongs(await this.mediaTable.queryRemoteSongsAsync(REMOTE_POOL_COUNT))
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] ensureRemoteDiscoverySongsAvailable dbRemote=${remoteSongs.length}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(remoteSongs)}`
|
|
|
+ )
|
|
|
if (remoteSongs.length > 0) {
|
|
|
this.applyRemoteDiscoverySongs(remoteSongs, true)
|
|
|
return
|
|
|
@@ -423,17 +442,24 @@ export struct FindView {
|
|
|
private async queryIndexedRemotePlaybackSongs(): Promise<VideoItem[]> {
|
|
|
const account = await this.prepareActiveRemoteAccount()
|
|
|
if (!account) {
|
|
|
+ Logger.warn(TAG, '[remote-debug] queryIndexedRemotePlaybackSongs skip: no active account')
|
|
|
return []
|
|
|
}
|
|
|
const supportsGlobalIndex = this.remoteDriveManager.supportsGlobalSearchIndexForAccount(account)
|
|
|
const isIndexReady = supportsGlobalIndex && this.remoteDriveManager.isGlobalSearchIndexReady(account)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] queryIndexedRemotePlaybackSongs account=${account.name}, type=${account.webType}, ` +
|
|
|
+ `supportsGlobalIndex=${supportsGlobalIndex}, isIndexReady=${isIndexReady}`
|
|
|
+ )
|
|
|
if (supportsGlobalIndex && !isIndexReady) {
|
|
|
- ToastUtil.showToast('首次云端漫游正在建立全量歌曲索引,请稍候')
|
|
|
+ ToastUtil.showToast('云端加载,请稍候')
|
|
|
}
|
|
|
const indexedSongs = await this.remoteDriveManager.getGlobalSearchIndexSongs(account)
|
|
|
const clonedSongs = indexedSongs.map((item: VideoItem) => cloneVideoItem(item))
|
|
|
Logger.info(TAG,
|
|
|
- `发现页全量云端索引池加载完成: account=${account.name}, type=${account.webType}, indexed=${clonedSongs.length}`)
|
|
|
+ `发现页全量云端索引池加载完成: account=${account.name}, type=${account.webType}, indexed=${clonedSongs.length}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(clonedSongs)}`)
|
|
|
return this.filterUniqueSongs(clonedSongs)
|
|
|
}
|
|
|
|
|
|
@@ -449,6 +475,10 @@ export struct FindView {
|
|
|
}
|
|
|
Logger.info(TAG, `发现页开始预热远程歌曲: account=${account.name}, type=${account.webType}`)
|
|
|
const seedSongs = await this.remoteDriveManager.getDiscoverySeedSongs(account, REMOTE_POOL_COUNT)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] bootstrapRemoteDiscoverySongs seedCount=${seedSongs.length}, sample=${this.buildSongDebugLog(seedSongs)}`
|
|
|
+ )
|
|
|
if (seedSongs.length === 0) {
|
|
|
Logger.info(TAG, `发现页远程预热未拿到歌曲: account=${account.name}`)
|
|
|
return
|
|
|
@@ -465,6 +495,12 @@ export struct FindView {
|
|
|
const saved = await this.mediaTable.saveOrUpdateWebDavItem(seedSong)
|
|
|
if (saved) {
|
|
|
savedCount += 1
|
|
|
+ } else {
|
|
|
+ Logger.warn(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] bootstrapRemoteDiscoverySongs save failed name=${this.getSongTitle(seedSong)}, ` +
|
|
|
+ `type=${seedSong.type}, account=${seedSong.webdav_account_id ?? ''}, path=${this.sanitizeSongPath(seedSong.filePath)}`
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
if (savedCount <= 0) {
|
|
|
@@ -475,7 +511,11 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
this.applyRemoteDiscoverySongs(refreshedRemoteSongs, true)
|
|
|
- Logger.info(TAG, `发现页远程预热完成: saved=${savedCount}, remote=${refreshedRemoteSongs.length}`)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `发现页远程预热完成: saved=${savedCount}, remote=${refreshedRemoteSongs.length}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(refreshedRemoteSongs)}`
|
|
|
+ )
|
|
|
} catch (error) {
|
|
|
Logger.warn(TAG, `发现页远程预热失败: ${this.toErrorMessage(error)}`)
|
|
|
} finally {
|
|
|
@@ -893,6 +933,11 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
const safeIndex = Math.min(Math.max(startIndex, 0), songs.length - 1)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] emitPlaylistPlay id=${playlistId}, name=${playlistName}, count=${songs.length}, ` +
|
|
|
+ `startIndex=${safeIndex}, playType=${playType ?? -1}, sample=${this.buildSongDebugLog(songs)}`
|
|
|
+ )
|
|
|
if (playlistId === 'find-album-playlist' || playlistId.indexOf('find-') === 0) {
|
|
|
setFindPlaylist(playlistId, playlistName, songs, safeIndex)
|
|
|
}
|
|
|
@@ -910,6 +955,120 @@ export struct FindView {
|
|
|
emitter.emit(eventPlaylistPlay, { data: playlistData })
|
|
|
}
|
|
|
|
|
|
+ private getCurrentPlaybackQueue(): VideoItem[] {
|
|
|
+ const queue = AppStorage.get('songList') as VideoItem[] | undefined
|
|
|
+ return Array.isArray(queue) ? queue : []
|
|
|
+ }
|
|
|
+
|
|
|
+ private getCurrentPlaybackIndex(): number {
|
|
|
+ const currentIndex = AppStorage.get('currIndex') as number | undefined
|
|
|
+ return typeof currentIndex === 'number' ? currentIndex : -1
|
|
|
+ }
|
|
|
+
|
|
|
+ private canFavoriteSong(item: VideoItem): boolean {
|
|
|
+ return StrUtil.isNotEmpty(item.filePath)
|
|
|
+ }
|
|
|
+
|
|
|
+ private canDeleteSong(item: VideoItem): boolean {
|
|
|
+ return item.type === CommonConstants.TYPE_LOCAL && StrUtil.isNotEmpty(item.filePath)
|
|
|
+ }
|
|
|
+
|
|
|
+ private canQueueSongForNextPlay(item: VideoItem): boolean {
|
|
|
+ return StrUtil.isNotEmpty(item.filePath)
|
|
|
+ }
|
|
|
+
|
|
|
+ private isSongFavorite(item: VideoItem): boolean {
|
|
|
+ return item.isFav === 1
|
|
|
+ }
|
|
|
+
|
|
|
+ private syncPlaybackQueueStores(previousQueue: VideoItem[], nextQueue: VideoItem[], currentIndex: number): void {
|
|
|
+ const findQueue = getFindVideoItems()
|
|
|
+ if (findQueue.length > 0 && this.isSameSongSelection(previousQueue, findQueue)) {
|
|
|
+ const playlistId = getFindPlaylistId().length > 0 ? getFindPlaylistId() : 'find-search'
|
|
|
+ const playlistName = getFindPlaylistName().length > 0 ? getFindPlaylistName() : '发现搜索'
|
|
|
+ setFindPlaylist(playlistId, playlistName, nextQueue, currentIndex)
|
|
|
+ }
|
|
|
+
|
|
|
+ const webdavQueue = getWebdavVideoItems()
|
|
|
+ if (webdavQueue.length > 0 && this.isSameSongSelection(previousQueue, webdavQueue)) {
|
|
|
+ setWebdavPlaylist(nextQueue, currentIndex)
|
|
|
+ }
|
|
|
+
|
|
|
+ const navidromeQueue = getNavidromeVideoItems()
|
|
|
+ if (navidromeQueue.length > 0 && this.isSameSongSelection(previousQueue, navidromeQueue)) {
|
|
|
+ setNavidromePlaylist(nextQueue, currentIndex)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private handleAddSongToNextPlay(song: VideoItem): void {
|
|
|
+ if (!this.canQueueSongForNextPlay(song)) {
|
|
|
+ ToastUtil.showToast('当前歌曲暂不支持加入下一首播放')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const currentQueue = this.getCurrentPlaybackQueue()
|
|
|
+ const result = insertSongToNextPlayQueue(
|
|
|
+ currentQueue,
|
|
|
+ this.currentSong?.filePath ?? '',
|
|
|
+ this.getCurrentPlaybackIndex(),
|
|
|
+ song
|
|
|
+ )
|
|
|
+
|
|
|
+ if (result.status === QueueInsertStatus.INVALID_SONG) {
|
|
|
+ ToastUtil.showToast('当前歌曲暂不支持加入下一首播放')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (result.status === QueueInsertStatus.ALREADY_PLAYING) {
|
|
|
+ ToastUtil.showToast('当前正在播放这首歌')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (result.status === QueueInsertStatus.START_PLAY) {
|
|
|
+ this.emitPlaylistPlay('find-search-next', '发现搜索', [song], 0)
|
|
|
+ ToastUtil.showToast('已开始播放')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ AppStorage.setOrCreate('songList', result.queue)
|
|
|
+ AppStorage.setOrCreate('currIndex', result.currentIndex)
|
|
|
+ PreferencesUtil.putSync('LastMusicList', result.queue)
|
|
|
+ this.syncPlaybackQueueStores(currentQueue, result.queue, result.currentIndex)
|
|
|
+ ToastUtil.showToast('已添加到下一首播放')
|
|
|
+ }
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ private SongContextMenuBuilder(item: VideoItem) {
|
|
|
+ Menu() {
|
|
|
+ MenuItem({
|
|
|
+ symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.forward_end_fill')),
|
|
|
+ content: '下一首播放'
|
|
|
+ })
|
|
|
+ .visibility(this.canQueueSongForNextPlay(item) ? Visibility.Visible : Visibility.None)
|
|
|
+ .onClick(() => {
|
|
|
+ this.handleAddSongToNextPlay(item)
|
|
|
+ })
|
|
|
+
|
|
|
+ MenuItem({
|
|
|
+ symbolStartIcon: new SymbolGlyphModifier(this.isSongFavorite(item) ?
|
|
|
+ $r('sys.symbol.heart_fill') : $r('sys.symbol.heart')),
|
|
|
+ content: this.isSongFavorite(item) ? '取消收藏' : '收藏'
|
|
|
+ })
|
|
|
+ .visibility(this.canFavoriteSong(item) ? Visibility.Visible : Visibility.None)
|
|
|
+ .onClick(() => {
|
|
|
+ void this.handleAlbumFavoriteSong(item)
|
|
|
+ })
|
|
|
+
|
|
|
+ MenuItem({
|
|
|
+ symbolStartIcon: new SymbolGlyphModifier($r('sys.symbol.trash')),
|
|
|
+ content: '删除'
|
|
|
+ })
|
|
|
+ .visibility(this.canDeleteSong(item) ? Visibility.Visible : Visibility.None)
|
|
|
+ .onClick(() => {
|
|
|
+ this.openDeleteSongDialog(item)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .attributeModifier(new MenuModifier())
|
|
|
+ }
|
|
|
+
|
|
|
private async getFullLocalSongsPool(): Promise<VideoItem[]> {
|
|
|
if (this.localSongsPool.length > 0) {
|
|
|
return this.localSongsPool
|
|
|
@@ -924,6 +1083,11 @@ export struct FindView {
|
|
|
|
|
|
private async getFullRemoteSongsPool(): Promise<VideoItem[]> {
|
|
|
if (this.remotePlaybackPool.length > 0) {
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] getFullRemoteSongsPool cacheHit=${this.remotePlaybackPool.length}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(this.remotePlaybackPool)}`
|
|
|
+ )
|
|
|
return this.remotePlaybackPool
|
|
|
}
|
|
|
if (!this.mediaTable) {
|
|
|
@@ -935,8 +1099,18 @@ export struct FindView {
|
|
|
await this.ensureRemoteDiscoverySongsAvailable()
|
|
|
remoteSongs = this.filterUniqueSongs(await this.mediaTable.queryRemoteSongsAsync())
|
|
|
}
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] getFullRemoteSongsPool beforeSelect indexed=${indexedSongs.length}, db=${remoteSongs.length}, ` +
|
|
|
+ `indexedSample=${this.buildSongDebugLog(indexedSongs)}, dbSample=${this.buildSongDebugLog(remoteSongs)}`
|
|
|
+ )
|
|
|
this.remotePlaybackPool = buildPreferredRemotePlaybackPool(indexedSongs, remoteSongs)
|
|
|
- Logger.info(TAG, `发现页全量云端播放池已就绪: indexed=${indexedSongs.length}, db=${remoteSongs.length}, selected=${this.remotePlaybackPool.length}`)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `发现页全量云端播放池已就绪: indexed=${indexedSongs.length}, db=${remoteSongs.length}, ` +
|
|
|
+ `selected=${this.remotePlaybackPool.length}, source=${indexedSongs.length > 0 ? 'indexed' : 'db'}, ` +
|
|
|
+ `sample=${this.buildSongDebugLog(this.remotePlaybackPool)}`
|
|
|
+ )
|
|
|
return this.remotePlaybackPool
|
|
|
}
|
|
|
|
|
|
@@ -950,6 +1124,12 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
const startIndex = Math.floor(Math.random() * queue.length)
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] playFromFullRemoteQueue random playlist=${playlistId}, fullQueue=${fullQueue.length}, ` +
|
|
|
+ `fallback=${fallbackSongs.length}, selectedQueue=${queue.length}, source=${fullQueue.length > 0 ? 'full' : 'fallback'}, ` +
|
|
|
+ `startIndex=${startIndex}, startSong=${this.buildSongDebugItem(queue[startIndex])}`
|
|
|
+ )
|
|
|
this.emitPlaylistPlay(playlistId, playlistName, queue, startIndex, 3)
|
|
|
return
|
|
|
}
|
|
|
@@ -965,6 +1145,11 @@ export struct FindView {
|
|
|
}
|
|
|
|
|
|
const targetFilePath = targetSong.filePath || ''
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] playFromFullRemoteQueue precise playlist=${playlistId}, target=${this.buildSongDebugItem(targetSong)}, ` +
|
|
|
+ `fullQueue=${fullQueue.length}, fallback=${fallbackSongs.length}`
|
|
|
+ )
|
|
|
const fullIndex = resolveQueueStartIndex(fullQueue, targetFilePath)
|
|
|
if (fullIndex >= 0) {
|
|
|
this.emitPlaylistPlay(playlistId, playlistName, fullQueue, fullIndex)
|
|
|
@@ -1002,6 +1187,11 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
const allRemoteSongs = await this.getFullRemoteSongsPool()
|
|
|
+ Logger.info(
|
|
|
+ TAG,
|
|
|
+ `[remote-debug] handleActionButtonTap cloud-random remotePlaybackPool=${allRemoteSongs.length}, ` +
|
|
|
+ `remoteSongsPool=${this.remoteSongsPool.length}, remoteSongs=${this.remoteSongs.length}, cloudMoodSongs=${this.cloudMoodSongs.length}`
|
|
|
+ )
|
|
|
if (allRemoteSongs.length === 0) {
|
|
|
ToastUtil.showToast('需要先配置网盘并加载歌曲后才能播放')
|
|
|
return
|
|
|
@@ -1395,9 +1585,13 @@ export struct FindView {
|
|
|
return
|
|
|
}
|
|
|
this.currentAlbumSongs = this.currentAlbumSongs.filter((item: VideoItem) => !deletedKeys.has(item.filePath))
|
|
|
+ this.searchResults = this.searchResults.filter((item: VideoItem) => !deletedKeys.has(item.filePath))
|
|
|
this.filterPlaylistCachesByDeletedKeys(deletedKeys)
|
|
|
await this.loadDiscoveryContent(false)
|
|
|
this.syncCurrentAlbumDetailFromState()
|
|
|
+ if (this.isSearchMode && this.searchText.length > 0) {
|
|
|
+ await this.onSearchInput(this.searchText)
|
|
|
+ }
|
|
|
ToastUtil.showToast('删除成功')
|
|
|
}
|
|
|
|
|
|
@@ -1649,6 +1843,36 @@ export struct FindView {
|
|
|
return `[${parts.join(', ')}](${items.length})`
|
|
|
}
|
|
|
|
|
|
+ private buildSongDebugLog(items: VideoItem[], limit: number = 5): string {
|
|
|
+ if (items.length === 0) {
|
|
|
+ return '[]'
|
|
|
+ }
|
|
|
+ const parts: string[] = []
|
|
|
+ const maxCount = Math.min(limit, items.length)
|
|
|
+ for (let i = 0; i < maxCount; i++) {
|
|
|
+ parts.push(this.buildSongDebugItem(items[i]))
|
|
|
+ }
|
|
|
+ return `[${parts.join('; ')}](${items.length})`
|
|
|
+ }
|
|
|
+
|
|
|
+ private buildSongDebugItem(item?: VideoItem): string {
|
|
|
+ if (!item) {
|
|
|
+ return 'unknown'
|
|
|
+ }
|
|
|
+ return `${this.getSongTitle(item)}|type=${item.type}|acc=${item.webdav_account_id ?? ''}|path=${this.sanitizeSongPath(item.filePath)}`
|
|
|
+ }
|
|
|
+
|
|
|
+ private sanitizeSongPath(path?: string): string {
|
|
|
+ if (StrUtil.isEmpty(path)) {
|
|
|
+ return ''
|
|
|
+ }
|
|
|
+ const value = path as string
|
|
|
+ if (value.length <= 48) {
|
|
|
+ return value
|
|
|
+ }
|
|
|
+ return `...${value.substring(value.length - 48)}`
|
|
|
+ }
|
|
|
+
|
|
|
private buildAlbumSelectionLog(items: FindAlbumGroup[], limit: number = 4): string {
|
|
|
if (items.length === 0) {
|
|
|
return '[]'
|
|
|
@@ -2190,34 +2414,62 @@ export struct FindView {
|
|
|
.padding(10)
|
|
|
}
|
|
|
|
|
|
+ @Builder
|
|
|
+ private buildSwipeDeleteAction(item: VideoItem) {
|
|
|
+ Row() {
|
|
|
+ Button('删除')
|
|
|
+ .width(72)
|
|
|
+ .height(52)
|
|
|
+ .fontSize(14)
|
|
|
+ .fontColor(Color.White)
|
|
|
+ .backgroundColor($r('app.color.btn_red'))
|
|
|
+ .borderRadius(14)
|
|
|
+ .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.8 })
|
|
|
+ .onClick(() => {
|
|
|
+ this.openDeleteSongDialog(item)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .padding({ left: 8, right: 4 })
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
@Builder
|
|
|
private buildSearchContent() {
|
|
|
- Scroll() {
|
|
|
- Column({ space: 12 }) {
|
|
|
- if (this.isSearchLoading) {
|
|
|
+ List({ space: 12 }) {
|
|
|
+ if (this.isSearchLoading) {
|
|
|
+ ListItem() {
|
|
|
this.buildSearchLoadingState()
|
|
|
- } else if (this.searchText.length === 0 && this.searchHistoryItems.length > 0) {
|
|
|
+ }
|
|
|
+ } else if (this.searchText.length === 0 && this.searchHistoryItems.length > 0) {
|
|
|
+ ListItem() {
|
|
|
this.SearchHistoryView()
|
|
|
- } else if (this.searchText.length === 0) {
|
|
|
+ }
|
|
|
+ } else if (this.searchText.length === 0) {
|
|
|
+ ListItem() {
|
|
|
this.buildSectionEmptyState('搜索本地和网盘歌曲', '输入歌曲名、歌手或专辑名后即可开始搜索', false)
|
|
|
- } else if (this.searchResults.length === 0) {
|
|
|
+ }
|
|
|
+ } else if (this.searchResults.length === 0) {
|
|
|
+ ListItem() {
|
|
|
this.buildSectionEmptyState('没有找到匹配歌曲', '试试其他关键词,结果会同时包含本地和网盘歌曲', false)
|
|
|
- } else {
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ ListItem() {
|
|
|
Row() {
|
|
|
Text('搜索结果')
|
|
|
- .fontSize(15)
|
|
|
- .fontWeight(FontWeight.Bold)
|
|
|
- .fontColor(this.getPrimaryTextColor())
|
|
|
+ .fontSize(14)
|
|
|
+ .fontWeight(FontWeight.Medium)
|
|
|
+ .fontColor(this.getSecondaryTextColor())
|
|
|
Blank()
|
|
|
Text(`${this.searchResults.length} 首`)
|
|
|
.fontSize(12)
|
|
|
.fontColor(this.getSecondaryTextColor())
|
|
|
}
|
|
|
.width('100%')
|
|
|
+ }
|
|
|
|
|
|
- ForEach(this.searchResults, (item: VideoItem, index: number) => {
|
|
|
+ ForEach(this.searchResults, (item: VideoItem, index: number) => {
|
|
|
+ ListItem() {
|
|
|
PointLightContentButton({
|
|
|
pointColor: this.themeColor,
|
|
|
buttonColor: this.getCardBackgroundColor(),
|
|
|
@@ -2232,15 +2484,29 @@ export struct FindView {
|
|
|
.onClick(() => {
|
|
|
this.emitPlaylistPlay('find-search', '发现搜索', this.searchResults, index)
|
|
|
})
|
|
|
- }, getFindSongKey)
|
|
|
- }
|
|
|
+ }
|
|
|
+ .swipeAction(this.canDeleteSong(item)
|
|
|
+ ? {
|
|
|
+ end: this.buildSwipeDeleteAction(item),
|
|
|
+ edgeEffect: SwipeEdgeEffect.None
|
|
|
+ }
|
|
|
+ : {})
|
|
|
+ .bindContextMenu(this.SongContextMenuBuilder(item), ResponseType.LongPress,
|
|
|
+ {
|
|
|
+ preview: MenuPreviewMode.IMAGE
|
|
|
+ })
|
|
|
+ .bindContextMenu(this.SongContextMenuBuilder(item), ResponseType.RightClick,
|
|
|
+ {
|
|
|
+ preview: MenuPreviewMode.IMAGE
|
|
|
+ })
|
|
|
+ }, getFindSongKey)
|
|
|
}
|
|
|
- .width('100%')
|
|
|
- .padding({ left: 12, right: 12, top: this.topSafeHeight +65, bottom: this.bottomSafeHeight + 96 })
|
|
|
}
|
|
|
+ .width('100%')
|
|
|
+ .height('100%')
|
|
|
+ .padding({ left: 12, right: 12, top: this.topSafeHeight + 65, bottom: this.bottomSafeHeight + 96 })
|
|
|
.scrollBar(BarState.Off)
|
|
|
.edgeEffect(EdgeEffect.Spring)
|
|
|
- .width('100%')
|
|
|
.layoutWeight(1)
|
|
|
}
|
|
|
|
|
|
@@ -3211,6 +3477,9 @@ export struct FindView {
|
|
|
onSongTap: (index: number, songs?: VideoItem[]) => {
|
|
|
this.handleAlbumSongTap(index, songs)
|
|
|
},
|
|
|
+ onPlayNextSong: (song: VideoItem) => {
|
|
|
+ this.handleAddSongToNextPlay(song)
|
|
|
+ },
|
|
|
onFavoriteSong: (song: VideoItem) => {
|
|
|
void this.handleAlbumFavoriteSong(song)
|
|
|
},
|