| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /**
- * 方形播放器卡片 (2x2)
- * 显示专辑封面、歌曲信息和播放按钮
- * 参考华为官方设计,移除收藏功能
- * 需求: 5.1, 1.4, 1.5
- */
- // 定义对齐规则 - 参考华为官方代码
- const SquareSingerAlignRules: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
- 'top': { 'anchor': 'musicTitle', 'align': VerticalAlign.Bottom },
- 'left': { 'anchor': 'musicCover', 'align': HorizontalAlign.End }
- };
- const SquareCoverAlignRules: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
- 'bottom': { 'anchor': '__container__', 'align': VerticalAlign.Bottom }
- };
- const PlayAlignRules: Record<string, Record<string, string | VerticalAlign | HorizontalAlign>> = {
- 'bottom': { 'anchor': '__container__', 'align': VerticalAlign.Bottom },
- 'right': { 'anchor': '__container__', 'align': HorizontalAlign.End }
- };
- @Entry
- @Component
- struct PlayerWidgetSquare {
- // 卡片数据属性 - 使用LocalStorageProp与FormExtensionAbility通信
- @LocalStorageProp('formId') formId: string = '12400633174999288';
- @LocalStorageProp('isPlaying') isPlaying: boolean = false;
- @LocalStorageProp('songTitle') songTitle: string = 'Dream It Possible';
- @LocalStorageProp('songArtist') songArtist: string = 'Delacey';
- @LocalStorageProp('coverImage') coverImage: string = '';
- @LocalStorageProp('isLoading') isLoading: boolean = false;
- @LocalStorageProp('imageColorHex') imageColorHex: string = '2A2A2A';
- @LocalStorageProp('imgName') imgName: string = ''; // 图片文件名,用于memory://协议
- /**
- * 格式化歌曲标题显示
- */
- private getDisplayTitle(): string {
- if (!this.songTitle || this.songTitle.trim() === '') {
- return '暂无播放';
- }
- return this.songTitle;
- }
- /**
- * 格式化艺术家显示
- */
- private getDisplayArtist(): string {
- if (!this.songArtist || this.songArtist.trim() === '') {
- return '未知艺术家';
- }
- return this.songArtist;
- }
- /**
- * 获取专辑封面
- */
- private getCoverImage(): Resource | string {
- console.info(`Heanup PlayerWidgetSquare: getCoverImage called, coverImage='${this.coverImage}', imgName='${this.imgName}'`);
-
- // 优先使用通过formImages传递的本地图片(支持网络图片下载后的显示)
- if (this.imgName && this.imgName.trim() !== '') {
- const memoryUrl = 'memory://' + this.imgName;
- console.info(`Heanup PlayerWidgetSquare: Using memory image: ${memoryUrl}`);
- return memoryUrl;
- }
-
- // 如果有coverImage且不是网络URL,使用本地路径
- if (this.coverImage && this.coverImage.trim() !== '' && !this.isNetworkUrl(this.coverImage)) {
- console.info(`Heanup PlayerWidgetSquare: Using local cover image: ${this.coverImage}`);
- return this.coverImage;
- }
-
- // 默认使用内置图片
- console.info(`Heanup PlayerWidgetSquare: Using default cover image`);
- return $r('app.media.ic_avatar4'); // 使用默认专辑封面
- }
- /**
- * 检查是否为网络URL
- */
- private isNetworkUrl(url: string): boolean {
- return url.startsWith('http://') || url.startsWith('https://');
- }
- build() {
- RelativeContainer() {
- // 歌曲标题 - 参考华为官方样式
- Text(this.getDisplayTitle())
- .fontSize(14)
- .fontWeight(700)
- .width('85%')
- .fontColor(Color.White)
- .textOverflow({ overflow: TextOverflow.Ellipsis })
- .maxLines(1)
- .id('musicTitle')
- // 艺术家名称 - 参考华为官方样式
- Text(this.getDisplayArtist())
- .fontSize(12)
- .fontColor('#CCFFFFFF')
- .fontWeight(500)
- .maxLines(1)
- .alignRules(SquareSingerAlignRules)
- .margin({ top: 2 })
- .id('singerText')
- // 专辑封面 - 参考华为官方黑胶唱片设计
- Stack({ alignContent: Alignment.Center }) {
- Image($r('app.media.ic_music_bg_mini'))
- .height(88)
- .width(88)
- Button()
- .backgroundImage(this.getCoverImage())
- .backgroundImageSize(ImageSize.Cover)
- .height(58)
- .width(58)
- .borderRadius(29)
- }
- .alignRules(SquareCoverAlignRules)
- .id('musicCover')
- .onClick(() => {
- console.info('Heanup PlayerWidgetSquare: Album cover clicked');
- postCardAction(this, {
- 'action': 'router',
- 'abilityName': 'EntryAbility'
- });
- })
- // 播放按钮 - 参考华为官方样式
- SymbolGlyph(this.isPlaying ? $r('sys.symbol.pause_round_triangle_fill') : $r('sys.symbol.play_round_triangle_fill'))
- .fontSize(36)
- .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
- .fontColor(['#E5FFFFFF'])
- .alignRules(PlayAlignRules)
- .onClick(() => {
- console.info('Heanup PlayerWidgetSquare: Play/Pause button clicked');
- if (!this.isLoading) {
- postCardAction(this, {
- 'action': 'call',
- 'abilityName': 'EntryAbility',
- 'params': {
- 'formId': this.formId,
- 'method': 'playPause',
- 'widgetIsPlaying': this.isPlaying // 传递卡片当前显示的播放状态
- }
- });
- }
- })
- }
- .height('100%')
- .width('100%')
- .linearGradient({
- direction: GradientDirection.Bottom,
- repeating: false,
- colors: [[`#ff${this.imageColorHex}`, 0.0], [`#ff${this.imageColorHex}`, 0.5], [`#ff${this.imageColorHex}`, 1.0]]
- })
- .padding(12)
- .onClick(() => {
- console.info('Heanup PlayerWidgetSquare: Container clicked, jumping to main app');
- postCardAction(this, {
- 'action': 'router',
- 'abilityName': 'EntryAbility'
- });
- })
- }
- }
|