onecold 4 місяців тому
батько
коміт
45dd618aef

+ 2 - 2
entry/src/main/ets/pages/NewIndex.ets

@@ -1232,10 +1232,10 @@ struct NewIndex {
 
   isTextSelected(index:number):boolean{
     if(this.mType == 0){
-      return this.modeType == index
+      return this.modeType == index+1
     }
     if (this.mType == 8) {
-      return index == 4
+      return index == 0
     }
     if (this.mType == 2) {
       return index == 5

+ 179 - 200
entry/src/main/ets/view/FindAlbumDetail.ets

@@ -1,6 +1,9 @@
 import { StrUtil } from '@pura/harmony-utils'
 import { CommonConstants } from '../common/constants/CommonConstants'
+import { ButtonFancyModifier, ShadowModifier, SymbolGlyphFancyModifier } from '../common/util/AttributeModifierUtil'
 import { VideoItem } from '../viewmodel/VideoItem'
+import { PlayingIndicator } from './PlayingIndicator'
+import { PointLightContentButton } from './PointLight/PointLightContentButton'
 
 function getFindAlbumSongKey(item: VideoItem, index: number): string {
   if (StrUtil.isNotEmpty(item.filePath)) {
@@ -25,6 +28,8 @@ export struct FindAlbumDetail {
   @Prop topSafeHeight: number = 0
   @Prop bottomSafeHeight: number = 0
   @Prop themeColor: string = CommonConstants.DEFAULT_THEME_COLOR
+  @StorageLink('currentSong') currentSong: VideoItem | undefined = undefined
+  @StorageLink('isPlaying') isPlaying: boolean = false
   onPlayAll: () => void = () => {}
   onRandomPlay: () => void = () => {}
   onBack: () => void = () => {}
@@ -45,8 +50,8 @@ export struct FindAlbumDetail {
   }
 
   private getSongSubtitle(item: VideoItem): string {
-    if (StrUtil.isNotEmpty(item.artist) && StrUtil.isNotEmpty(item.fileName) && item.artist !== item.fileName) {
-      return `${item.artist} · ${item.fileName}`
+    if (StrUtil.isNotEmpty(item.artist)) {
+      return `${item.artist} · ${item.duration}`
     }
     if (StrUtil.isNotEmpty(item.artist)) {
       return item.artist as string
@@ -54,9 +59,6 @@ export struct FindAlbumDetail {
     if (StrUtil.isNotEmpty(item.fileName)) {
       return item.fileName as string
     }
-    if (StrUtil.isNotEmpty(item.album)) {
-      return item.album as string
-    }
     return '本地音乐'
   }
 
@@ -87,33 +89,6 @@ export struct FindAlbumDetail {
     return '未知歌手'
   }
 
-  private getAlbumSourceText(): string {
-    if (StrUtil.isNotEmpty(this.albumSourceLabel)) {
-      return this.albumSourceLabel
-    }
-    return '专辑'
-  }
-
-  private getSongIndexText(item: VideoItem, index: number): string {
-    if (StrUtil.isNotEmpty(item.track)) {
-      const parsed = Number.parseInt(item.track as string, 10)
-      if (!Number.isNaN(parsed) && parsed > 0) {
-        return String(parsed)
-      }
-    }
-    return String(index + 1)
-  }
-
-  @Builder
-  private buildSourceTag(text: string, isStrong: boolean = false) {
-    Text(text)
-      .fontSize(11)
-      .fontWeight(isStrong ? FontWeight.Medium : FontWeight.Regular)
-      .fontColor(isStrong ? $r('app.color.white') : this.getPrimaryTextColor())
-      .padding({ left: 10, right: 10, top: 6, bottom: 6 })
-      .backgroundColor(isStrong ? this.getThemeAccent() : '#F1EDF7')
-      .borderRadius(999)
-  }
 
   @Builder
   private buildHeroTag(text: string) {
@@ -127,187 +102,144 @@ export struct FindAlbumDetail {
   }
 
   @Builder
-  private buildHeaderActions() {
-    Row({ space: 12 }) {
-      Button({ type: ButtonType.Capsule, stateEffect: false }) {
-        Row({ space: 8 }) {
-          SymbolGlyph($r('sys.symbol.play_fill'))
-            .fontSize(18)
-            .fontColor([this.getThemeAccent()])
-            .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
+  private buildPlayAllActionContent() {
+    Row({ space: 8 }) {
+      SymbolGlyph($r('sys.symbol.play_fill'))
+        .fontSize(18)
+        .fontColor([this.getThemeAccent()])
+        .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
 
-          Text('播放全部')
-            .fontSize(14)
-            .fontWeight(FontWeight.Medium)
-            .fontColor(this.getPrimaryTextColor())
-            .maxLines(1)
+      Text('播放全部')
+        .fontSize(14)
+        .fontWeight(FontWeight.Medium)
+        .fontColor(this.getPrimaryTextColor())
+        .maxLines(1)
+    }
+    .width('100%')
+    .height(48)
+    .justifyContent(FlexAlign.Center)
+    .alignItems(VerticalAlign.Center)
+  }
+
+  @Builder
+  private buildRandomActionContent() {
+    Row({ space: 8 }) {
+      SymbolGlyph($r('sys.symbol.shuffle'))
+        .fontSize(18)
+        .fontColor([Color.White])
+        .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
+
+      Text('随机播放')
+        .fontSize(14)
+        .fontWeight(FontWeight.Medium)
+        .fontColor('#FFFFFFFF')
+        .maxLines(1)
+    }
+    .width('100%')
+    .height(48)
+    .justifyContent(FlexAlign.Center)
+    .alignItems(VerticalAlign.Center)
+  }
+
+
+
+  @Builder
+  private buildHeaderActions() {
+    Row({ space: 10 }) {
+      PointLightContentButton({
+        pointColor: this.getThemeAccent(),
+        buttonColor: '#1FFFFFFF',
+        buttonRadius: 20,
+        pointLightHeight: 48,
+        useShadow: true,
+        builder: () => {
+          this.buildPlayAllActionContent()
         }
-        .width('100%')
-        .justifyContent(FlexAlign.Center)
-        .alignItems(VerticalAlign.Center)
-      }
-      .layoutWeight(1)
-      .height(44)
-      .backgroundColor('#FFFFFFFF')
-      .borderRadius(22)
-      .border({ width: 1, color: '#10FFFFFF', radius: 22 })
-      .shadow({ radius: 14, color: '#22000000', offsetY: 8 })
-      .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.97 })
+      })
+      .width(132)
+      .height(48)
+      .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.9 })
+      .border({ width: 1, color: '#10FFFFFF', radius: 20 })
       .onClick(() => {
         this.onPlayAll()
       })
 
-      Button({ type: ButtonType.Capsule, stateEffect: false }) {
-        Row({ space: 8 }) {
-          SymbolGlyph($r('sys.symbol.arrow_clockwise'))
-            .fontSize(18)
-            .fontColor([Color.White])
-            .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
-
-          Text('随机播放')
-            .fontSize(14)
-            .fontWeight(FontWeight.Medium)
-            .fontColor('#FFFFFFFF')
-            .maxLines(1)
+      PointLightContentButton({
+        pointColor: Color.White,
+        buttonColor: '#1FFFFFFF',
+        buttonRadius: 20,
+        pointLightHeight: 48,
+        useShadow: true,
+        builder: () => {
+          this.buildRandomActionContent()
         }
-        .width('100%')
-        .justifyContent(FlexAlign.Center)
-        .alignItems(VerticalAlign.Center)
-      }
-      .layoutWeight(1)
-      .height(44)
-      .backgroundColor('#1FFFFFFF')
-      .borderRadius(22)
-      .border({ width: 1, color: '#30FFFFFF', radius: 22 })
-      .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.97 })
+      })
+      .width(132)
+      .height(48).clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.96 })
+      .border({ width: 1, color: '#30FFFFFF', radius: 20 })
       .onClick(() => {
         this.onRandomPlay()
       })
     }
     .width('100%')
+    .justifyContent(FlexAlign.Center)
   }
 
   @Builder
   private buildHeroHeader() {
-    Stack({ alignContent: Alignment.TopStart }) {
+    Stack({ alignContent: Alignment.BottomEnd }) {
       Image(this.getAlbumCover())
         .width('100%')
-        .height(410)
+        .height(320)
         .objectFit(ImageFit.Cover)
+        .opacity(0.7)
 
       Column() {
-        Blank()
-      }
-      .width('100%')
-      .height(410)
-      .linearGradient({
-        direction: GradientDirection.Bottom,
-        colors: [['#05070D12', 0], ['#0A0E1F66', 0.4], ['#11141FE8', 1]]
-      })
-      .opacity(1)
 
-      Column() {
-        Row() {
-          Button({ type: ButtonType.Circle, stateEffect: false }) {
-            SymbolGlyph($r('sys.symbol.chevron_left'))
-              .fontSize(20)
-              .fontColor([Color.White])
-          }
-          .width(40)
-          .height(40)
-          .backgroundColor('#24000000')
-          .border({ width: 1, color: '#26FFFFFF', radius: 20 })
-          .shadow(ShadowStyle.OUTER_DEFAULT_XS)
-          .onClick(() => {
-            this.onBack()
-          })
-
-          Blank()
-        }
-        .width('100%')
-        .alignItems(VerticalAlign.Center)
+        Column({ space: 14 }) {
+          Text(this.albumTitle)
+            .fontSize(26)
+            .fontWeight(FontWeight.Bold)
+            .textAlign(TextAlign.Center)
+            .fontColor('#FFFFFFFF')
+            .maxLines(2)
+            .textOverflow({ overflow: TextOverflow.Ellipsis })
+            .width('100%')
 
-        Blank()
+          Text(this.getAlbumArtistText())
+            .fontSize(18)
+            .lineHeight(21)
+            .textAlign(TextAlign.Center)
+            .fontWeight(FontWeight.Bold)
+            .fontColor('#D8FFFFFF')
+            .maxLines(1)
+            .textOverflow({ overflow: TextOverflow.Ellipsis })
+            .width('100%')
 
-        Column({ space: 14 }) {
-          Column({ space: 8 }) {
-            Row({ space: 8 }) {
-              this.buildHeroTag(this.getAlbumSourceText())
-              this.buildHeroTag(this.songs.length + ' 首歌曲')
-            }
-
-            Text(this.albumTitle)
-              .fontSize(26)
-              .fontWeight(FontWeight.Bold)
-              .textAlign(TextAlign.Start)
-              .fontColor('#FFFFFFFF')
-              .maxLines(2)
-              .textOverflow({ overflow: TextOverflow.Ellipsis })
-              .width('100%')
-
-            Text(this.getAlbumArtistText())
-              .fontSize(15)
-              .lineHeight(21)
-              .textAlign(TextAlign.Start)
-              .fontColor('#D8FFFFFF')
-              .maxLines(1)
-              .textOverflow({ overflow: TextOverflow.Ellipsis })
-              .width('100%')
-          }
-          .width('100%')
-          .alignItems(HorizontalAlign.Start)
+          this.buildHeroTag(this.songs.length + ' 首歌曲')
 
           this.buildHeaderActions()
         }
         .width('100%')
-        .alignItems(HorizontalAlign.Start)
+        .alignItems(HorizontalAlign.Center)
       }
       .width('100%')
-      .height(410)
+      .height(320)
       .padding({ left: 18, right: 18, top: this.topSafeHeight + 8, bottom: 26 })
     }
     .width('100%')
-    .height(410)
+    .height(320)
   }
 
-  @Builder
-  private buildSongSectionHeader() {
-    Row() {
-      Text('曲目列表')
-        .fontSize(18)
-        .fontWeight(FontWeight.Bold)
-        .fontColor(this.getPrimaryTextColor())
 
-      Blank()
-
-      this.buildSourceTag(this.songs.length + ' 首')
-    }
-    .width('100%')
-    .padding({ left: 16, right: 16, top: 2, bottom: 4 })
-  }
 
   @Builder
-  private buildSongCard(item: VideoItem, index: number) {
+  private buildSongCard(item: VideoItem) {
     Row({ space: 12 }) {
-      Stack({ alignContent: Alignment.Center }) {
-        Column() {
-          Blank()
-        }
-        .width(34)
-        .height(34)
-        .backgroundColor('#F1ECF8')
-        .borderRadius(17)
-
-        Text(this.getSongIndexText(item, index))
-          .fontSize(12)
-          .fontWeight(FontWeight.Medium)
-          .fontColor(this.getThemeAccent())
-      }
-
       Image(this.getSongCover(item))
-        .width(58)
-        .height(58)
-        .borderRadius(18)
+        .width(52)
+        .height(52)
+        .borderRadius(8)
         .objectFit(ImageFit.Cover)
 
       Column({ space: 6 }) {
@@ -320,7 +252,7 @@ export struct FindAlbumDetail {
           .width('100%')
 
         Text(this.getSongSubtitle(item))
-          .fontSize(12)
+          .fontSize(13)
           .lineHeight(17)
           .fontColor(this.getSecondaryTextColor())
           .maxLines(1)
@@ -331,27 +263,19 @@ export struct FindAlbumDetail {
       .alignItems(HorizontalAlign.Start)
 
       Column({ space: 8 }) {
-        Text(item.duration ? item.duration : '--:--')
-          .fontSize(11)
-          .fontColor(this.getSecondaryTextColor())
-
-        SymbolGlyph($r('sys.symbol.play_fill'))
-          .fontSize(13)
-          .fontColor([this.getThemeAccent()])
-          .effectStrategy(SymbolEffectStrategy.HIERARCHICAL)
+        PlayingIndicator({
+          isActive: this.isPlaying && this.currentSong?.filePath === item.filePath,
+          indicatorSize: 18,
+          marginRight: 20,
+          marginTop: 8,
+          marginBottom: 8
+        })
       }
       .alignItems(HorizontalAlign.End)
     }
     .width('100%')
     .padding({ left: 14, right: 14, top: 14, bottom: 14 })
     .backgroundColor('#FBFAFD')
-    .borderRadius(24)
-    .border({ width: 1, color: '#0F000000', radius: 24 })
-    .shadow({ radius: 12, color: '#12000000', offsetY: 6 })
-    .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.985 })
-    .onClick(() => {
-      this.onSongTap(index)
-    })
   }
 
   @Builder
@@ -380,29 +304,84 @@ export struct FindAlbumDetail {
     .justifyContent(FlexAlign.Center)
   }
 
+
   build() {
+    Stack() {
+
+      this.buildContentView();
+
+      // 顶部区域:标题栏在上,面包屑在下
+      Column() {
+        this.topTitleBar()
+      }
+      .width('100%')
+      .animation({
+        duration: 500,
+        curve: Curve.Friction  // 可选动画曲线
+      })
+      .position({ top: 0, left: 0 })
+      // .backgroundColor($r('app.color.start_window_background'))
+
+
+    }
+    .width('100%')
+    .height('100%')
+    .alignContent(Alignment.Bottom)
+    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
+  }
+
+  @Builder
+  private topTitleBar() {
+    Column() {
+      Row({ space: 12 }) {
+        Button({ type: ButtonType.Circle, stateEffect: true }) {
+          SymbolGlyph($r('sys.symbol.chevron_left'))
+            .attributeModifier(new SymbolGlyphFancyModifier(24, '', ''))
+        }
+        .attributeModifier(new ButtonFancyModifier(40, 40))
+        .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.6 })
+        .animation({ duration: 300, curve: Curve.Ease })
+        .onClick(() => {
+           this.onBack()
+        })
+        .attributeModifier(new ShadowModifier())
+        .zIndex(0)
+    }
+    .padding({ top: this.topSafeHeight + 10, left: 10, right: 10, bottom: 6 })
+    .width('100%')
+    .backgroundColor(Color.Transparent)
+    }
+  }
+
+  @Builder
+  buildContentView() {
     List({ space: 12 }) {
       ListItem() {
         this.buildHeroHeader()
       }
 
       if (this.songs.length === 0) {
-        ListItem() {
-          this.buildSongSectionHeader()
-        }
-
         ListItem() {
           this.buildEmptyState()
         }
         .padding({ left: 16, right: 16 })
       } else {
-        ListItem() {
-          this.buildSongSectionHeader()
-        }
-
         ForEach(this.songs, (item: VideoItem, index: number) => {
           ListItem() {
-            this.buildSongCard(item, index)
+            PointLightContentButton({
+              pointColor: this.getThemeAccent(),
+              buttonColor: '#00FFFFFF',
+              buttonRadius: 15,
+              pointLightHeight: 132,
+              useShadow: true,
+              builder: () => {
+                this.buildSongCard(item)
+              }
+            })
+            .width('100%')
+            .onClick(() => {
+              this.onSongTap(index)
+            })
           }
           .padding({ left: 16, right: 16 })
         }, getFindAlbumSongKey)
@@ -412,7 +391,7 @@ export struct FindAlbumDetail {
     .height('100%')
     .scrollBar(BarState.Off)
     .edgeEffect(EdgeEffect.Spring)
-    .backgroundColor('#F7F5FB')
-    .padding({ bottom: this.bottomSafeHeight + 18 })
+    .backgroundColor($r('app.color.start_window_background'))
+    .padding({ bottom: this.bottomSafeHeight + 75 })
   }
 }

+ 199 - 7
entry/src/main/ets/view/FindView.ets

@@ -387,6 +387,194 @@ export struct FindView {
     return result
   }
 
+  private isSameSongSelection(left: VideoItem[], right: VideoItem[]): boolean {
+    if (left.length !== right.length) {
+      return false
+    }
+    for (let i = 0; i < left.length; i++) {
+      if (left[i].filePath !== right[i].filePath) {
+        return false
+      }
+    }
+    return true
+  }
+
+  private isSameLeadingSongs(left: VideoItem[], right: VideoItem[], count: number): boolean {
+    const safeCount = Math.min(count, left.length, right.length)
+    for (let i = 0; i < safeCount; i++) {
+      if (left[i].filePath !== right[i].filePath) {
+        return false
+      }
+    }
+    return safeCount > 0
+  }
+
+  private isSameAlbumSelection(left: FindAlbumGroup[], right: FindAlbumGroup[]): boolean {
+    if (left.length !== right.length) {
+      return false
+    }
+    for (let i = 0; i < left.length; i++) {
+      if (left[i].id !== right[i].id) {
+        return false
+      }
+    }
+    return true
+  }
+
+  private isSameLeadingAlbums(left: FindAlbumGroup[], right: FindAlbumGroup[], count: number): boolean {
+    const safeCount = Math.min(count, left.length, right.length)
+    for (let i = 0; i < safeCount; i++) {
+      if (left[i].id !== right[i].id) {
+        return false
+      }
+    }
+    return safeCount > 0
+  }
+
+  private rotateSongs(items: VideoItem[], offset: number): VideoItem[] {
+    if (items.length === 0) {
+      return []
+    }
+    const safeOffset = ((offset % items.length) + items.length) % items.length
+    if (safeOffset === 0) {
+      return items.slice()
+    }
+    return items.slice(safeOffset).concat(items.slice(0, safeOffset))
+  }
+
+  private rotateAlbums(items: FindAlbumGroup[], offset: number): FindAlbumGroup[] {
+    if (items.length === 0) {
+      return []
+    }
+    const safeOffset = ((offset % items.length) + items.length) % items.length
+    if (safeOffset === 0) {
+      return items.slice()
+    }
+    return items.slice(safeOffset).concat(items.slice(0, safeOffset))
+  }
+
+  private ensureDifferentLeadingSongs(next: VideoItem[], current: VideoItem[]): VideoItem[] {
+    const pageSize = this.getSectionPageSize(this.getDiscoverSectionColumns())
+    if (!this.isSameLeadingSongs(next, current, pageSize)) {
+      return next
+    }
+    if (next.length <= pageSize) {
+      return next
+    }
+    const rotated = this.rotateSongs(next, pageSize)
+    if (!this.isSameLeadingSongs(rotated, current, pageSize)) {
+      return rotated
+    }
+    return next
+  }
+
+  private ensureDifferentLeadingAlbums(next: FindAlbumGroup[], current: FindAlbumGroup[]): FindAlbumGroup[] {
+    const pageSize = this.getSectionPageSize(this.getDiscoverSectionColumns())
+    if (!this.isSameLeadingAlbums(next, current, pageSize)) {
+      return next
+    }
+    if (next.length <= pageSize) {
+      return next
+    }
+    const rotated = this.rotateAlbums(next, pageSize)
+    if (!this.isSameLeadingAlbums(rotated, current, pageSize)) {
+      return rotated
+    }
+    return next
+  }
+
+  private pickDifferentPreferredSongs(items: VideoItem[], count: number, current: VideoItem[]): VideoItem[] {
+    const next = this.pickPreferredSongs(items, count)
+    if (!this.isSameSongSelection(next, current) || items.length <= current.length) {
+      return next
+    }
+
+    const currentSet: Set<string> = new Set<string>()
+    for (let i = 0; i < current.length; i++) {
+      currentSet.add(current[i].filePath)
+    }
+
+    const differentItems: VideoItem[] = []
+    for (let i = 0; i < items.length; i++) {
+      const item = items[i]
+      if (currentSet.has(item.filePath)) {
+        continue
+      }
+      differentItems.push(item)
+    }
+
+    if (differentItems.length === 0) {
+      return next
+    }
+
+    const refreshed = this.pickPreferredSongs(differentItems, count)
+    if (refreshed.length >= Math.min(count, items.length)) {
+      return refreshed
+    }
+
+    const result: VideoItem[] = refreshed.slice()
+    const seen: Set<string> = new Set<string>()
+    for (let i = 0; i < result.length; i++) {
+      seen.add(result[i].filePath)
+    }
+
+    for (let i = 0; i < next.length && result.length < count; i++) {
+      const item = next[i]
+      if (seen.has(item.filePath)) {
+        continue
+      }
+      seen.add(item.filePath)
+      result.push(item)
+    }
+    return result
+  }
+
+  private pickDifferentAlbumGroups(items: FindAlbumGroup[], count: number, current: FindAlbumGroup[]): FindAlbumGroup[] {
+    const next = this.pickAlbumGroups(items, count)
+    if (!this.isSameAlbumSelection(next, current) || items.length <= current.length) {
+      return next
+    }
+
+    const currentSet: Set<string> = new Set<string>()
+    for (let i = 0; i < current.length; i++) {
+      currentSet.add(current[i].id)
+    }
+
+    const differentItems: FindAlbumGroup[] = []
+    for (let i = 0; i < items.length; i++) {
+      const item = items[i]
+      if (currentSet.has(item.id)) {
+        continue
+      }
+      differentItems.push(item)
+    }
+
+    if (differentItems.length === 0) {
+      return next
+    }
+
+    const refreshed = this.pickAlbumGroups(differentItems, count)
+    if (refreshed.length >= Math.min(count, items.length)) {
+      return refreshed
+    }
+
+    const result: FindAlbumGroup[] = refreshed.slice()
+    const seen: Set<string> = new Set<string>()
+    for (let i = 0; i < result.length; i++) {
+      seen.add(result[i].id)
+    }
+
+    for (let i = 0; i < next.length && result.length < count; i++) {
+      const item = next[i]
+      if (seen.has(item.id)) {
+        continue
+      }
+      seen.add(item.id)
+      result.push(item)
+    }
+    return result
+  }
+
   private shuffleAlbumGroups(items: FindAlbumGroup[]): FindAlbumGroup[] {
     const copy: FindAlbumGroup[] = items.slice()
     for (let i = copy.length - 1; i > 0; i--) {
@@ -598,31 +786,35 @@ export struct FindView {
   }
 
   private refreshLocalRandomSongs(): void {
-    this.hotSongs = this.pickPreferredSongs(this.localSongsPool, HOT_SECTION_COUNT)
+    this.hotSongs = this.pickDifferentPreferredSongs(this.localSongsPool, HOT_SECTION_COUNT, this.hotSongs)
   }
 
   private refreshCloudSongs(): void {
-    this.remoteSongs = this.pickPreferredSongs(this.remoteSongsPool, CLOUD_SECTION_COUNT)
+    const next = this.pickDifferentPreferredSongs(this.remoteSongsPool, CLOUD_SECTION_COUNT, this.remoteSongs)
+    this.remoteSongs = this.ensureDifferentLeadingSongs(next, this.remoteSongs)
     this.cloudSectionPageIndex = 0
   }
 
   private refreshRecentSongs(): void {
-    this.recentSongs = this.pickPreferredSongs(this.recentSongsPool, RECENT_SECTION_COUNT)
+    this.recentSongs = this.pickDifferentPreferredSongs(this.recentSongsPool, RECENT_SECTION_COUNT, this.recentSongs)
     this.recentSectionPageIndex = 0
   }
 
   private refreshPopularSongs(): void {
-    this.popularSongs = this.pickPreferredSongs(this.topPlayedSongsPool, POPULAR_SECTION_COUNT)
+    const next = this.pickDifferentPreferredSongs(this.topPlayedSongsPool, POPULAR_SECTION_COUNT, this.popularSongs)
+    this.popularSongs = this.ensureDifferentLeadingSongs(next, this.popularSongs)
     this.popularSectionPageIndex = 0
   }
 
   private refreshFeaturedAlbums(): void {
-    this.featuredAlbums = this.pickAlbumGroups(this.featuredAlbumsPool, FEATURED_ALBUM_COUNT)
+    const next = this.pickDifferentAlbumGroups(this.featuredAlbumsPool, FEATURED_ALBUM_COUNT, this.featuredAlbums)
+    this.featuredAlbums = this.ensureDifferentLeadingAlbums(next, this.featuredAlbums)
     this.featuredAlbumPageIndex = 0
   }
 
   private refreshCloudAlbums(): void {
-    this.cloudAlbums = this.pickAlbumGroups(this.cloudAlbumsPool, CLOUD_ALBUM_COUNT)
+    const next = this.pickDifferentAlbumGroups(this.cloudAlbumsPool, CLOUD_ALBUM_COUNT, this.cloudAlbums)
+    this.cloudAlbums = this.ensureDifferentLeadingAlbums(next, this.cloudAlbums)
     this.cloudAlbumPageIndex = 0
   }
 
@@ -1394,7 +1586,7 @@ export struct FindView {
 
       PointLightActionButton({
         text: '随心所欲',
-        iconResource: $r('sys.symbol.music_note_list'),
+        iconResource: $r('sys.symbol.shuffle'),
         pointColor: this.themeColor,
         textColor: $r('app.color.text_color'),
         buttonColor: this.getCardBackgroundColor()

+ 1 - 1
entry/src/main/ets/view/LocalMusic.ets

@@ -9103,7 +9103,7 @@ export struct LocalMusic {
     } catch (err) {
       const error = err as Error;
       Logger.error('heanup LocalMusic', `loadPage error: ${error.message}`);
-      ToastUtil.showToast('加载数据失败');
+      // ToastUtil.showToast('加载数据失败');
       this.isLoadingPage = false;
       this.hasMoreData = false;
     }

+ 3 - 2
entry/src/main/ets/viewmodel/MainViewModel.ets

@@ -46,11 +46,12 @@ export  class  MainViewModel{
   //测滑菜单的数据
   getDrawerData(): Array<ItemData> {
     let drawerGridData: ItemData[] = [
-      new ItemData($r('app.string.local_music'), { type: 'symbol', value: $r('sys.symbol.music') }, MainViewModel.MENU_MUSIC, false),
+      new ItemData($r('app.string.find_music'), { type: 'symbol', value: $r('sys.symbol.music_note_circle') }, MainViewModel.MENU_FIND, false),
+      new ItemData($r('app.string.dir'), { type: 'symbol', value: $r('sys.symbol.music') }, MainViewModel.MENU_MUSIC, false),
       new ItemData($r('app.string.media_ku'), $r('app.media.hm_playlist'),MainViewModel.MENU_MIEDIA_KU,false),
       new ItemData($r('app.string.artist'), $r('app.media.kp_music'),MainViewModel.MENU_MIEDIA_ARTIST,false),
       new ItemData($r('app.string.album'), $r('app.media.llq'),MainViewModel.MENU_MIEDIA_ALBUM,false),
-      new ItemData($r('app.string.find_music'), { type: 'symbol', value: $r('sys.symbol.music_note_circle') }, MainViewModel.MENU_FIND, false),
+
       // new ItemData($r('app.string.user_center'), { type: 'symbol', value: $r('sys.symbol.person') }, MainViewModel.MENU_USER, false),
       new ItemData($r('app.string.file_scan'), { type: 'symbol', value: $r('sys.symbol.doc_text_badge_magnifyingglass') },MainViewModel.MENU_FILE_SCAN,false),
 

+ 4 - 0
entry/src/main/resources/base/element/string.json

@@ -726,6 +726,10 @@
     {
       "name": "find_music",
       "value": "发现页"
+    },
+    {
+      "name": "dir",
+      "value": "文件夹"
     }
   ]
 }