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