1/* 2 * Copyright (c) 2022 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 mediaLibrary from '@ohos.multimedia.mediaLibrary' 17import iaImage from '@ohos.multimedia.image' 18import { getTimeString } from '../model/TimeTools' 19import Logger from '../model/Logger' 20 21const TRANSLATE: number = -110 22const TAG: string = 'MediaItem:' 23 24@Component 25export struct MediaItem { 26 @State translateLeft: number = 0 27 @State translateRight: number = TRANSLATE 28 @State pixelMap: iaImage.PixelMap = undefined 29 @State mediaItem: mediaLibrary.FileAsset = undefined 30 @Link @Watch('leftSliderChange') leftSliderIndex: number 31 private index: number = -1 32 private deleteDialogShow: (index: number, mediaType) => void 33 private renameDialogShow: (index: number, mediaType) => void 34 35 leftSliderChange() { 36 animateTo({ duration: 500, curve: Curve.Linear }, () => { 37 if (this.index !== this.leftSliderIndex) { 38 this.translateLeft = 0 39 this.translateRight = TRANSLATE 40 } else { 41 if (this.translateLeft < 0) { 42 this.translateLeft = 0 43 this.translateRight = TRANSLATE 44 } else { 45 this.translateLeft = TRANSLATE 46 this.translateRight = 0 47 } 48 } 49 }) 50 } 51 52 async aboutToAppear() { 53 let size: iaImage.Size = { width: 100, height: 66 } 54 this.mediaItem.getThumbnail(size, (err, pixelMap) => { 55 Logger.info(TAG, 'getThumbnail callback') 56 if (err) { 57 Logger.info(TAG, `getThumbnail callback,err=${JSON.stringify(err)}`) 58 return 59 } 60 this.pixelMap = pixelMap 61 Logger.info(TAG, `getThumbnail callback,success = ${typeof this.pixelMap}`) 62 }) 63 } 64 65 getImageSrc() { 66 switch (this.mediaItem.mediaType) { 67 case mediaLibrary.MediaType.VIDEO: 68 return $r('app.media.videoCover') 69 case mediaLibrary.MediaType.AUDIO: 70 return $r('app.media.audioCover') 71 } 72 } 73 74 build() { 75 Flex({ justifyContent: FlexAlign.Center }) { 76 Flex({ 77 justifyContent: FlexAlign.Start, 78 alignItems: ItemAlign.Center 79 }) { 80 81 Image(this.pixelMap ? this.pixelMap : this.getImageSrc()) 82 .width(100) 83 .height('100%') 84 .borderRadius(12) 85 .objectFit(ImageFit.Fill) 86 87 Text(getTimeString(this.mediaItem.duration)) 88 .fontSize(14) 89 .fontColor('#FFFFFF') 90 .position({ 91 x: '5', 92 y: '72%' 93 }) 94 .zIndex(2) 95 96 Text(this.mediaItem.displayName) 97 .align(Alignment.Start) 98 .fontSize(16) 99 .fontColor('#FFFFFF') 100 .fontFamily('HarmonyHeiTi-Medium') 101 .margin({ 102 left: 12 103 }) 104 .height(40) 105 .textOverflow({ 106 overflow: TextOverflow.Clip 107 }) 108 .width('48%') 109 } 110 .width('95%') 111 .height(66) 112 .borderRadius(12) 113 .backgroundColor('rgba(255,255,255,0.10)') 114 115 116 Row() { 117 Button() { 118 Image($r("app.media.icon_rename")) 119 .size({ 120 width: 60, 121 height: 40 122 }) 123 .objectFit(ImageFit.Contain) 124 } 125 .margin({ 126 left: 5 127 }) 128 .size({ 129 width: 40, 130 height: 40 131 }) 132 .type(ButtonType.Circle) 133 .onClick(() => { 134 this.leftSliderIndex = -1 135 this.renameDialogShow(this.index, this.mediaItem.mediaType) 136 }) 137 138 Button() { 139 Image($r('app.media.icon_delete')) 140 .objectFit(ImageFit.Contain) 141 .size({ 142 width: 40, 143 height: 40 144 }) 145 } 146 .type(ButtonType.Circle) 147 .size({ 148 width: 40, 149 height: 40 150 }) 151 .backgroundColor('#FF0000') 152 .margin({ 153 left: 8 154 }) 155 .onClick(() => { 156 this.deleteDialogShow(this.index, this.mediaItem.mediaType) 157 this.leftSliderIndex = -1 158 }) 159 } 160 .width('15%') 161 .margin({ 162 left: 15, 163 right: 15 164 }) 165 } 166 .width('120%') 167 .margin({ 168 left: this.translateLeft, 169 right: 110 170 }) 171 .priorityGesture( 172 GestureGroup( 173 GestureMode.Parallel, 174 PanGesture({ 175 fingers: 1, 176 direction: PanDirection.Right, 177 distance: 20 178 }) 179 .onActionEnd(() => { 180 this.leftSliderIndex = -1 181 }), 182 PanGesture({ 183 fingers: 1, 184 direction: PanDirection.Left, 185 distance: 20 186 }) 187 .onActionEnd(() => { 188 this.leftSliderIndex = this.index 189 })) 190 ) 191 } 192}