| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- 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 { AudioQuality, FFMpegTags } from '../common/util/Utility';
- import MediaTable from '../common/util/MediaTable';
- import { McPieChart, Options } from '@mcui/mccharts'
- import { ComponentContent } from '@kit.ArkUI';
- // 批量编辑标签
- @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 mediaKuCount: number = 0;
- @State albumCount: number = 0;
- @State artistCount: number = 0;
- @State lqCount: number = 0;
- @State sqCount: number = 0;
- @State hqCount: number = 0;
- @State losslessCount: number = 0;
- @State hrCount: 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 contentNode?: ComponentContent<Object> = undefined;
- @State isRefreshing: boolean = false;
- @State ratio: number = 1;
- @State maxRefreshingHeight: number = 100.0;
- private table: MediaTable = new MediaTable(this.context)
- @State defOption: Options = new Options({
- title: {
- show: true,
- text: '曲库统计',
- left: 40,
- top: 20
- },
- series:[
- {
- data:[
- {value:this.mediaKuCount, name:'媒体库'},
- {value:this.artistCount, name:'艺术家'},
- {value:this.albumCount, name:'专辑'},
- ]
- }
- ]
- })
- @State HrOption: Options = new Options({
- title: {
- show: true,
- text: '音质统计',
- left: 40,
- top: 20
- },
- series:[
- {
- data:[
- {value:this.lqCount, name:'LQ'},
- {value:this.sqCount, name:'SQ'},
- {value:this.hqCount, name:'HQ'},
- {value:this.losslessCount, name:'Lossless'},
- {value:this.hrCount, name:'Hi-Res'},
- ]
- }
- ]
- })
- onColorModeChange() {
- this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
- }
- async aboutToAppear() {
- let uiContext = this.getUIContext();
- this.contentNode = new ComponentContent(uiContext, wrapBuilder(customRefreshingContent));
- this.centerChart()
- }
- async centerChart(){
- this.mediaKuCount = PreferencesUtil.getNumberSync('mediaKuCount', 0)
- this.artistCount = PreferencesUtil.getNumberSync('artistCount', 0)
- this.albumCount = PreferencesUtil.getNumberSync('albumCount', 0)
- setTimeout(() => {
- // 使用Option实例对象的setVal方法来实现,修改什么属性就传什么
- this.defOption.setVal({
- animation:true,
- series: [
- {
- data:[
- {value:this.mediaKuCount, name:'媒体库'},
- {value:this.artistCount, name:'艺术家'},
- {value:this.albumCount, name:'专辑'},
- ]
- }
- ]
- })
- }, 1000)
- await new Promise<void>((resolve, reject) => {
- this.table.getRdbStore(this.context, (err:Error) => {
- err ? reject(err) : resolve();
- });
- });
- this.table.queryByPlayCountDesc(1000, 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([])
- }
- })
- this.table.countSongsByQualityOptimized(async (result:Record<AudioQuality, number>) => {
- this.lqCount = result.LQ
- this.hqCount = result.HQ
- this.hrCount = result.HR
- this.sqCount = result.SQ
- setTimeout(() => {
- // 使用Option实例对象的setVal方法来实现,修改什么属性就传什么
- this.HrOption.setVal({
- animation:true,
- series:[
- {
- data:[
- {value:this.lqCount, name:'LQ'},
- {value:this.hqCount, name:'HQ'},
- {value:this.sqCount, name:'SQ'},
- {value:this.hrCount, name:'Hi-Res'},
- ]
- }
- ]
- })
- }, 1000)
- })
- }
- build() {
- Column(){
- this.topTitleBar()
- this.listView()
- }
- .height('100%')
- .width('100%')
- .backgroundColor($r('app.color.index_background'))
- }
- @Builder
- centerCharts() {
- Row() {
- Swiper() {
- McPieChart({
- options: this.defOption
- })
- McPieChart({
- options: this.HrOption
- })
- }
- }
- .borderRadius(14)
- .backgroundColor($r('app.color.start_window_background'))
- .height('35%')
- .margin({bottom:10})
- }
- @Builder
- listView() {
- Column(){
- Refresh({ refreshing: $$this.isRefreshing, refreshingContent: this.contentNode }) {
- List({ scroller: this.listScroller }) {
- ListItemGroup({ header: this.centerCharts() }) {
- ListItem() {
- Column() {
- Text('听歌次数排行榜')
- .fontSize(15)
- .maxLines(1)
- .fontWeight(FontWeight.Bold)
- .textAlign(TextAlign.Start)
- .padding({ left: 10 })
- .fontColor($r('app.color.text_color'))
- .margin({bottom:6,top:4,left: 1 })
- }
- }
- 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 })
- ))
- }
- .pullDownRatio(this.ratio)
- .pullToRefresh(true)
- .refreshOffset(64)
- .onOffsetChange((offset: number) => {
- // 越接近最大距离,下拉跟手系数越小。
- this.ratio = 1 - Math.pow((offset / this.maxRefreshingHeight), 3);
- })
- .onStateChange((refreshStatus: RefreshStatus) => {
- console.info('onecold Refresh onStatueChange state is ' + refreshStatus);
- })
- .onRefreshing(async () => {
- await this.centerChart()
- setTimeout(() => {
- this.isRefreshing = false;
- }, 2000)
- console.log('onRefreshing test');
- })
- }
- .borderRadius(20)
- .padding({top:10,bottom:6})
- .height('auto')
- .margin({top:10,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() {
- Stack({ alignContent: Alignment.TopStart }) {
- Image(item.pixelMapPath)
- .width(75)
- .height(70)
- .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(17)
- .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(15)
- .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(index < 3?18:16)
- .maxLines(1)
- .padding({ right: 5 })
- .textOverflow({ overflow: TextOverflow.MARQUEE })
- .animation({
- duration: 555,
- curve: 'Linear',
- })
- .fontColor(index < 3?this.themeColor:$r('app.color.text_color'))
- .margin({ right: 18 })
- }
- .layoutWeight(1)
- .height('100%')
- .width('100%')
- }
- }
- .backgroundColor(Color.Transparent)
- .width('100%')
- .height(89)
- }
- }
- @Builder
- function customRefreshingContent() {
- Stack() {
- Row() {
- LoadingProgress().height(32)
- }
- .alignItems(VerticalAlign.Center)
- }
- .align(Alignment.Center)
- .clip(true)
- // 设置最小高度约束保证自定义组件高度随刷新区域高度变化时自定义组件高度不会低于minHeight。
- .constraintSize({ minHeight: 32 })
- .width("100%")
- }
|