• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022-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 prompt from '@ohos.promptAction'
17import router from '@ohos.router'
18import mediaQuery from '@ohos.mediaquery'
19import mediaLibrary from '@ohos.multimedia.mediaLibrary'
20import { logger } from '../util/Logger'
21
22const TAG: string = 'ChoicePhoto'
23
24@Component
25export struct ChoicePhoto {
26  @State whichShow: Array<boolean> = [true, false]
27  @State medias: Array<mediaLibrary.FileAsset> = []
28  @State choiceShow: Array<Resource> = [$r('app.string.choice_photo'), $r('app.string.choice_video')]
29  @State taskShow: Array<Resource> = [$r('app.media.photo'), $r('app.media.video')]
30  @State textShow: Array<Resource> = [$r('app.string.photograph'), $r('app.string.take_video')]
31  @State isShowChoices: Array<boolean> = new Array(this.medias.length).fill(false)
32  @State @Watch('choiceChange') choiceMedias: Array<mediaLibrary.FileAsset> = []
33  @State mediaUris: Array<string> = []
34  @State isChoice: boolean = false
35  @State nextText: string = ''
36  @State isLand: boolean = false
37  private mediaLibraryInstance: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(getContext(this) as any)
38  private listener = mediaQuery.matchMediaSync('screen and (min-aspect-ratio: 1.5) or (orientation: landscape)')
39  onLand = (mediaQueryResult) => {
40    if (mediaQueryResult.matches) {
41      this.isLand = true
42    } else {
43      this.isLand = false
44    }
45  }
46
47  choiceChange() {
48    if (this.choiceMedias.length > 0) {
49      this.isChoice = true
50    } else {
51      this.isChoice = false
52    }
53  }
54
55  @Builder showChoiceBuild($$: {
56    backGround: string,
57    showNumber: number
58  }) {
59    Column() {
60      Text($$.showNumber === 0 ? '' : `${$$.showNumber}`)
61        .fontSize(14)
62        .fontColor(Color.White)
63        .height(20)
64        .margin({ top: 2 })
65    }
66    .width(24)
67    .height(24)
68    .margin({ top: 6, right: 6 })
69    .borderRadius(15)
70    .border({ width: 1, style: BorderStyle.Solid, color: Color.White })
71    .backgroundColor($$.backGround)
72  }
73
74  async getFileAssetsFromType(mediaType: mediaLibrary.MediaType) {
75    logger.info(TAG, `getFileAssetsFromType`)
76    let context = getContext(this) as any
77    let mediaLibraryInstance = mediaLibrary.getMediaLibrary(context)
78    if (!mediaLibraryInstance) {
79      return
80    }
81    logger.info(TAG, `mediaLibraryInstance = ${JSON.stringify(mediaLibraryInstance)}`)
82    let fileKeyObj = mediaLibrary.FileKey
83    let fetchOp = {
84      selections: `${fileKeyObj.MEDIA_TYPE}=?`,
85      selectionArgs: [`${mediaType}`],
86    }
87    let fetchFileResult = await mediaLibraryInstance.getFileAssets(fetchOp)
88    logger.info(TAG, `fetchFileResult = ${JSON.stringify(fetchFileResult)} , ${fetchFileResult.getCount()}`)
89    if (fetchFileResult && fetchFileResult.getCount() > 0) {
90      this.medias = await fetchFileResult.getAllObject()
91    }
92    logger.info(TAG, `this.medias = ${JSON.stringify(this.medias)}`)
93  }
94
95  convertContext(context: any) {
96    return context
97  }
98
99  async convertResourceToString(resource: Resource) {
100    return await this.convertContext(getContext(this)).resourceManager.getString(resource)
101  }
102
103  async aboutToAppear() {
104    logger.info(TAG, `aboutToAppear`)
105    this.listener.on('change', this.onLand)
106    this.nextText = await this.convertResourceToString($r('app.string.next'))
107    this.getFileAssetsFromType(mediaLibrary.MediaType.IMAGE)
108  }
109
110  getMaxHeight() {
111    if (!this.isLand && this.isChoice) {
112      return { maxHeight: '64%' }
113    } else if (!this.isLand && !this.isChoice) {
114      return { maxHeight: '75%' }
115    } else if (this.isLand && this.isChoice) {
116      return { maxHeight: '62%' }
117    } else if (this.isLand && !this.isChoice) {
118      return { maxHeight: '73%' }
119    }
120  }
121
122  build() {
123    Column() {
124      Row() {
125        Image($r('app.media.back'))
126          .width(44)
127          .height(24)
128          .objectFit(ImageFit.Contain)
129          .onClick(() => {
130            router.back()
131          })
132
133        Text($r('app.string.recently_added'))
134          .fontColor(Color.Black)
135          .fontSize(22)
136          .margin({ left: 120 })
137          .textAlign(TextAlign.Center)
138
139        Image($r('app.media.drop_down'))
140          .width(30)
141          .height(32)
142          .objectFit(ImageFit.Contain)
143
144        Blank()
145
146        Button(`${this.nextText} ${this.isChoice === true ? `(${this.choiceMedias.length})` : ''}`)
147          .fontSize(20)
148          .height(32)
149          .backgroundColor(this.isChoice === true ? '#E92F4F' : '#fffa8e8e')
150          .margin({ right: 10 })
151          .borderRadius(20)
152          .onClick(() => {
153            if (this.isChoice === false) {
154              return
155            }
156            this.mediaUris = this.choiceMedias.map((item) => {
157              return item.uri
158            })
159            router.push({
160              url: 'pages/EditPages',
161              params: { mediaUris: this.mediaUris, isLand: this.isLand }
162
163            })
164          })
165      }
166      .width('100%')
167      .height(35)
168      .padding({ left: 14 })
169      .margin({ top: 20 })
170
171      Column() {
172        Row() {
173          ForEach(this.choiceShow, (item, index) => {
174            Column() {
175              Text(item)
176                .fontSize(20)
177                .fontWeight(500)
178                .fontColor(this.whichShow[index] === true ? '#0000000' : '#99182431')
179                .onClick(() => {
180                  this.whichShow.fill(false)
181                  if (this.whichShow.length > index) {
182                    this.whichShow[index] = true
183                  }
184                  this.medias = []
185                  if (index === 0) {
186                    this.getFileAssetsFromType(mediaLibrary.MediaType.IMAGE)
187                  } else {
188                    this.choiceMedias = []
189                    this.isShowChoices = new Array(this.medias.length).fill(false)
190                    this.getFileAssetsFromType(mediaLibrary.MediaType.VIDEO)
191                  }
192                })
193              if (this.whichShow[index]) {
194                Divider()
195                  .vertical(false)
196                  .strokeWidth(3)
197                  .color('#ffff0000')
198                  .lineCap(LineCapStyle.Round)
199                  .width('40%')
200                  .margin({ top: 4 })
201              }
202            }
203            .width('30%')
204          })
205        }
206        .margin({ top: 20 })
207      }
208
209      Scroll() {
210        Column() {
211          Grid() {
212            ForEach(this.medias, (item, index) => {
213              GridItem() {
214                Stack({ alignContent: Alignment.TopEnd }) {
215                  Image(item.uri)
216                    .width('100%')
217                    .height('100%')
218                    .borderRadius(10)
219                    .objectFit(ImageFit.Fill)
220
221                  if (this.isShowChoices[index]) {
222                    this.showChoiceBuild({ backGround: '#e92f4f', showNumber: this.choiceMedias.indexOf(item) + 1 })
223                  } else {
224                    this.showChoiceBuild({ backGround: '#ffb7b4b4', showNumber: 0 })
225                  }
226                }
227                .width('100%')
228                .height('100%')
229                .onClick(() => {
230                  this.isShowChoices[index] = !this.isShowChoices[index]
231                  if (this.isShowChoices[index]) {
232                    if (this.choiceMedias.length > 5) {
233                      prompt.showDialog({ message: $r('app.string.choice_number') })
234                      this.isShowChoices[index] = !this.isShowChoices[index]
235                      return
236                    }
237                    this.choiceMedias.push(item)
238                  } else {
239                    if (this.choiceMedias.indexOf(item) != -1) {
240                      this.choiceMedias.splice(this.choiceMedias.indexOf(item), 1)
241                    }
242                  }
243                })
244              }
245              .aspectRatio(1)
246            })
247          }
248          .columnsTemplate('1fr 1fr 1fr 1fr')
249          .columnsGap(8)
250          .rowsGap(8)
251        }
252        .height('100%')
253        .width('95%')
254        .margin({ top: 8 })
255      }
256      .margin({ top: 20 })
257      .width('100%')
258      .constraintSize(this.getMaxHeight())
259      .backgroundColor('#fff5f3f3')
260
261      if (this.isChoice) {
262        Grid() {
263          ForEach(this.choiceMedias, (item, index) => {
264            GridItem() {
265              Stack({ alignContent: Alignment.TopEnd }) {
266                Image(item.uri)
267                  .width('100%')
268                  .height(70)
269                  .borderRadius(10)
270                Image($r('app.media.delete'))
271                  .width(20)
272                  .height(20)
273                  .margin({ top: 5, right: 5 })
274                  .onClick(() => {
275                    for (let i = 0;i < this.medias.length; i++) {
276                      if (this.choiceMedias[index] && this.isShowChoices.length > i && this.medias[i] === this.choiceMedias[index]) {
277                        this.isShowChoices[i] = false
278                      }
279                    }
280                    this.choiceMedias.splice(index, 1)
281                  })
282              }
283              .width('100%')
284            }
285          })
286        }
287        .columnsTemplate('1fr 1fr 1fr 1fr 1fr 1fr')
288        .columnsGap(8)
289        .rowsGap(8)
290        .margin({ top: 8 })
291        .width('95%')
292        .height(70)
293
294        Divider()
295          .vertical(false)
296          .strokeWidth(1)
297          .color('#ffd9d5d6')
298          .lineCap(LineCapStyle.Round)
299          .width('100%')
300          .margin({ top: 8 })
301      }
302
303      Row() {
304        ForEach(this.taskShow, (item, index) => {
305          Column() {
306            Image(item)
307              .width(30)
308              .height(30)
309
310            Text(this.textShow[index])
311              .fontSize(14)
312              .fontColor('#99182431')
313              .margin({ top: 2 })
314          }
315          .width('50%')
316        })
317      }
318      .margin({ top: 8 })
319    }
320  }
321}