|
|
@@ -23,23 +23,38 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
private listScroller: ListScroller = new ListScroller()
|
|
|
@State isSearchMode: boolean = false
|
|
|
@Prop playlist: Playlist
|
|
|
- @Prop mediaKuList: Array<VideoItem>
|
|
|
- @StorageProp('mediaKuList') mediaKuList2: Array<VideoItem> = []; //媒体库文件
|
|
|
+ @StorageProp('mediaKuList') mediaKuList: Array<VideoItem> = []; //媒体库文件
|
|
|
private mediaTable: MediaTable = new MediaTable(getContext(this))
|
|
|
private playlistTable: PlaylistTable = new PlaylistTable(getContext(this))
|
|
|
- @State dataSource: LazyDataSource<VideoItem> = new LazyDataSource(this.filteredSongs)
|
|
|
+ @State dataSource: LazyDataSource<VideoItem> = new LazyDataSource([])
|
|
|
+ // 分页相关状态
|
|
|
+ @State currentPage: number = 0
|
|
|
+ @State hasMoreData: boolean = true
|
|
|
+ private readonly PAGE_SIZE: number = 50
|
|
|
+ // 用于存储完整数据的引用
|
|
|
+ private allSongs: VideoItem[] = []
|
|
|
// 回调函数
|
|
|
onConfirm?: (songs: VideoItem[]) => void
|
|
|
onCancel?: () => void
|
|
|
|
|
|
aboutToAppear() {
|
|
|
- LogUtil.info('heanup AddSongsToPlaylistDialogContent aboutToAppear 开始')
|
|
|
- LogUtil.info('heanup playlist: ' + (this.playlist ? JSON.stringify({ id: this.playlist.id, name: this.playlist.name }) : 'null'))
|
|
|
- // console.info('onecold mediaKuList 对话框 aboutToAppear='+this.mediaKuList.length)
|
|
|
- this.updateListData(this.mediaKuList2)
|
|
|
-
|
|
|
+ LogUtil.info('heanup AddSongsToPlaylistDialogContent aboutToAppear 开始')
|
|
|
+ LogUtil.info('heanup playlist: ' +
|
|
|
+ (this.playlist ? JSON.stringify({ id: this.playlist.id, name: this.playlist.name }) : 'null'))
|
|
|
+ console.info('onecold mediaKuList 对话框 aboutToAppear=' + this.mediaKuList.length)
|
|
|
+ this.allSongs = [...this.mediaKuList]
|
|
|
+ this.filteredSongs = [...this.mediaKuList]
|
|
|
+ this.loadInitialData()
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 加载初始数据
|
|
|
+ */
|
|
|
+ private loadInitialData() {
|
|
|
+ this.currentPage = 0
|
|
|
+ this.hasMoreData = true
|
|
|
+ this.updateListData(false)
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 搜索过滤歌曲
|
|
|
@@ -47,37 +62,85 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
filterSongs() {
|
|
|
this.isSearchMode = true
|
|
|
if (!this.searchText.trim()) {
|
|
|
- this.filteredSongs = [...this.mediaKuList]
|
|
|
+ this.filteredSongs = [...this.allSongs]
|
|
|
} else {
|
|
|
- this.filteredSongs = this.mediaKuList.filter(item =>{
|
|
|
- //支持模糊匹配和艺术家 专辑匹配
|
|
|
- const regex = new RegExp(this.searchText.replace(/\s+/g, '.*'), 'i');
|
|
|
- return regex.test(item.name.toLowerCase())||
|
|
|
- regex.test(item.fileName?.toLowerCase() ?? "") ||
|
|
|
- regex.test(item.artist?.toLowerCase() ?? "") ||
|
|
|
- regex.test(item.album?.toLowerCase() ?? "")
|
|
|
- })
|
|
|
+ // 添加空值检查以防止TypeError
|
|
|
+ if (!this.allSongs || !Array.isArray(this.allSongs)) {
|
|
|
+ this.filteredSongs = []
|
|
|
+ } else {
|
|
|
+ this.filteredSongs = this.allSongs.filter(item => {
|
|
|
+ //支持模糊匹配和艺术家 专辑匹配
|
|
|
+ const regex = new RegExp(this.searchText.replace(/\s+/g, '.*'), 'i');
|
|
|
+ return regex.test(item.name.toLowerCase()) ||
|
|
|
+ regex.test(item.fileName?.toLowerCase() ?? "") ||
|
|
|
+ regex.test(item.artist?.toLowerCase() ?? "") ||
|
|
|
+ regex.test(item.album?.toLowerCase() ?? "")
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
- this.updateListData(this.filteredSongs)
|
|
|
+ // 重置分页状态并重新加载数据
|
|
|
+ this.loadInitialData()
|
|
|
}
|
|
|
|
|
|
- updateListData(mList: Array<VideoItem>) {
|
|
|
+ // 修改 updateListData 方法,使其更清晰
|
|
|
+ updateListData(append: boolean = false) {
|
|
|
this.getUIContext().animateTo({ duration: 666 }, () => {
|
|
|
this.opacityItem = 0;
|
|
|
})
|
|
|
- //只展示100条,不然会报错
|
|
|
+
|
|
|
setTimeout(() => {
|
|
|
- if (ArrayUtil.isNotEmpty(mList)&&mList.length > 100) {
|
|
|
- this.dataSource.pushArrayData(mList.slice(0, 100))
|
|
|
- }else{
|
|
|
- this.dataSource.pushArrayData(mList)
|
|
|
+ const sourceData = this.filteredSongs
|
|
|
+ let dataToShow: VideoItem[] = []
|
|
|
+
|
|
|
+ if (append) {
|
|
|
+ // 追加数据模式
|
|
|
+ const currentData = this.dataSource.dataArray
|
|
|
+ const startIndex = this.currentPage * this.PAGE_SIZE
|
|
|
+ const endIndex = Math.min(startIndex + this.PAGE_SIZE, sourceData.length)
|
|
|
+ const newData = sourceData.slice(startIndex, endIndex)
|
|
|
+
|
|
|
+ if (newData.length > 0) {
|
|
|
+ dataToShow = [...currentData, ...newData]
|
|
|
+ this.currentPage++
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 初始加载模式
|
|
|
+ this.currentPage = 1
|
|
|
+ const endIndex = Math.min(this.PAGE_SIZE, sourceData.length)
|
|
|
+ dataToShow = sourceData.slice(0, endIndex)
|
|
|
}
|
|
|
|
|
|
+ // 更新数据源
|
|
|
+ this.dataSource.pushArrayData(dataToShow)
|
|
|
+
|
|
|
+ // 检查是否还有更多数据
|
|
|
+ const totalLoaded = dataToShow.length
|
|
|
+ this.hasMoreData = totalLoaded < sourceData.length
|
|
|
+
|
|
|
this.getUIContext().animateTo({ duration: 666 }, () => {
|
|
|
- this.opacityItem = 1;
|
|
|
- });
|
|
|
- }, 200);
|
|
|
+ this.opacityItem = 1
|
|
|
+ })
|
|
|
+ }, 200)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 改进的加载更多数据方法
|
|
|
+ loadMoreData() {
|
|
|
+ console.info('loadMoreData called, hasMoreData:', this.hasMoreData, 'isLoading:', this.isLoading)
|
|
|
+
|
|
|
+ if (!this.hasMoreData || this.isLoading) {
|
|
|
+ console.info('loadMoreData skipped - no more data or already loading')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ console.info('loadMoreData executing')
|
|
|
+ this.isLoading = true
|
|
|
|
|
|
+ // 使用 setTimeout 模拟异步加载
|
|
|
+ setTimeout(() => {
|
|
|
+ this.updateListData(true) // append mode
|
|
|
+ this.isLoading = false
|
|
|
+ console.info('loadMoreData completed, current data length:', this.dataSource.dataArray.length)
|
|
|
+ }, 300)
|
|
|
}
|
|
|
|
|
|
build() {
|
|
|
@@ -111,9 +174,9 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
// 已选择歌曲数量
|
|
|
if (this.selectedSongs.length > 0) {
|
|
|
Row() {
|
|
|
- Text(`已选择 ${this.selectedSongs.length} 首歌曲`)
|
|
|
+ Text(`已选择 ${this.selectedSongs.length} 首歌曲`)
|
|
|
.fontSize(14)
|
|
|
- .fontColor($r('app.color.theme_color'))
|
|
|
+ .fontColor(this.themeColor)
|
|
|
.fontWeight(FontWeight.Medium)
|
|
|
|
|
|
Blank()
|
|
|
@@ -133,7 +196,7 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
}
|
|
|
|
|
|
// 歌曲列表
|
|
|
- if (this.filteredSongs.length === 0&&this.isSearchMode) {
|
|
|
+ if (this.dataSource.dataArray.length === 0 && this.isSearchMode) {
|
|
|
Column({ space: 12 }) {
|
|
|
Image($r('app.media.music_red'))
|
|
|
.width(64)
|
|
|
@@ -168,7 +231,7 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
Button(`添加${this.selectedSongs.length > 0 ? `(${this.selectedSongs.length})` : ''}`)
|
|
|
.width('45%')
|
|
|
.height(40)
|
|
|
- .backgroundColor($r('app.color.theme_color'))
|
|
|
+ .backgroundColor(this.themeColor)
|
|
|
.borderRadius(8)
|
|
|
.fontSize(14)
|
|
|
.fontColor(Color.White)
|
|
|
@@ -194,7 +257,7 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
*/
|
|
|
private handleConfirm() {
|
|
|
if (this.selectedSongs.length === 0) {
|
|
|
- ToastUtil.showToast('请选择至少一首歌曲')
|
|
|
+ ToastUtil.showToast(' 请选择至少一首歌曲')
|
|
|
return
|
|
|
}
|
|
|
|
|
|
@@ -221,7 +284,7 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
.draggable(false)
|
|
|
.interpolation(ImageInterpolation.High)// 用于重采样后的抗锯齿
|
|
|
.autoResize(true) // 重采样,可减少内存占用
|
|
|
- .opacity(this.opacityItem)// 绑定透明度
|
|
|
+ .opacity(this.opacityItem) // 绑定透明度
|
|
|
// 歌曲信息
|
|
|
Column({ space: 4 }) {
|
|
|
Text(song.name || '未知歌曲')
|
|
|
@@ -233,7 +296,7 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
|
|
|
Row() {
|
|
|
if (song.artist) {
|
|
|
- Text(song.artist)
|
|
|
+ Text(song.artist+' '+song.duration)
|
|
|
.fontSize(12)
|
|
|
.fontColor('#999999')
|
|
|
.maxLines(1)
|
|
|
@@ -286,17 +349,60 @@ struct AddSongsToPlaylistDialogContent {
|
|
|
.clickEffect({ level: ClickEffectLevel.LIGHT })
|
|
|
|
|
|
}, (song: VideoItem) => song.id)
|
|
|
+
|
|
|
+ // 添加 footer 来显示加载状态
|
|
|
+ ListItem() {
|
|
|
+ this.footer()
|
|
|
+ }
|
|
|
+ .visibility(this.hasMoreData ? Visibility.Visible : Visibility.None)
|
|
|
}
|
|
|
.cachedCount(6)
|
|
|
+ .height('100%')
|
|
|
+ .scrollBar(BarState.Off)
|
|
|
+ .edgeEffect(EdgeEffect.Spring, { alwaysEnabled: true })
|
|
|
+ .onReachEnd(() => {
|
|
|
+ // 滚动到底部时加载更多数据
|
|
|
+ console.info('List onReachEnd triggered')
|
|
|
+ this.loadMoreData()
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
}
|
|
|
.scrollBar(BarState.Auto)
|
|
|
-
|
|
|
.scrollable(ScrollDirection.Vertical)
|
|
|
.height(300)
|
|
|
}
|
|
|
|
|
|
+ // 改进的 footer Builder
|
|
|
+ @Builder
|
|
|
+ footer() {
|
|
|
+ Column() {
|
|
|
+ if (this.isLoading) {
|
|
|
+ Row() {
|
|
|
+ LoadingProgress()
|
|
|
+ .height(20)
|
|
|
+ .width(20)
|
|
|
+ Text('加载中...')
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor('#999999')
|
|
|
+ .margin({ left: 8 })
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .height(40)
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ } else if (this.hasMoreData) {
|
|
|
+ Row() {
|
|
|
+ Text('上拉加载更多')
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor('#999999')
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .height(40)
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -356,3 +462,5 @@ export function showAddSongsToPlaylistDialog(
|
|
|
) {
|
|
|
dialogManager.showAddSongsToPlaylistDialog(playlist, onConfirm, onCancel)
|
|
|
}
|
|
|
+
|
|
|
+
|