|
|
@@ -37,6 +37,7 @@ export struct PlaylistDetailPage {
|
|
|
@State pageOpacity: number = 0
|
|
|
@State contentScale: number = 0.95
|
|
|
@State showContent: boolean = false
|
|
|
+ @State isSortMode: boolean = false // 是否处于排序模式
|
|
|
|
|
|
private playlistTable: PlaylistTable = new PlaylistTable(getContext(this))
|
|
|
private mediaTable: MediaTable = new MediaTable(getContext(this))
|
|
|
@@ -459,20 +460,33 @@ export struct PlaylistDetailPage {
|
|
|
.height(24)
|
|
|
.margin({ left: 12, right: 8 })
|
|
|
.onClick(() => {
|
|
|
- router.back()
|
|
|
+ // 如果在排序模式,先退出排序模式
|
|
|
+ if (this.isSortMode) {
|
|
|
+ this.exitSortMode()
|
|
|
+ } else {
|
|
|
+ router.back()
|
|
|
+ }
|
|
|
})
|
|
|
-
|
|
|
- Text(this.playlist?.name || '歌单详情')
|
|
|
+
|
|
|
+ Text(this.isSortMode ? '排序模式' : (this.playlist?.name || '歌单详情'))
|
|
|
.fontSize(18)
|
|
|
.fontColor(Color.White)
|
|
|
.fontWeight(FontWeight.Medium)
|
|
|
.layoutWeight(1)
|
|
|
.textAlign(TextAlign.Center)
|
|
|
|
|
|
- // 占位空间,保持标题居中
|
|
|
- Blank()
|
|
|
- .width(24)
|
|
|
+ // 排序/完成按钮
|
|
|
+ Text(this.isSortMode ? '完成' : '排序')
|
|
|
+ .fontSize(16)
|
|
|
+ .fontColor(Color.White)
|
|
|
.margin({ right: 12 })
|
|
|
+ .onClick(() => {
|
|
|
+ if (this.isSortMode) {
|
|
|
+ this.exitSortMode()
|
|
|
+ } else {
|
|
|
+ this.enterSortMode()
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
.height(48)
|
|
|
.width('100%')
|
|
|
@@ -859,15 +873,42 @@ export struct PlaylistDetailPage {
|
|
|
.justifyContent(FlexAlign.Center)
|
|
|
|
|
|
|
|
|
- // 更多操作按钮
|
|
|
- Text('⋯')
|
|
|
- .fontSize(20)
|
|
|
- .fontColor($r('app.color.text_color'))
|
|
|
- .opacity(0.6)
|
|
|
+ // 排序模式下显示上下移动按钮,否则显示更多按钮
|
|
|
+ if (this.isSortMode) {
|
|
|
+ Row({ space: 8 }) {
|
|
|
+ // 上移按钮
|
|
|
+ Text('▲')
|
|
|
+ .fontSize(16)
|
|
|
+ .fontColor(index === 0 ? '#cccccc' : this.themeColor)
|
|
|
+ .onClick(() => {
|
|
|
+ if (index > 0) {
|
|
|
+ this.moveSong(index, index - 1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .enabled(index > 0)
|
|
|
+
|
|
|
+ // 下移按钮
|
|
|
+ Text('▼')
|
|
|
+ .fontSize(16)
|
|
|
+ .fontColor(index === this.songList.length - 1 ? '#cccccc' : this.themeColor)
|
|
|
+ .onClick(() => {
|
|
|
+ if (index < this.songList.length - 1) {
|
|
|
+ this.moveSong(index, index + 1)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .enabled(index < this.songList.length - 1)
|
|
|
+ }
|
|
|
.margin({ right: 15 })
|
|
|
- .onClick(() => {
|
|
|
- this.showSongMenu(song)
|
|
|
- })
|
|
|
+ } else {
|
|
|
+ Text('⋯')
|
|
|
+ .fontSize(20)
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ .opacity(0.6)
|
|
|
+ .margin({ right: 15 })
|
|
|
+ .onClick(() => {
|
|
|
+ this.showSongMenu(song)
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
.width('100%')
|
|
|
.height(70)
|
|
|
@@ -878,12 +919,18 @@ export struct PlaylistDetailPage {
|
|
|
.height(70)
|
|
|
.width('100%')
|
|
|
.onClick(() => {
|
|
|
- this.playSong(song, index)
|
|
|
+ // 排序模式下禁用点击播放
|
|
|
+ if (!this.isSortMode) {
|
|
|
+ this.playSong(song, index)
|
|
|
+ }
|
|
|
})
|
|
|
.gesture(
|
|
|
LongPressGesture()
|
|
|
.onAction(() => {
|
|
|
- this.showSongMenu(song)
|
|
|
+ // 排序模式下不显示菜单
|
|
|
+ if (!this.isSortMode) {
|
|
|
+ this.showSongMenu(song)
|
|
|
+ }
|
|
|
})
|
|
|
)
|
|
|
.stateStyles({
|
|
|
@@ -891,7 +938,7 @@ export struct PlaylistDetailPage {
|
|
|
.backgroundColor(Color.Transparent)
|
|
|
},
|
|
|
pressed: {
|
|
|
- .backgroundColor('#f1f3f5')
|
|
|
+ .backgroundColor(this.isSortMode ? Color.Transparent : '#f1f3f5')
|
|
|
}
|
|
|
})
|
|
|
// 当前播放歌曲的背景高亮
|
|
|
@@ -1132,4 +1179,72 @@ export struct PlaylistDetailPage {
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 进入排序模式
|
|
|
+ */
|
|
|
+ enterSortMode() {
|
|
|
+ this.isSortMode = true
|
|
|
+ ToastUtil.showToast('点击上下箭头调整歌曲顺序')
|
|
|
+ LogUtil.info('heanup 进入排序模式')
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 退出排序模式
|
|
|
+ */
|
|
|
+ exitSortMode() {
|
|
|
+ this.isSortMode = false
|
|
|
+ ToastUtil.showToast('排序已保存')
|
|
|
+ LogUtil.info('heanup 退出排序模式')
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 移动歌曲位置
|
|
|
+ */
|
|
|
+ async moveSong(fromIndex: number, toIndex: number) {
|
|
|
+ if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 ||
|
|
|
+ fromIndex >= this.songList.length || toIndex >= this.songList.length) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ LogUtil.info(`heanup 移动歌曲: from ${fromIndex} to ${toIndex}`)
|
|
|
+
|
|
|
+ // 1. 在本地数组中移动
|
|
|
+ const movedSong = this.songList.splice(fromIndex, 1)[0]
|
|
|
+ this.songList.splice(toIndex, 0, movedSong)
|
|
|
+
|
|
|
+ // 2. 触发UI更新
|
|
|
+ this.songList = [...this.songList]
|
|
|
+
|
|
|
+ // 3. 更新数据库中的sortOrder
|
|
|
+ await this.updateAllSongsSortOrder()
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新所有歌曲的sortOrder到数据库
|
|
|
+ */
|
|
|
+ async updateAllSongsSortOrder() {
|
|
|
+ try {
|
|
|
+ LogUtil.info('heanup 开始更新所有歌曲的sortOrder')
|
|
|
+
|
|
|
+ for (let i = 0; i < this.songList.length; i++) {
|
|
|
+ const song = this.songList[i]
|
|
|
+ const success = await this.playlistTable.updatePlaylistSongSortOrder(
|
|
|
+ this.playlistId,
|
|
|
+ song.filePath,
|
|
|
+ i
|
|
|
+ )
|
|
|
+
|
|
|
+ if (success) {
|
|
|
+ LogUtil.info(`heanup 更新歌曲[${i}] ${song.name} sortOrder成功`)
|
|
|
+ } else {
|
|
|
+ LogUtil.error(`heanup 更新歌曲[${i}] ${song.name} sortOrder失败`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ LogUtil.info('heanup 所有歌曲sortOrder更新完成')
|
|
|
+ } catch (error) {
|
|
|
+ LogUtil.error('heanup 更新歌曲sortOrder失败: ' + error)
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|