• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (C) 2023 Huawei Device Co., Ltd.
3* Licensed under the Apache License, Version 2.0 (the "License");
4* you may not use this file except in compliance with the License.
5* You may obtain a copy of the License at
6*
7* http://www.apache.org/licenses/LICENSE-2.0
8*
9* Unless required by applicable law or agreed to in writing, software
10* distributed under the License is distributed on an "AS IS" BASIS,
11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12* See the License for the specific language governing permissions and
13* limitations under the License.
14*/
15
16import AVSessionManager from '@ohos.multimedia.avsession';
17import common from '@ohos.app.ability.common';
18import control from '../feature/MediaController';
19import Log from '../common/Logger';
20
21const TAG: string = 'PresentPage';
22
23@Entry
24@Component
25struct PresentPage {
26  @State
27  isShowQueue: boolean = false;
28  @StorageLink('isLyric')
29  isLyric: boolean = false;
30  @StorageLink('item')
31  itemShow: Array<AVSessionManager.AVQueueItem> = new Array;
32  @StorageLink('history')
33  history: Array<AVSessionManager.AVSessionDescriptor> = new Array();
34  @StorageLink('isPlaying')
35  isPlaying: boolean = false;
36  controller = new control();
37  @StorageLink('metaDataMap')
38  @Watch('onMetaDataChangeCallback')
39  private metaDataMap: Map<string, AVSessionManager.AVMetadata> = new Map();
40  @StorageLink('playStateMap')
41  private playStateMap: Map<string, AVSessionManager.AVMetadata> = new Map();
42  @StorageLink('queueTitleMap')
43  private queueTitleMap: Map<string, string> = new Map();
44  @StorageLink('queueItemsMap')
45  private queueItemsMap: Map<string, Array<AVSessionManager.AVQueueItem>> = new Map();
46  @StorageLink('lyricMap')
47  private lyricMap: Map<string, string> = new Map();
48  @StorageLink('bundleNameMap')
49  private bundleNameMap: Map<string, string> = new Map();
50  @StorageLink('sessionArray')
51  private sessionArray: Array<string> = new Array();
52
53  async aboutToAppear() {
54    await this.controller.initLink();
55    await this.controller.startControl();
56  }
57
58  onMetaDataChangeCallback() {
59    Log.info(TAG, 'metadatachange check metadatamap: ' + JSON.stringify(this.metaDataMap));
60    Log.info(TAG, 'metadatachange check sessionarray: ' + JSON.stringify(this.sessionArray![0]));
61  }
62
63  build() {
64    Stack() {
65      Image('#00000000')
66        .width('100%')
67        .height('100%')
68        .onTouch((event?: TouchEvent) => {
69          if (event !== undefined && event.type == TouchType.Down) {
70            Log.info(TAG, 'touch down img, terminate self sss');
71            let context: common.UIAbilityContext | undefined = AppStorage.get<common.UIAbilityContext>('context')
72            context!.terminateSelf()
73          }
74        })
75      Column() {
76        Stack({ alignContent: Alignment.TopStart }) {
77          Column() {
78          }
79          .width('100%')
80          .height('100%')
81          .backgroundColor('#99ffffff')
82          .zIndex(1)
83          .borderRadius('16vp')
84          .id('FirstPanel')
85
86          Column() {
87            Row() {
88              Image(this.sessionArray[0] && this.metaDataMap.get(this.sessionArray[0])
89                ? (this.metaDataMap?.get(this.sessionArray[0]))?.mediaImage : $r('app.media.no_music'))
90                .width('48vp')
91                .height('48vp')
92                .id('CurrentImage')
93              Column() {
94                Text(this.sessionArray[0] && this.metaDataMap.get(this.sessionArray[0])
95                  ? (this.metaDataMap?.get(this.sessionArray[0]))?.title : $r('app.string.not_in_play'))
96                  .fontSize('16fp')
97                  .fontColor('#182431')
98                  .maxLines(1)
99                  .textOverflow({ overflow: TextOverflow.Ellipsis })
100                  .width('228vp')
101                  .id('Title')
102                Text(this.sessionArray[0] && this.metaDataMap.get(this.sessionArray[0])
103                  ? (this.metaDataMap?.get(this.sessionArray[0]))?.artist : $r('app.string.not_in_play'))
104                  .fontSize('14fp')
105                  .fontColor('#182431')
106                  .opacity(0.6)
107                  .maxLines(1)
108                  .textOverflow({ overflow: TextOverflow.Ellipsis })
109                  .width('228vp')
110                  .id('Artist')
111              }
112              .margin({ left: '12vp' })
113              .alignItems(HorizontalAlign.Start)
114            }
115            .justifyContent(FlexAlign.Start)
116            .width('100%')
117            .margin({ top: '12vp' })
118
119            Row() {
120              Image(this.isShowQueue ? $r('app.media.list_activate') : $r('app.media.list_none'))
121                .width('24vp')
122                .height('24vp')
123                .id('ShowQueue')
124                .onClick(() => {
125                  this.isShowQueue = !this.isShowQueue;
126                  Log.info(TAG, 'isShowQueue set to : ' + this.isShowQueue);
127                })
128              Image($r('app.media.previous')).width('24vp').height('24vp')
129                .id('Previous')
130                .onClick(() => {
131                  if (this.sessionArray[0]) {
132                    this.controller.previous(this.sessionArray[0]);
133                    Log.info(TAG, 'on previous click ');
134                  }
135                })
136              Image(this.isPlaying ? $r('app.media.stopmusic') : $r('app.media.playmusic'))
137                .width('24vp')
138                .height('24vp')
139                .id('PlayOrPause:' + this.isPlaying)
140                .onClick(() => {
141                  if (this.sessionArray[0]) {
142                    if (this.isPlaying) {
143                      this.controller.pause(this.sessionArray[0]);
144                    } else {
145                      this.controller.play(this.sessionArray[0]);
146                    }
147                    Log.info(TAG, 'on play/pause click ');
148                  }
149                })
150              Image($r('app.media.next')).width('24vp').height('24vp')
151                .id('Next')
152                .onClick(() => {
153                  if (this.sessionArray[0]) {
154                    this.controller.next(this.sessionArray[0]);
155                    Log.info(TAG, 'on next click ');
156                  }
157                })
158              Image(this.isLyric ? $r('app.media.lyric_activate') : $r('app.media.lyric_none'))
159                .width('24vp')
160                .height('24vp')
161                .id('Lyric')
162                .onClick(() => {
163                  this.controller.getLyric(this.sessionArray[0]);
164                  Log.info(TAG, ' isLyric set to :' + this.isLyric);
165                })
166            }
167            .justifyContent(FlexAlign.SpaceBetween)
168            .margin({ left: '12vp', right: '12vp', top: '20vp', bottom: '12vp' })
169            .width('264vp')
170            .height('24vp')
171
172            Row() {
173              Text(this.sessionArray[0] && this.lyricMap[this.sessionArray[0]]
174                ? this.lyricMap[this.sessionArray[0]] : $r('app.string.not_in_play'))
175                .id('LyricText')
176                .fontColor('#182431')
177                .maxLines(1)
178                .textOverflow({ overflow: TextOverflow.Ellipsis })
179            }
180            .width('264vp')
181            .height('20vp')
182            .margin({ top: '12vp', bottom: '12vp', left: '12vp', right: '12vp' })
183            .alignItems(VerticalAlign.Center)
184            .justifyContent(FlexAlign.Center)
185            .visibility(this.isLyric ? Visibility.Visible : Visibility.None)
186
187            Divider()
188              .height('0.5vp')
189              .opacity(0.05)
190              .color('#182431')
191              .width('100%')
192              .margin({ top: '12.5vp' })
193              .visibility(this.sessionArray.length > 1 ? Visibility.Visible : Visibility.None)
194            Row() {
195              Image(this.sessionArray[1] && this.metaDataMap[this.sessionArray[1]]
196                && this.metaDataMap[this.sessionArray[1]].mediaImage
197                ? (this.metaDataMap[this.sessionArray[1]]).mediaImage : $r('app.media.no_music'))
198                .width('48vp')
199                .height('48vp')
200                .id('HistoryImage')
201              Column() {
202                Text(this.sessionArray[1] && this.metaDataMap[this.sessionArray[1]]
203                  ? (this.metaDataMap[this.sessionArray[1]]).title : $r('app.string.not_in_play'))
204                  .fontSize('16fp')
205                  .maxLines(1)
206                  .fontColor('#182431')
207                  .id('HistoryTitle')
208                  .textOverflow({ overflow: TextOverflow.Ellipsis })
209                  .width('228vp')
210                Text(this.sessionArray[1] && this.bundleNameMap[this.sessionArray[1]]
211                  ? (this.bundleNameMap[this.sessionArray[1]]) : '')
212                  .fontSize('14fp')
213                  .fontColor('#182431')
214                  .opacity(0.6)
215                  .maxLines(1)
216                  .id('HistoryArtist')
217                  .textOverflow({ overflow: TextOverflow.Ellipsis })
218                  .width('228vp')
219              }
220              .margin({ left: '12vp' })
221              .alignItems(HorizontalAlign.Start)
222              .justifyContent(FlexAlign.Center)
223            }
224            .justifyContent(FlexAlign.Start).width('100%').margin({ top: '12vp', bottom: '12.5vp' })
225            .visibility(this.sessionArray.length > 1 ? Visibility.Visible : Visibility.None)
226
227            Divider()
228              .height('0.5vp')
229              .opacity(0.05)
230              .color('#182431')
231              .width('100%')
232              .visibility(this.sessionArray.length > 2 ? Visibility.Visible : Visibility.None)
233
234            Row() {
235              Image(this.sessionArray[2] && this.metaDataMap?.get(this.sessionArray[2])
236                && this.metaDataMap?.get(this.sessionArray[2])?.mediaImage
237                ? (this.metaDataMap?.get(this.sessionArray[2]))?.mediaImage : $r('app.media.no_music'))
238                .width('48vp')
239                .height('48vp')
240              Column() {
241                Text(this.sessionArray[2] && this.metaDataMap?.get(this.sessionArray[2])
242                  ? (this.metaDataMap?.get(this.sessionArray[2]))?.title : $r('app.string.not_in_play'))
243                  .fontSize('16fp')
244                  .fontColor('#182431')
245                  .maxLines(1)
246                  .textOverflow({ overflow: TextOverflow.Ellipsis })
247                  .width('228vp')
248                Text(this.sessionArray[2] && this.bundleNameMap[this.sessionArray[2]]
249                  ? (this.bundleNameMap[this.sessionArray[2]]) : '')
250                  .fontSize('14fp')
251                  .fontColor('#182431')
252                  .opacity(0.6)
253                  .maxLines(1)
254                  .textOverflow({ overflow: TextOverflow.Ellipsis })
255                  .width('228vp')
256              }
257              .margin({ left: '12vp' })
258              .alignItems(HorizontalAlign.Start)
259              .justifyContent(FlexAlign.Center)
260            }
261            .justifyContent(FlexAlign.Start)
262            .width('100%')
263            .margin({ top: 10 })
264            .visibility(this.sessionArray.length > 2 ? Visibility.Visible : Visibility.None)
265          }
266          .width('288vp')
267          .height('100%')
268          .zIndex(2)
269          .margin({ top: '4vp', bottom: '4vp', left: '12vp', right: '12vp' })
270        }
271        .width('312vp')
272        .height(this.getMediaCardHeight())
273        .margin({ top: '40vp' })
274
275        Stack() {
276          Column() {
277          }
278          .width('100%')
279          .height('153vp')
280          .backgroundColor('#99ffffff')
281          .zIndex(1)
282          .borderRadius('24vp')
283
284          Column() {
285            Column() {
286              Text(this.sessionArray[0]
287                && this.queueItemsMap[this.sessionArray[0]]
288                && this.queueItemsMap[this.sessionArray[0]][0]
289                ? this.queueItemsMap[this.sessionArray[0]][0].description.title : 'queue null')
290                .fontSize('16fp')
291                .fontColor('#182431')
292                .maxLines(1)
293                .textOverflow({ overflow: TextOverflow.Ellipsis })
294            }
295            .alignItems(HorizontalAlign.Start)
296            .height('48vp')
297            .justifyContent(FlexAlign.Center)
298            .width('100%')
299            .id('FirstMusicInQueue')
300            .onClick(() => {
301              if (this.sessionArray[0] &&
302              this.queueItemsMap[this.sessionArray[0]] &&
303                this.queueItemsMap[this.sessionArray[0]][0] !== undefined) {
304                Log.info(TAG, 'pre skip :' + this.queueItemsMap[this.sessionArray[0]][0].itemId);
305                this.controller.skip(this.sessionArray[0], this.queueItemsMap[this.sessionArray[0]][0].itemId);
306              }
307            })
308
309            Divider()
310              .height('0.5vp')
311              .opacity(0.05)
312              .color('#182431')
313              .width('100%')
314
315            Column() {
316              Text(this.sessionArray[0]
317                && this.queueItemsMap[this.sessionArray[0]]
318                && this.queueItemsMap[this.sessionArray[0]][1]
319                ? this.queueItemsMap[this.sessionArray[0]][1].description.title : 'queue null')
320                .fontSize('16fp')
321                .fontColor('#182431')
322                .maxLines(1)
323                .textOverflow({ overflow: TextOverflow.Ellipsis })
324            }
325            .alignItems(HorizontalAlign.Start)
326            .height('48vp')
327            .justifyContent(FlexAlign.Center)
328            .width('100%')
329            .id('SecondMusicInQueue')
330            .onClick(() => {
331              if (this.sessionArray[0] &&
332              this.queueItemsMap[this.sessionArray[0]] &&
333                this.queueItemsMap[this.sessionArray[0]][1] !== undefined) {
334                Log.info(TAG, 'pre skip :' + this.queueItemsMap[this.sessionArray[0]][1].itemId);
335                this.controller.skip(this.sessionArray[0], this.queueItemsMap[this.sessionArray[0]][1].itemId);
336              }
337            })
338
339            Divider()
340              .height('0.5vp')
341              .opacity(0.05)
342              .color('#182431')
343              .width('100%')
344
345            Column() {
346              Text(this.sessionArray[0]
347                && this.queueItemsMap[this.sessionArray[0]]
348                && this.queueItemsMap[this.sessionArray[0]][2]
349                ? this.queueItemsMap[this.sessionArray[0]][2].description.title : 'queue null')
350                .fontSize('16fp')
351                .fontColor('#182431')
352                .maxLines(1)
353                .textOverflow({ overflow: TextOverflow.Ellipsis })
354            }
355            .alignItems(HorizontalAlign.Start)
356            .height('48vp')
357            .justifyContent(FlexAlign.Center)
358            .width('100%')
359            .id('ThirdMusicInQueue')
360            .onClick(() => {
361              if (this.sessionArray[0] &&
362              this.queueItemsMap[this.sessionArray[0]] &&
363                this.queueItemsMap[this.sessionArray[0]][2] !== undefined) {
364                this.controller.skip(this.sessionArray[0], this.queueItemsMap[this.sessionArray[0]][2].itemId);
365              }
366            })
367          }
368          .width('288vp')
369          .height('144vp')
370          .id('SecondPanel')
371          .zIndex(2)
372          .alignItems(HorizontalAlign.Start)
373          .margin({ top: '4vp', bottom: '4vp', left: '12vp', right: '12vp' })
374        }
375        .width('312vp')
376        .height('153vp')
377        .margin({ top: '12vp' })
378        .visibility(this.isShowQueue ? Visibility.Visible : Visibility.None)
379      }
380      .height(this.getTotalHeight())
381      .width('312vp')
382      .margin({ top: '40vp', left: '24vp', right: '24vp' })
383      .backgroundColor('#00000000')
384    }
385    .backgroundImage($r('app.media.background'))
386    .backgroundImageSize(ImageSize.Cover)
387    .alignContent(Alignment.Top)
388    .width('100%')
389    .height('100%')
390  }
391
392  getMediaCardHeight(): string {
393    let mediaNum: number = this.sessionArray.length > 0 ?
394      (this.sessionArray.length > 3 ? 3 : this.sessionArray.length) : 1; // If has 3 or more history, get 3 of them.
395    let mediaExtraHeight: number = ((mediaNum - 1) > 0 ? 12 : 0) + (mediaNum - 1) * 73; // 73 is the length given from UX designer
396    let height: number = 124 + (this.isLyric ? 44 : 0) + mediaExtraHeight; // 124 and 44 is the size given from UX designer
397    Log.info(TAG, 'get height : ' + height);
398    return String(height) + 'vp';
399  }
400
401  getTotalHeight(): string {
402    let mediaNum: number = this.sessionArray.length > 0 ?
403      (this.sessionArray.length > 3 ? 3 : this.sessionArray.length) : 1; // If has 3 or more history, get 3 of them.
404    let mediaExtraHeight: number = ((mediaNum - 1) > 0 ? 12 : 0) + (mediaNum - 1) * 73; // 73 is the length given from UX designer
405    let height: number = 124 + (this.isLyric ? 44 : 0) + mediaExtraHeight; // 124 and 44 is the length given from UX designer
406    Log.info(TAG, 'get media height : ' + height);
407    height += (this.isShowQueue ? 165 : 0); // 165 is the length given from UX designer
408    Log.info(TAG, 'get total height : ' + height);
409    return String(height + 40) + 'vp';
410  }
411}
412