PlayerWidgetSmall.ets 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /**
  2. * 小尺寸播放器卡片 (1x2)
  3. * 只显示播放控制按钮:上一首、播放/暂停、下一首
  4. * 需求: 5.1, 1.4, 1.5
  5. */
  6. @Entry
  7. @Component
  8. struct PlayerWidgetSmall {
  9. // 卡片数据属性 - 使用LocalStorageProp与FormExtensionAbility通信
  10. @LocalStorageProp('formId') formId: string = '202501';
  11. @LocalStorageProp('isPlaying') isPlaying: boolean = false;
  12. @LocalStorageProp('songTitle') songTitle: string = 'Dream It Possible';
  13. @LocalStorageProp('songArtist') songArtist: string = 'Delacey';
  14. @LocalStorageProp('coverImage') coverImage: string = '';
  15. @LocalStorageProp('hasNext') hasNext: boolean = false;
  16. @LocalStorageProp('hasPrevious') hasPrevious: boolean = false;
  17. @LocalStorageProp('isLoading') isLoading: boolean = false;
  18. @LocalStorageProp('imageColorHex') imageColorHex: string = '2A2A2A';
  19. @LocalStorageProp('imgName') imgName: string = ''; // 图片文件名,用于memory://协议
  20. /**
  21. * 获取专辑封面
  22. */
  23. private getCoverImage(): Resource | string {
  24. console.info(`Heanup PlayerWidgetSquare: getCoverImage called, coverImage='${this.coverImage}', imgName='${this.imgName}'`);
  25. // 优先使用通过formImages传递的本地图片(支持网络图片下载后的显示)
  26. if (this.imgName && this.imgName.trim() !== '') {
  27. const memoryUrl = 'memory://' + this.imgName;
  28. console.info(`Heanup PlayerWidgetSquare: Using memory image: ${memoryUrl}`);
  29. return memoryUrl;
  30. }
  31. // 如果有coverImage且不是网络URL,使用本地路径
  32. if (this.coverImage && this.coverImage.trim() !== '' && !this.isNetworkUrl(this.coverImage)) {
  33. console.info(`Heanup PlayerWidgetSquare: Using local cover image: ${this.coverImage}`);
  34. return this.coverImage;
  35. }
  36. // 默认使用内置图片
  37. console.info(`Heanup PlayerWidgetSquare: Using default cover image`);
  38. return $r('app.media.ic_avatar4'); // 使用默认专辑封面
  39. }
  40. /**
  41. * 检查是否为网络URL
  42. */
  43. private isNetworkUrl(url: string): boolean {
  44. return url.startsWith('http://') || url.startsWith('https://');
  45. }
  46. build() {
  47. // 简洁的播放控制条
  48. Row() {
  49. // 上一首按钮
  50. Button() {
  51. Image($r('app.media.hm_previous'))
  52. .width(20)
  53. .height(20)
  54. .fillColor('#E5FFFFFF')
  55. }
  56. .width(36)
  57. .height(36)
  58. .backgroundColor(Color.Transparent)
  59. .opacity(this.hasPrevious ? 1.0 : 0.5)
  60. .onClick(() => {
  61. console.info(`Heanup PlayerWidgetSmall: Previous button clicked`);
  62. if (!this.isLoading && this.hasPrevious) {
  63. postCardAction(this, {
  64. 'action': 'call',
  65. 'abilityName': 'EntryAbility',
  66. 'params': {
  67. 'formId': this.formId,
  68. 'method': 'prevSong'
  69. }
  70. });
  71. }
  72. })
  73. // 播放/暂停按钮
  74. Button() {
  75. SymbolGlyph(this.isPlaying ? $r('sys.symbol.pause_round_triangle_fill') : $r('sys.symbol.play_round_triangle_fill'))
  76. .fontSize(28)
  77. .symbolEffect(new ReplaceSymbolEffect(EffectScope.WHOLE), true)
  78. .fontColor(['#E5FFFFFF'])
  79. }
  80. .width(44)
  81. .height(44)
  82. .backgroundColor(Color.Transparent)
  83. .margin({ left: 8, right: 8 })
  84. .onClick(() => {
  85. console.info('Heanup PlayerWidgetSmall: Play/Pause button clicked');
  86. if (!this.isLoading) {
  87. postCardAction(this, {
  88. 'action': 'call',
  89. 'abilityName': 'EntryAbility',
  90. 'params': {
  91. 'formId': this.formId,
  92. 'method': 'playPause',
  93. 'widgetIsPlaying': this.isPlaying // 传递卡片当前显示的播放状态
  94. }
  95. });
  96. }
  97. })
  98. // 下一首按钮
  99. Button() {
  100. Image($r('app.media.hm_next'))
  101. .width(20)
  102. .height(20)
  103. .fillColor('#E5FFFFFF')
  104. }
  105. .width(36)
  106. .height(36)
  107. .backgroundColor(Color.Transparent)
  108. .opacity(this.hasNext ? 1.0 : 0.5)
  109. .onClick(() => {
  110. console.info(`Heanup PlayerWidgetSmall: Next button clicked`);
  111. if (!this.isLoading && this.hasNext) {
  112. postCardAction(this, {
  113. 'action': 'call',
  114. 'abilityName': 'EntryAbility',
  115. 'params': {
  116. 'formId': this.formId,
  117. 'method': 'nextSong'
  118. }
  119. });
  120. }
  121. })
  122. }
  123. .width('100%')
  124. .height('100%')
  125. .justifyContent(FlexAlign.Center)
  126. .alignItems(VerticalAlign.Center)
  127. // .backgroundColor('#FF2A2A2A')
  128. .borderRadius(8)
  129. .padding(8)
  130. .backgroundImage(this.getCoverImage())
  131. .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
  132. .backgroundImageSize(ImageSize.Cover)
  133. .onClick(() => {
  134. console.info('Heanup PlayerWidgetSmall: Container clicked, jumping to main app');
  135. postCardAction(this, {
  136. 'action': 'router',
  137. 'abilityName': 'EntryAbility'
  138. });
  139. })
  140. }
  141. }