|
|
@@ -0,0 +1,233 @@
|
|
|
+import { common, ConfigurationConstant } from '@kit.AbilityKit';
|
|
|
+import { CommonConstants } from '../common/constants/CommonConstants';
|
|
|
+import { VideoItem } from '../viewmodel/VideoItem';
|
|
|
+import { LazyDataSource } from '../common/util/LazyDataSource';
|
|
|
+import { LogUtil, PreferencesUtil, StrUtil, ToastUtil } from '@pura/harmony-utils';
|
|
|
+import fs from '@ohos.file.fs';
|
|
|
+import { changeMusicCover, findLocalCoverImage, getApiLyric, repairAudioMetadata,
|
|
|
+ searchCover,
|
|
|
+ syncLyricToDB} from '../common/util/MusicTagUtils';
|
|
|
+import { util } from '@kit.ArkTS';
|
|
|
+import { FFMpegTags } from '../common/util/Utility';
|
|
|
+import MediaTable from '../common/util/MediaTable';
|
|
|
+
|
|
|
+
|
|
|
+// 批量编辑标签
|
|
|
+@Component
|
|
|
+export struct ChartsCount {
|
|
|
+ private listScroller: ListScroller = new ListScroller()
|
|
|
+ @State isLyric:boolean = true
|
|
|
+ @State isCover:boolean = true
|
|
|
+ @Link isShowDrawer: boolean;
|
|
|
+ @Link offsetX: number;
|
|
|
+ @State dataSource: LazyDataSource<VideoItem> = new LazyDataSource([])
|
|
|
+ @State selectedFiles: Array<VideoItem> = []
|
|
|
+ @StorageProp('topRectHeight') topRectHeight: number = 0;
|
|
|
+ @State isDarkMode: boolean = false
|
|
|
+ @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number =
|
|
|
+ ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
|
|
|
+ @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR;
|
|
|
+ context = this.getUIContext().getHostContext() as common.UIAbilityContext
|
|
|
+
|
|
|
+ private table: MediaTable = new MediaTable(this.context)
|
|
|
+
|
|
|
+
|
|
|
+ onColorModeChange() {
|
|
|
+ this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
|
|
|
+ }
|
|
|
+
|
|
|
+ async aboutToAppear() {
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
+ this.table.getRdbStore(this.context, (err:Error) => {
|
|
|
+ err ? reject(err) : resolve();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.table.queryByPlayCountDesc(0, async (result: VideoItem[]) => {
|
|
|
+ this.selectedFiles = result
|
|
|
+ // 确保 selectedFiles 有默认值后再初始化 dataSource
|
|
|
+ if (this.selectedFiles && this.selectedFiles.length > 0) {
|
|
|
+ // this.dataSource = new LazyDataSource(this.selectedFiles)
|
|
|
+ this.dataSource.pushArrayData(this.selectedFiles)
|
|
|
+ } else {
|
|
|
+ this.dataSource = new LazyDataSource([])
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ build() {
|
|
|
+ Column(){
|
|
|
+ this.topTitleBar()
|
|
|
+ this.listView()
|
|
|
+
|
|
|
+ }
|
|
|
+ .height('100%')
|
|
|
+ .width('100%')
|
|
|
+ .backgroundColor($r('app.color.index_background'))
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ listView() {
|
|
|
+ Column(){
|
|
|
+ List({ scroller: this.listScroller }) {
|
|
|
+ // ListItemGroup({ header: this.listHeader() }) {
|
|
|
+ LazyForEach(this.dataSource, (item: VideoItem, index: number) => {
|
|
|
+ ListItem() {
|
|
|
+ Column() {
|
|
|
+ this.MusicItem(item, index)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .borderRadius(14)
|
|
|
+ .backgroundColor($r('app.color.start_window_background'))
|
|
|
+ .margin({top:7,bottom:7})
|
|
|
+ .transition(TransitionEffect.asymmetric(
|
|
|
+ TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
|
|
|
+ TransitionEffect.scale({ x: 0, y: 0 })
|
|
|
+ ))
|
|
|
+ .clickEffect({ level: ClickEffectLevel.LIGHT })
|
|
|
+ }, (item: VideoItem) => item.filePath)
|
|
|
+ // }
|
|
|
+
|
|
|
+ }
|
|
|
+ .cachedCount(2)
|
|
|
+ // .layoutWeight(1)
|
|
|
+ // .height('100%')
|
|
|
+ .transition(TransitionEffect.asymmetric(
|
|
|
+ TransitionEffect.scale({ x: 1.2, y: 1.2 }).animation({ duration: 500 }),
|
|
|
+ TransitionEffect.scale({ x: 0, y: 0 })
|
|
|
+ ))
|
|
|
+
|
|
|
+ }
|
|
|
+ .borderRadius(20)
|
|
|
+ .padding({top:10,bottom:6})
|
|
|
+ .height('auto')
|
|
|
+ .margin({top:20,right:20,left:20})
|
|
|
+ .layoutWeight(1)
|
|
|
+ .height('100%')
|
|
|
+ }
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ listHeader() {
|
|
|
+ Stack({alignContent:Alignment.Start}){
|
|
|
+ Text(`共${this.selectedFiles.length}首歌`)
|
|
|
+ .fontSize(14)
|
|
|
+ .maxLines(1)
|
|
|
+ .textAlign(TextAlign.Start)
|
|
|
+ .padding({ left: 25 })
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ .margin({bottom:6,top:4,left: 6 })
|
|
|
+ }
|
|
|
+ .height('auto').width('100%')
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ topTitleBar() {
|
|
|
+ // 顶部安全区和自定义标题栏
|
|
|
+ Column() {
|
|
|
+ // 顶部安全区
|
|
|
+ Blank()
|
|
|
+ .height(this.topRectHeight)
|
|
|
+ .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
|
|
|
+ .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
|
|
|
+ // 自定义标题栏(Stack实现绝对居中)
|
|
|
+ Stack() {
|
|
|
+ // 居中标题
|
|
|
+ Text('歌曲统计')
|
|
|
+ .fontSize(18)
|
|
|
+ .fontColor(Color.White)
|
|
|
+ .align(Alignment.Center)
|
|
|
+ // 左右按钮
|
|
|
+ Row() {
|
|
|
+ Image($r('app.media.menu'))
|
|
|
+ .width(26)
|
|
|
+ .height(26)
|
|
|
+ .margin({ left: 12, right: 8 })
|
|
|
+ .onClick(() => {
|
|
|
+ this.getUIContext().animateTo({ duration: 666 }, () => {
|
|
|
+ // 动画闭包内控制Image组件的出现和消失
|
|
|
+ this.isShowDrawer = !this.isShowDrawer
|
|
|
+ this.offsetX = 0
|
|
|
+ })
|
|
|
+ })
|
|
|
+ Blank().flexGrow(1)
|
|
|
+ Blank().width(32)
|
|
|
+ }
|
|
|
+ .height(48)
|
|
|
+ .width('100%')
|
|
|
+ .alignItems(VerticalAlign.Center)
|
|
|
+ }
|
|
|
+ .height(48)
|
|
|
+ .width('100%')
|
|
|
+ .backgroundColor(this.isDarkMode ? $r('app.color.title_bar_bg') : this.themeColor)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Builder
|
|
|
+ private MusicItem(item: VideoItem, index?: number) {
|
|
|
+ Button({ type: ButtonType.Normal, stateEffect: true }) {
|
|
|
+ Column() {
|
|
|
+ Row() {
|
|
|
+ Image(item.pixelMapPath)
|
|
|
+ .width(80)
|
|
|
+ .height(80)
|
|
|
+ .borderRadius(8)
|
|
|
+ .alt($r('app.media.music_red'))
|
|
|
+ .alignSelf(ItemAlign.Center)
|
|
|
+ .interpolation(ImageInterpolation.Medium)// 用于重采样后的抗锯齿
|
|
|
+ .autoResize(true) // 重采样,可减少内存占用
|
|
|
+ .padding({ left: 10,top:3,bottom:3 })
|
|
|
+ Column(){
|
|
|
+ Text(item.name)
|
|
|
+ .fontSize(16)
|
|
|
+ .maxLines(1)
|
|
|
+ .textOverflow({ overflow: TextOverflow.MARQUEE })//超长滚动
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ .padding({ left: 10 })
|
|
|
+ .textAlign(TextAlign.Start)
|
|
|
+ .margin({ left: 5 })
|
|
|
+ Text(StrUtil.isEmpty(item.artist) ? item.cTime : item.artist )
|
|
|
+ .fontSize(14)
|
|
|
+ .fontColor(Color.Gray)
|
|
|
+ .textOverflow({ overflow: TextOverflow.MARQUEE })//超长滚动
|
|
|
+ .textAlign(TextAlign.Start)
|
|
|
+ .padding({ top: 5,left: 10 })
|
|
|
+ .margin({ left: 5 })
|
|
|
+ }
|
|
|
+ .alignItems(HorizontalAlign.Start)
|
|
|
+
|
|
|
+ Blank()
|
|
|
+ // 根据嵌入状态显示勾选图标
|
|
|
+ Text(item.playCount+'')
|
|
|
+ .fontSize(15)
|
|
|
+ .maxLines(1)
|
|
|
+ .padding({ right: 5 })
|
|
|
+ .textOverflow({ overflow: TextOverflow.MARQUEE })
|
|
|
+ .animation({
|
|
|
+ duration: 555,
|
|
|
+ curve: 'Linear',
|
|
|
+ })
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ .margin({ right: 18 })
|
|
|
+
|
|
|
+ }
|
|
|
+ .layoutWeight(1)
|
|
|
+ .height('100%')
|
|
|
+ .width('100%')
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .backgroundColor(Color.Transparent)
|
|
|
+ .width('100%')
|
|
|
+ .height(99)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|