Selaa lähdekoodia

feat(playlist): 添加歌单歌曲排序功能

- 新增排序模式状态管理
- 实现进入和退出排序模式逻辑
- 添加歌曲上下移动功能- 禁用排序模式下的播放和菜单操作
- 更新排序后歌曲列表的数据库存储- 提供排序模式下的UI提示和交互反馈
chendeben 10 kuukautta sitten
vanhempi
sitoutus
d099e6a9e3
1 muutettua tiedostoa jossa 132 lisäystä ja 17 poistoa
  1. 132 17
      entry/src/main/ets/pages/PlaylistDetailPage.ets

+ 132 - 17
entry/src/main/ets/pages/PlaylistDetailPage.ets

@@ -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)
+    }
+  }
 }