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