Ver Fonte

WebDavMainPage 点击进入文件夹如果是很多文件夹 这个进度条转圈圈应该显示在根目录右边的图片上 转圈圈在图片边框 加上这个功能

onecold há 4 meses atrás
pai
commit
58bb0ab4fb

+ 104 - 154
entry/src/main/ets/pages/WebDavMainPage.ets

@@ -1,4 +1,4 @@
-import { BreadcrumbItem, RemoteDirectorySnapshot, RemoteDriveGlobalSearchResult, RemoteDriveManager } from '../common/util/RemoteDriveManager';
+import { BreadcrumbItem, RemoteDriveGlobalSearchResult, RemoteDriveManager } from '../common/util/RemoteDriveManager';
 import { WebDavAccount } from '../viewmodel/WebDavAccount';
 import { Song } from '../viewmodel/Song';
 import { RemoteDriveManagerStates } from '../common/enums/RemoteDriveManagerStates';
@@ -131,6 +131,7 @@ export struct WebDavMainPage {
   @Link isShowDrawer: boolean;
   @State isLoading: boolean = false;
   @State isRefreshingCache: boolean = false;
+  @State isDirectoryNavigationLoading: boolean = false;
   private webDavFiles: FileInfo[] = []; // 原始目录数据保持为普通字段,避免大数组响应式代理卡顿
   @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR;
   @StorageProp('isDarkMode') isDarkMode: boolean = false;
@@ -173,7 +174,6 @@ export struct WebDavMainPage {
   };
   private downloadCenterRefreshTimer: number = -1;
   private displayReloadToken: number = 0;
-  private pendingDirectoryRefreshTimer: number = -1;
   private pendingDirectoryRefreshToken: number = 0;
 
   private async runSerializedThumbnailFfmpeg(task: () => Promise<void>): Promise<void> {
@@ -271,19 +271,23 @@ export struct WebDavMainPage {
   }
 
   private cancelPendingDirectoryRefresh(): void {
-    if (this.pendingDirectoryRefreshTimer >= 0) {
-      clearTimeout(this.pendingDirectoryRefreshTimer)
-      this.pendingDirectoryRefreshTimer = -1
-    }
     this.pendingDirectoryRefreshToken += 1
   }
 
-  private scheduleDirectoryRefresh(previewPath: string | undefined, loadAction: () => Promise<void>,
+  private startDirectoryNavigationLoading(): void {
+    this.isDirectoryNavigationLoading = true
+  }
+
+  private stopDirectoryNavigationLoading(): void {
+    this.isDirectoryNavigationLoading = false
+  }
+
+  private scheduleDirectoryRefresh(_targetPath: string | undefined, loadAction: () => Promise<void>,
     errorPrefix: string): void {
     this.cancelPendingDirectoryRefresh()
+    this.startDirectoryNavigationLoading()
     const refreshToken: number = this.pendingDirectoryRefreshToken
-    const hasPreview: boolean = previewPath !== undefined ? this.showDirectoryPreviewCache(previewPath) : false
-    this.isLoading = !hasPreview
+    this.isLoading = true
     this.isRefreshingCache = false
 
     const executeLoad = (): void => {
@@ -297,18 +301,11 @@ export struct WebDavMainPage {
         Logger.error(TAG, `${errorPrefix}: ${error.message}`)
         this.isLoading = false
         this.isRefreshingCache = false
+        this.stopDirectoryNavigationLoading()
       })
     }
 
-    if (!hasPreview) {
-      executeLoad()
-      return
-    }
-
-    this.pendingDirectoryRefreshTimer = setTimeout(() => {
-      this.pendingDirectoryRefreshTimer = -1
-      executeLoad()
-    }, 220) as number
+    executeLoad()
   }
 
   private buildThumbnailIdentity(item: VideoItem): string {
@@ -2218,6 +2215,7 @@ export struct WebDavMainPage {
     // 取消订阅
     this.cancelPendingDirectoryRefresh();
     this.resetRemoteThumbPrefetchState();
+    this.stopDirectoryNavigationLoading();
     this.webdavManager.unsubscribe(this.eventHandler);
     this.downloadCenterManager.unsubscribe(this.downloadCenterListener);
     this.stopDownloadCenterRefresh();
@@ -2229,6 +2227,7 @@ export struct WebDavMainPage {
     switch (event) {
       case RemoteDriveManagerStates.LoadFilesInfoStart:
         this.resetRemoteThumbPrefetchState();
+        this.startDirectoryNavigationLoading();
         if (this.dataSource.totalCount() > 0 || this.visibleFoldersState.length > 0) {
           this.isLoading = false;
           this.isRefreshingCache = true;
@@ -2246,6 +2245,7 @@ export struct WebDavMainPage {
         this.currentDirectoryPath = this.webdavManager.currentPath || '/';
         this.isLoading = false;
         this.isRefreshingCache = false;
+        this.stopDirectoryNavigationLoading();
 
         // 更新可见文件夹列表
         this.updateVisibleFolders();
@@ -2264,6 +2264,7 @@ export struct WebDavMainPage {
       case RemoteDriveManagerStates.LoadFilesInfoFailed:
         this.isLoading = false;
         this.isRefreshingCache = false;
+        this.stopDirectoryNavigationLoading();
         // this.getUIContext().getPromptAction().showToast({ message: '加载失败' });
         break;
       case RemoteDriveManagerStates.InsertAccountSucceed:
@@ -2367,103 +2368,6 @@ export struct WebDavMainPage {
     return -1;
   }
 
-  private cloneSong(item: VideoItem): VideoItem {
-    const clone = new VideoItem(
-      item.name,
-      item.id,
-      item.filePath,
-    item.type,
-    item.videoSize,
-    item.cTime,
-    item.size,
-    item.pixelMapPath,
-    item.artist,
-    item.album,
-    item.fileName,
-      item.lastPlayed
-    );
-    clone.duration = item.duration;
-    clone.mimeType = item.mimeType;
-    clone.trackCount = item.trackCount;
-    clone.sampleRate = item.sampleRate;
-    clone.size = item.size;
-    clone.webdav_account_id = item.webdav_account_id;
-    clone.remote_rel_path = item.remote_rel_path;
-    clone.artist = item.artist;
-    clone.album = item.album;
-    clone.lyricContent = item.lyricContent;
-    clone.pixelMapPath = item.pixelMapPath;
-    clone.isCustomCover = item.isCustomCover;
-    clone.cTime = item.cTime;
-    clone.fileName = item.fileName;
-    clone.md5Str = item.md5Str;
-    clone.bit_rate = item.bit_rate;
-    clone.probe_score = item.probe_score;
-    clone.year = item.year;
-    clone.nb_streams = item.nb_streams;
-    clone.nb_programs = item.nb_programs;
-    clone.genre = item.genre;
-    clone.track = item.track;
-    clone.disc = item.disc;
-    clone.channels = item.channels;
-    clone.channel_layout = item.channel_layout;
-    clone.start_time = item.start_time;
-    clone.ALBUMARTIST = item.ALBUMARTIST;
-    clone.COMPOSER = item.COMPOSER;
-    clone.COMMENT = item.COMMENT;
-    clone.LYRICIST = item.LYRICIST;
-    clone.pyStr = item.pyStr;
-    clone.extra_json = item.extra_json;
-    clone.parentPath = item.parentPath;
-    clone.isFav = item.isFav;
-    clone.playCount = item.playCount;
-    clone.lastPlayed = item.lastPlayed;
-    clone.videoSize = item.videoSize;
-    clone.isFav = item.isFav;
-    return clone;
-  }
-
-  private cloneFolderInfo(item: FileInfo): FileInfo {
-    const clone = new FileInfo(item.rootpath, item.name, item.totalSize, item.time);
-    clone.readOnly = item.readOnly;
-    clone.fileName = item.fileName;
-    clone.href = item.href;
-    clone.contentLength = item.contentLength;
-    clone.isDirectory = item.isDirectory;
-    return clone;
-  }
-
-  private applyDirectoryPreviewSnapshot(snapshot: RemoteDirectorySnapshot, targetPath: string): void {
-    const previewSongs: VideoItem[] = snapshot.songs.map((item: VideoItem) => this.cloneSong(item));
-    const previewFiles: FileInfo[] = snapshot.files.map((item: FileInfo) => this.cloneFolderInfo(item));
-    this.songs = previewSongs;
-    this.webDavFiles = previewFiles;
-    this.currentDirectoryPath = targetPath;
-    this.webdavManager.webDavSongs = previewSongs.slice();
-    this.webdavManager.webDavFiles = previewFiles.slice();
-    this.webdavManager.currentPath = targetPath;
-    this.updateVisibleFolders();
-    this.breadcrumbs = this.webdavManager.getBreadcrumbsForPreview(this.selectedAccount, targetPath);
-    if (this.isSearchMode && this.searchText.length > 0) {
-      void this.applyGlobalSearch(this.searchText, ++this.searchTicket);
-      return;
-    }
-    this.restoreCurrentDirectorySearchView();
-  }
-
-  private showDirectoryPreviewCache(targetPath?: string): boolean {
-    if (!this.selectedAccount) {
-      return false;
-    }
-    const resolvedPath = targetPath && targetPath.length > 0 ? targetPath : (this.selectedAccount.filepath || '/');
-    const preview = this.webdavManager.getDirectoryPreview(this.selectedAccount, resolvedPath);
-    if (!preview) {
-      return false;
-    }
-    this.applyDirectoryPreviewSnapshot(preview, resolvedPath);
-    return true;
-  }
-
   // 加载账户列表
   private loadAccounts(): void {
     this.accounts = this.webdavManager.getAllWebDavAccounts();
@@ -3533,54 +3437,100 @@ export struct WebDavMainPage {
     return this.topSafeHeight + 85
   }
 
+  // 目录切换时统一在当前可见的账户图标外层显示转圈,避免页面中间闪大 loading。
+  @Builder
+  private buildDirectoryNavigationIndicator(iconSize: number, containerSize: number) {
+    Stack({ alignContent: Alignment.Center }) {
+      if (this.isDirectoryNavigationLoading) {
+        // 使用环形进度外圈承载目录切换态,避免在标题栏或页面中央再出现第二套 loading。
+        Progress({ value: 0, total: 100, type: ProgressType.Ring })
+          .width(containerSize + 8)
+          .height(containerSize + 8)
+          .color(this.themeColor)
+          .style({ strokeWidth: 2.5, status: ProgressStatus.LOADING, shadow: false })
+          .scale({ x: -1, y: 1 })
+      }
+
+      Image(this.selectedAccount.coverPath ?
+        this.selectedAccount.coverPath : getCloudDiskIcon(this.selectedAccount.webType))
+        .width(iconSize)
+        .height(iconSize)
+        .alt($r('app.media.cloudDisk'))
+    }
+    .width(containerSize)
+    .height(containerSize)
+    .borderRadius(containerSize / 2)
+    .backgroundColor('#EFEFEF')
+  }
+
   @Builder
   breaker() {
     // 面包屑导航
     Column({ space: 8 }) {
-      // 面包屑导航
-      if (this.currentDirectoryPath !== '') {
+      if (!this.isSearchMode || this.webdavManager.canGoBack()) {
         Row({ space: 8 }) {
-          Button({ type: ButtonType.Circle }) {
-            Image(this.selectedAccount.coverPath?
-              this.selectedAccount.coverPath:getCloudDiskIcon(this.selectedAccount.webType))
-              .width(18)
-              .height(18)
-              .alt($r('app.media.cloudDisk'))
+          // 根目录只展示账号图标和加载态,不再承载返回动作;子目录才点击返回上级。
+          if (this.webdavManager.canGoBack()) {
+            Row() {
+              this.buildDirectoryNavigationIndicator(18, 24)
+            }
+            .width(24)
+            .height(24)
+            .margin({left:5})
+            .clickEffect({ level: ClickEffectLevel.MIDDLE, scale: 0.92 })
+            .onClick(() => this.goBack())
+            .bindContentCover($$this.isShowDownloadCenter, this.DownloadCenterBuilder(),
+              {
+                modalTransition:ModalTransition.DEFAULT,
+                onWillDisappear: () => {
+                  this.isShowDownloadCenter = false
+                },
+              })
+          } else {
+            Row() {
+              this.buildDirectoryNavigationIndicator(18, 24)
+            }
+            .width(24)
+            .height(24)
+            .margin({left:5})
+            .bindContentCover($$this.isShowDownloadCenter, this.DownloadCenterBuilder(),
+              {
+                modalTransition:ModalTransition.DEFAULT,
+                onWillDisappear: () => {
+                  this.isShowDownloadCenter = false
+                },
+              })
           }
-          .width(24)
-          .height(24)
-          .backgroundColor('#EFEFEF')
-          .margin({left:5})
-          .onClick(() => this.goBack())
-          .bindContentCover($$this.isShowDownloadCenter, this.DownloadCenterBuilder(),
-            {
-              modalTransition:ModalTransition.DEFAULT,
-              onWillDisappear: () => {
-                this.isShowDownloadCenter = false
-              },
-            })
 
           Row({ space: 4 }) {
-            ForEach(this.breadcrumbs, (crumb: BreadcrumbItem, index: number) => {
-              Row() {
-                Text(crumb.label)
-                  .fontSize(15)
-                  .fontColor($r('app.color.text_color'))
-                  .maxLines(1)
-                  .textOverflow({ overflow: TextOverflow.Ellipsis })
-              }
-              .onClick(() => {
-                this.navigateToBreadcrumb(crumb);
+            if (this.breadcrumbs.length === 0) {
+              Text('根目录')
+                .fontSize(15)
+                .fontColor($r('app.color.text_color'))
+                .maxLines(1)
+                .textOverflow({ overflow: TextOverflow.Ellipsis })
+            } else {
+              ForEach(this.breadcrumbs, (crumb: BreadcrumbItem, index: number) => {
+                Row() {
+                  Text(crumb.label)
+                    .fontSize(15)
+                    .fontColor($r('app.color.text_color'))
+                    .maxLines(1)
+                    .textOverflow({ overflow: TextOverflow.Ellipsis })
+                }
+                .onClick(() => {
+                  this.navigateToBreadcrumb(crumb);
+                })
+
+                // 添加分隔符(除了最后一个元素)
+                if (index < this.breadcrumbs.length - 1) {
+                  Text('/')
+                    .fontSize(15)
+                    .fontColor($r('app.color.index_tab_font_color'))
+                    .opacity(0.6)
+                }
               })
-
-              // 添加分隔符(除了最后一个元素)
-              if (index < this.breadcrumbs.length - 1) {
-                Text('/')
-                  .fontSize(15)
-                  .fontColor($r('app.color.index_tab_font_color'))
-                  .opacity(0.6)
-              }
-            })
+            }
           }
           .layoutWeight(1)
 

+ 1 - 0
entry/src/main/ets/view/FindView.ets

@@ -3238,6 +3238,7 @@ export struct FindView {
           .aspectRatio(3 / 4)
           .borderRadius(16)
           .width(160)
+          .alt($r('app.media.alt'))
           .objectFit(ImageFit.Cover)
 
         Row() {

+ 2 - 4
entry/src/main/ets/view/LocalMusic.ets

@@ -5905,12 +5905,10 @@ export struct LocalMusic {
     Button({ type: ButtonType.Capsule, stateEffect: true }) {
       Row() {
         SymbolGlyph($r('sys.symbol.folder'))
-          .fontSize(this.twoFingerType==3?48:this.twoFingerType==2?42:38)
+          .fontSize(this.twoFingerType==3?55:this.twoFingerType==2?50:45)
           .fontColor([this.themeColor])
           .alignSelf(ItemAlign.Center)
-          // .height(this.twoFingerType==3?46:this.twoFingerType==2?40:35)
-          // .width(this.twoFingerType==3?46:this.twoFingerType==2?40:35)
-          .margin({ left: 28 ,top:8,bottom:8})
+          .margin({ left: 20 ,top:8,bottom:8})
         Column() {
           Text(item.name.startsWith('.') ? item.name.replace(/\./g, '') : item.name)
             .fontSize(this.twoFingerType == 1 ? 12 : this.twoFingerType == 2 ? 15 : 18)