|
|
@@ -18,7 +18,7 @@ import MediaTable from '../common/util/MediaTable';
|
|
|
@Component
|
|
|
export struct TagsContentCover {
|
|
|
private listScroller: ListScroller = new ListScroller()
|
|
|
- onTagsResult = (_result: boolean) => {
|
|
|
+ onTagsResult = (_result: boolean,deleteCache_path?:string) => {
|
|
|
}
|
|
|
@State isLyric:boolean = true
|
|
|
@State isCover:boolean = true
|
|
|
@@ -45,6 +45,9 @@ export struct TagsContentCover {
|
|
|
|
|
|
// 新增状态用于跟踪每个文件的嵌入状态
|
|
|
@State embedStatusMap: Map<string, boolean> = new Map<string, boolean>();
|
|
|
+ // 分别跟踪歌词和封面嵌入状态
|
|
|
+ @State lyricEmbedStatusMap: Map<string, boolean> = new Map<string, boolean>();
|
|
|
+ @State coverEmbedStatusMap: Map<string, boolean> = new Map<string, boolean>();
|
|
|
|
|
|
|
|
|
onColorModeChange() {
|
|
|
@@ -143,7 +146,7 @@ export struct TagsContentCover {
|
|
|
.fontColor([this.themeColor])
|
|
|
.alignSelf(ItemAlign.Center)
|
|
|
.margin({ left: 15 })
|
|
|
- Text('说明:不是本app路径下的歌曲将在DownLoad/天天静听/内嵌标签文件夹中生成新的内嵌歌曲。')
|
|
|
+ Text('说明:不是本app路径下的歌曲将在[DownLoad/天天静听/批量内嵌]标签文件夹中生成新的内嵌歌曲。如果失败可以多试几次。')
|
|
|
.margin({ left: 5 ,right: 5})
|
|
|
.fontSize(14)
|
|
|
.padding({top:4,bottom:4})
|
|
|
@@ -213,32 +216,61 @@ export struct TagsContentCover {
|
|
|
|
|
|
@Builder
|
|
|
startButton(){
|
|
|
- Stack(){
|
|
|
- Progress({ value: this.currentProgress, total: this.totalFiles,
|
|
|
- type: ProgressType.Capsule }).height(55)
|
|
|
- .margin({top:20,right:20,left:20})
|
|
|
- .backgroundColor($r('app.color.index_background'))
|
|
|
+ Column(){
|
|
|
+
|
|
|
+
|
|
|
Button({ type: ButtonType.Capsule, stateEffect: true }) {
|
|
|
Row() {
|
|
|
- // 菜单图标
|
|
|
- SymbolGlyph($r('sys.symbol.star_trophy'))// .size({ width: 22, height: 22 })
|
|
|
- .fontSize(22)
|
|
|
- .fontColor([this.themeColor])
|
|
|
- .alignSelf(ItemAlign.Center)
|
|
|
- .margin({ left: 25 })
|
|
|
+ if(!this.isEmbedding) {
|
|
|
+ // 菜单图标
|
|
|
+ SymbolGlyph($r('sys.symbol.star_trophy'))
|
|
|
+ .fontSize(22)
|
|
|
+ .fontColor([this.themeColor])
|
|
|
+ .alignSelf(ItemAlign.Center)
|
|
|
+ .margin({ left: 25 })
|
|
|
+
|
|
|
+ // 菜单标题
|
|
|
+ Text('开始内嵌')
|
|
|
+ .margin({ left: 10, right: 20 })
|
|
|
+ .fontSize(15)
|
|
|
+ .fontWeight(480)
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ Blank()
|
|
|
+ // 右侧箭头
|
|
|
+ Image($r('app.media.arrow_right'))
|
|
|
+ .width(22)
|
|
|
+ .height(22)
|
|
|
+ .margin({ left: 0, right: 20 })
|
|
|
+ .align(Alignment.Center)
|
|
|
+ } else {
|
|
|
+ // 处理中的状态
|
|
|
+ SymbolGlyph($r('sys.symbol.hourglass'))
|
|
|
+ .fontSize(22)
|
|
|
+ .fontColor([this.themeColor])
|
|
|
+ .alignSelf(ItemAlign.Center)
|
|
|
+ .margin({ left: 25 })
|
|
|
+
|
|
|
+ Row(){
|
|
|
+ Text(`正在处理: ${this.currentFileIndex}/${this.totalFiles}`)
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ }
|
|
|
+ .width('100%')
|
|
|
+ .margin({left:20,right:8})
|
|
|
|
|
|
- // 菜单标题
|
|
|
- Text('开始内嵌')
|
|
|
- .margin({ left: 10, right: 20 })
|
|
|
- .fontSize(15)
|
|
|
- .fontWeight(480)
|
|
|
- Blank()
|
|
|
- // 右侧箭头
|
|
|
- Image($r('app.media.arrow_right'))
|
|
|
- .width(22)
|
|
|
- .height(22)
|
|
|
- .margin({ left: 0, right: 20 })
|
|
|
- .align(Alignment.Center)
|
|
|
+ Text(`${this.currentProgress}%`)
|
|
|
+ .margin({ left: 5 })
|
|
|
+ .fontSize(15)
|
|
|
+ .fontWeight(480)
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+
|
|
|
+ Blank()
|
|
|
+
|
|
|
+ Text(`成功:${this.embedSuccessCount} 失败:${this.embedFailedCount}`)
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor($r('app.color.text_color'))
|
|
|
+ .margin({ right: 20 })
|
|
|
+ }
|
|
|
}
|
|
|
.width('100%')
|
|
|
}
|
|
|
@@ -248,12 +280,11 @@ export struct TagsContentCover {
|
|
|
.backgroundColor($r('app.color.start_window_background'))
|
|
|
.clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
|
|
|
.onClick(()=>{
|
|
|
- this.startEmbed()
|
|
|
+ if(!this.isEmbedding) {
|
|
|
+ this.startEmbed()
|
|
|
+ }
|
|
|
})
|
|
|
-
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
// 会员功能弹窗
|
|
|
@@ -338,172 +369,194 @@ export struct TagsContentCover {
|
|
|
|
|
|
// 清空之前的嵌入状态
|
|
|
this.embedStatusMap = new Map<string, boolean>();
|
|
|
+ this.lyricEmbedStatusMap = new Map<string, boolean>();
|
|
|
+ this.coverEmbedStatusMap = new Map<string, boolean>();
|
|
|
|
|
|
- // 创建异步任务数组
|
|
|
- const embedTasks = this.selectedFiles.map(async (item: VideoItem, index: number) => {
|
|
|
- try {
|
|
|
- this.currentFileIndex = index + 1;
|
|
|
- this.currentFileName = item.name;
|
|
|
- await PermissionUtil.activatePermission(item.filePath)
|
|
|
-
|
|
|
- let success = true;
|
|
|
- let tempOutPath = ''
|
|
|
- // 1. 处理封面 (如果启用且需要处理)
|
|
|
- if(this.isCover){
|
|
|
- let defaultCover = ''
|
|
|
- // 先查找同名的png或jpg文件
|
|
|
- if (StrUtil.isEmpty(item.pixelMapPath) && item.filePath) {
|
|
|
- defaultCover = findLocalCoverImage(item.filePath);
|
|
|
-
|
|
|
- // 如果没有找到同名图片文件,则进行在线查询
|
|
|
- if (StrUtil.isEmpty(defaultCover)) {
|
|
|
- const imagePath: string | undefined = await searchCover(
|
|
|
- this.context,
|
|
|
- item,
|
|
|
- item.name,
|
|
|
- item?.artist || ''
|
|
|
- );
|
|
|
- defaultCover = imagePath || '';
|
|
|
- }
|
|
|
- }else if(item.pixelMapPath&&item.pixelMapPath.startsWith('http')){
|
|
|
- defaultCover = item.pixelMapPath
|
|
|
- }
|
|
|
- if (StrUtil.isNotEmpty(defaultCover)) {
|
|
|
- // 确保 filePath 存在
|
|
|
- if (item.filePath) {
|
|
|
- // 如果不是 packName 包下的文件,则直接路径用this.download_path
|
|
|
- if(!item.filePath.toLowerCase().includes(this.packName)){
|
|
|
- tempOutPath = this.download_path+ item.fileName
|
|
|
+ // 改为顺序执行以正确显示进度
|
|
|
+ try {
|
|
|
+ for (let index = 0; index < this.selectedFiles.length; index++) {
|
|
|
+ const item: VideoItem = this.selectedFiles[index];
|
|
|
+
|
|
|
+ try {
|
|
|
+ this.currentFileIndex = index + 1;
|
|
|
+ this.currentFileName = item.name;
|
|
|
+ await PermissionUtil.activatePermission(item.filePath)
|
|
|
+
|
|
|
+ let success = true;
|
|
|
+ let lyricSuccess = false;
|
|
|
+ let coverSuccess = false;
|
|
|
+ let tempOutPath = ''
|
|
|
+
|
|
|
+ // 1. 处理封面 (如果启用且需要处理)
|
|
|
+ if(this.isCover){
|
|
|
+ let defaultCover = ''
|
|
|
+ // 先查找同名的png或jpg文件
|
|
|
+ console.log('heanup item.pixelMapPath = ',item.pixelMapPath)
|
|
|
+ if (StrUtil.isEmpty(item.pixelMapPath) && item.filePath) {
|
|
|
+ defaultCover = findLocalCoverImage(item.filePath);
|
|
|
+
|
|
|
+ // 如果没有找到同名图片文件,则进行在线查询
|
|
|
+ if (StrUtil.isEmpty(defaultCover)) {
|
|
|
+ const imagePath: string | undefined = await searchCover(
|
|
|
+ this.context,
|
|
|
+ item,
|
|
|
+ item.name,
|
|
|
+ item?.artist || ''
|
|
|
+ );
|
|
|
+ defaultCover = imagePath || '';
|
|
|
}
|
|
|
- console.info('onecold tempOutPath: ' + tempOutPath)
|
|
|
-
|
|
|
-
|
|
|
- const result = await changeMusicCover(
|
|
|
- this.context,
|
|
|
- item.filePath,
|
|
|
- defaultCover,
|
|
|
- true, tempOutPath
|
|
|
- );
|
|
|
- if (!result) {
|
|
|
+ }else if(item.pixelMapPath&&item.pixelMapPath.startsWith('http')){
|
|
|
+ defaultCover = item.pixelMapPath
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotEmpty(defaultCover)) {
|
|
|
+ // 确保 filePath 存在
|
|
|
+ if (item.filePath) {
|
|
|
+ // 如果不是 packName 包下的文件,则直接路径用this.download_path
|
|
|
+ if(!item.filePath.toLowerCase().includes(this.packName)){
|
|
|
+ tempOutPath = this.download_path+ item.fileName
|
|
|
+ }
|
|
|
+ console.info('onecold tempOutPath: ' + tempOutPath)
|
|
|
+
|
|
|
+ const result = await changeMusicCover(
|
|
|
+ this.context,
|
|
|
+ item.filePath,
|
|
|
+ defaultCover,
|
|
|
+ true, tempOutPath
|
|
|
+ );
|
|
|
+ coverSuccess = result;
|
|
|
+ console.info(`heanup 封面内嵌结果 - 文件: ${item.name}, 结果: ${result}`);
|
|
|
+ if (!result) {
|
|
|
+ success = false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
success = false;
|
|
|
+ coverSuccess = false;
|
|
|
}
|
|
|
} else {
|
|
|
- success = false;
|
|
|
+ coverSuccess = true;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // 如果没有启用封面嵌入,设置为成功状态(不处理)
|
|
|
+ coverSuccess = true;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
- // 2. 处理歌词 (如果启用)
|
|
|
- if (this.isLyric) {
|
|
|
- let lyricContent = item.lyricContent || ''; // 默认为空字符串
|
|
|
-
|
|
|
- // 如果歌词为空,尝试读取同名.lrc文件
|
|
|
- if (StrUtil.isEmpty(lyricContent) && item.filePath) {
|
|
|
- const lrcPath = item.filePath.substring(0, item.filePath.lastIndexOf('.')) + '.lrc';
|
|
|
- try {
|
|
|
- if (fs.accessSync(lrcPath)) {
|
|
|
- const file = fs.openSync(lrcPath, fs.OpenMode.READ_ONLY);
|
|
|
- const buf = new ArrayBuffer(102400); // 100KB缓冲区
|
|
|
- const len = fs.readSync(file.fd, buf);
|
|
|
- const textDecoder = new util.TextDecoder('utf-8');
|
|
|
- // 修复错误3: 使用 Uint8Array 包装 ArrayBuffer
|
|
|
- lyricContent = textDecoder.decode(new Uint8Array(buf.slice(0, len)));
|
|
|
- fs.closeSync(file);
|
|
|
+ // 2. 处理歌词 (如果启用)
|
|
|
+ if (this.isLyric) {
|
|
|
+ let lyricContent = item.lyricContent || ''; // 默认为空字符串
|
|
|
+
|
|
|
+ // 如果歌词为空,尝试读取同名.lrc文件
|
|
|
+ if (StrUtil.isEmpty(lyricContent) && item.filePath) {
|
|
|
+ const lrcPath = item.filePath.substring(0, item.filePath.lastIndexOf('.')) + '.lrc';
|
|
|
+ try {
|
|
|
+ if (fs.accessSync(lrcPath)) {
|
|
|
+ const file = fs.openSync(lrcPath, fs.OpenMode.READ_ONLY);
|
|
|
+ const buf = new ArrayBuffer(102400); // 100KB缓冲区
|
|
|
+ const len = fs.readSync(file.fd, buf);
|
|
|
+ const textDecoder = new util.TextDecoder('utf-8');
|
|
|
+ // 修复错误3: 使用 Uint8Array 包装 ArrayBuffer
|
|
|
+ lyricContent = textDecoder.decode(new Uint8Array(buf.slice(0, len)));
|
|
|
+ fs.closeSync(file);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn(`读取LRC文件失败: ${JSON.stringify(error)}`);
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- console.warn(`读取LRC文件失败: ${JSON.stringify(error)}`);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // 如果仍然为空,尝试从API获取歌词
|
|
|
- if (StrUtil.isEmpty(lyricContent) && item.filePath) {
|
|
|
- try {
|
|
|
- const apiUrl = PreferencesUtil.getStringSync('LRC_API', '');
|
|
|
- // 修复错误1: 添加非空检查
|
|
|
- if (StrUtil.isNotEmpty(apiUrl)) {
|
|
|
- lyricContent = await getApiLyric(
|
|
|
- apiUrl,
|
|
|
- item.name || '', // 修复可能为undefined的情况
|
|
|
- item.artist || '', // 修复可能为undefined的情况
|
|
|
- apiUrl.includes(CommonConstants.LRC_API_2)
|
|
|
- );
|
|
|
+ // 如果仍然为空,尝试从API获取歌词
|
|
|
+ if (StrUtil.isEmpty(lyricContent) && item.filePath) {
|
|
|
+ try {
|
|
|
+ const apiUrl = PreferencesUtil.getStringSync('LRC_API', '');
|
|
|
+ // 修复错误1: 添加非空检查
|
|
|
+ if (StrUtil.isNotEmpty(apiUrl)) {
|
|
|
+ lyricContent = await getApiLyric(
|
|
|
+ apiUrl,
|
|
|
+ item.name || '', // 修复可能为undefined的情况
|
|
|
+ item.artist || '', // 修复可能为undefined的情况
|
|
|
+ apiUrl.includes(CommonConstants.LRC_API_2)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn(`获取API歌词失败: ${JSON.stringify(error)}`);
|
|
|
}
|
|
|
- } catch (error) {
|
|
|
- console.warn(`获取API歌词失败: ${JSON.stringify(error)}`);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // 如果有歌词内容,嵌入到音频文件
|
|
|
- if (StrUtil.isNotEmpty(lyricContent) && item.filePath) {
|
|
|
- const metadata: FFMpegTags = {};
|
|
|
- let newInput = item.filePath
|
|
|
- //内嵌标签歌路径如果不是包含包名,输入newInput要赋值tempOutPath,然后tempOutPath为空
|
|
|
- if(!item.filePath.toLowerCase().includes(this.packName)&&FileUtil.accessSync(tempOutPath)){
|
|
|
- newInput = tempOutPath
|
|
|
- tempOutPath = ''
|
|
|
- }
|
|
|
- // 修复错误2: 添加非空检查
|
|
|
- const result = await repairAudioMetadata(
|
|
|
- newInput,
|
|
|
- lyricContent,
|
|
|
- metadata,
|
|
|
- true ,
|
|
|
- tempOutPath
|
|
|
- );
|
|
|
- if (!result) {
|
|
|
- success = false;
|
|
|
- }else{
|
|
|
- if(!item.filePath.includes(this.packName)){
|
|
|
- //内嵌成功的歌路径如果不是包含包名,则要入库
|
|
|
- let newItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context, newInput,
|
|
|
- CommonConstants.TYPE_LOCAL, true);
|
|
|
- this.table.insert(newItem, (id: number) => {
|
|
|
-
|
|
|
-
|
|
|
- });
|
|
|
+ // 如果有歌词内容,嵌入到音频文件
|
|
|
+ if (StrUtil.isNotEmpty(lyricContent) && item.filePath) {
|
|
|
+ const metadata: FFMpegTags = {};
|
|
|
+ let newInput = item.filePath
|
|
|
+ //内嵌标签歌路径如果不是包含包名,输入newInput要赋值tempOutPath,然后tempOutPath为空
|
|
|
+ if(!item.filePath.toLowerCase().includes(this.packName)&&FileUtil.accessSync(tempOutPath)){
|
|
|
+ newInput = tempOutPath
|
|
|
+ tempOutPath = ''
|
|
|
}
|
|
|
- //内嵌成功后同步歌词到数据库
|
|
|
- syncLyricToDB(this.context,item.filePath,lyricContent)
|
|
|
+ // 修复错误2: 添加非空检查
|
|
|
+ const result = await repairAudioMetadata(
|
|
|
+ newInput,
|
|
|
+ lyricContent,
|
|
|
+ metadata,
|
|
|
+ true ,
|
|
|
+ tempOutPath
|
|
|
+ );
|
|
|
+ lyricSuccess = result;
|
|
|
+ if (!result) {
|
|
|
+ success = false;
|
|
|
+ }else{
|
|
|
+ if(!item.filePath.includes(this.packName)){
|
|
|
+ //内嵌成功的歌路径如果不是包含包名,则要入库
|
|
|
+ let newItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context, newInput,
|
|
|
+ CommonConstants.TYPE_LOCAL, true);
|
|
|
+ this.table.insert(newItem, (id: number) => {
|
|
|
+
|
|
|
+
|
|
|
+ });
|
|
|
+ }
|
|
|
+ //内嵌成功后同步歌词到数据库
|
|
|
+ syncLyricToDB(this.context,item.filePath,lyricContent)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ lyricSuccess = false;
|
|
|
}
|
|
|
+ } else {
|
|
|
+ // 如果没有启用歌词嵌入,设置为成功状态(不处理)
|
|
|
+ lyricSuccess = true;
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- // 更新嵌入状态
|
|
|
- if (item.filePath) {
|
|
|
- this.embedStatusMap.set(item.filePath, success);
|
|
|
- }
|
|
|
+ // 更新嵌入状态
|
|
|
+ if (item.filePath) {
|
|
|
+ this.embedStatusMap.set(item.filePath, success);
|
|
|
+ this.lyricEmbedStatusMap.set(item.filePath, lyricSuccess);
|
|
|
+ this.coverEmbedStatusMap.set(item.filePath, coverSuccess);
|
|
|
+ console.info(`heanup 更新状态 - 封面: ${coverSuccess}, 歌词: ${lyricSuccess}, 文件: ${item.name}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (success) {
|
|
|
+ this.embedSuccessCount++;
|
|
|
+ } else {
|
|
|
+ this.embedFailedCount++;
|
|
|
+ }
|
|
|
|
|
|
- if (success) {
|
|
|
- this.embedSuccessCount++;
|
|
|
- } else {
|
|
|
+ // 更新进度 - 使用 Math.round 避免小数
|
|
|
+ this.currentProgress = Math.round(((index + 1) / this.totalFiles) * 100);
|
|
|
+ console.info(`onecold 进度更新: ${this.currentProgress}% (${index + 1}/${this.totalFiles})`);
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`处理文件 ${item.name} 失败: ${JSON.stringify(error)}`);
|
|
|
this.embedFailedCount++;
|
|
|
}
|
|
|
- // 滚动到当前处理的项目位置
|
|
|
- // this.listScroller.scrollToIndex(index);
|
|
|
- this.currentProgress = Math.floor(((index + 1) / this.totalFiles) * 100);
|
|
|
- return success;
|
|
|
- } catch (error) {
|
|
|
- console.error(`处理文件 ${item.name} 失败: ${JSON.stringify(error)}`);
|
|
|
- this.embedFailedCount++;
|
|
|
- return false;
|
|
|
}
|
|
|
- });
|
|
|
|
|
|
- try {
|
|
|
- // 并发执行所有嵌入任务
|
|
|
- await Promise.all(embedTasks);
|
|
|
- } catch (error) {
|
|
|
- this.onTagsResult(false)
|
|
|
- console.error(`批量嵌入过程出错: ${JSON.stringify(error)}`);
|
|
|
- } finally {
|
|
|
+ // 完成处理
|
|
|
ToastUtil.showToast(`嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`)
|
|
|
this.isEmbedding = false;
|
|
|
this.currentProgress = 0;
|
|
|
this.totalFiles = this.selectedFiles.length;
|
|
|
- this.onTagsResult(true)
|
|
|
- // 可以在这里添加完成后的提示或回调
|
|
|
- console.info(`嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`);
|
|
|
+ this.onTagsResult(true,this.download_path)
|
|
|
+ console.info(`onecold 嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`);
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ this.onTagsResult(false)
|
|
|
+ console.error(`onecold 批量嵌入过程出错: ${JSON.stringify(error)}`);
|
|
|
+ this.isEmbedding = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -571,17 +624,60 @@ export struct TagsContentCover {
|
|
|
.fontColor(Color.Gray)
|
|
|
.margin({ left: 8 })
|
|
|
Blank()
|
|
|
- // 根据嵌入状态显示勾选图标
|
|
|
- SymbolGlyph($r('sys.symbol.checkmark_circle'))
|
|
|
- .fontSize(20)
|
|
|
- .fontColor([this.themeColor])
|
|
|
- .alignSelf(ItemAlign.Center)
|
|
|
- .padding({ right: 25 })
|
|
|
+ // 歌词嵌入状态
|
|
|
+
|
|
|
+ Row() {
|
|
|
+ Text('歌词')
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor(this.themeColor)
|
|
|
+ // 只有当状态存在时才显示图标
|
|
|
+ SymbolGlyph(this.lyricEmbedStatusMap.get(item.filePath)?$r('sys.symbol.checkmark_circle'):$r('sys.symbol.xmark_circle'))
|
|
|
+ .fontSize(16)
|
|
|
+ .margin({ left: 4 })
|
|
|
+ .fontColor([this.themeColor])
|
|
|
+ .alignSelf(ItemAlign.Center)
|
|
|
+ .visibility(this.lyricEmbedStatusMap.has(item.filePath)?Visibility.Visible:Visibility.Hidden)
|
|
|
+ .animation({
|
|
|
+ duration: 666,
|
|
|
+ curve: 'ease-in-out'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ .visibility(this.isLyric?Visibility.Visible:Visibility.None)
|
|
|
+ .animation({
|
|
|
+ duration: 666,
|
|
|
+ curve: 'ease-in-out'
|
|
|
+ })
|
|
|
+ .padding({ right:10 })
|
|
|
+
|
|
|
+
|
|
|
+ // 封面嵌入状态
|
|
|
+
|
|
|
+ Row() {
|
|
|
+ Text('封面')
|
|
|
+ .fontSize(12)
|
|
|
+ .fontColor(this.themeColor)
|
|
|
+ // 只有当状态存在时才显示图标
|
|
|
+
|
|
|
+ SymbolGlyph(this.coverEmbedStatusMap.get(item.filePath)?$r('sys.symbol.checkmark_circle'):$r('sys.symbol.xmark_circle'))
|
|
|
+ .fontSize(16)
|
|
|
+ .margin({ left: 4 })
|
|
|
+ .fontColor([this.themeColor])
|
|
|
+ .alignSelf(ItemAlign.Center)
|
|
|
+ .visibility(this.coverEmbedStatusMap.has(item.filePath)?Visibility.Visible:Visibility.Hidden)
|
|
|
+ .animation({
|
|
|
+ duration: 666,
|
|
|
+ curve: 'ease-in-out'
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+ .margin({ left: 5 })
|
|
|
+ .visibility(this.isCover?Visibility.Visible:Visibility.None)
|
|
|
.animation({
|
|
|
duration: 666,
|
|
|
- curve: 'ease-in-out' // 可选动画曲线
|
|
|
+ curve: 'ease-in-out'
|
|
|
})
|
|
|
- .visibility(this.embedStatusMap.get(item.filePath)?Visibility.Visible:Visibility.None)
|
|
|
+ .padding({ right: 25 })
|
|
|
+
|
|
|
|
|
|
}
|
|
|
.layoutWeight(1)
|