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 common from '@ohos.app.ability.common'; 17import { Location } from '../components/Location'; 18import { Information } from '../components/Information'; 19import { Choice } from '../components/Choice'; 20import { AddressService } from '../components/AddressService'; 21import { Valuation } from '../components/Valuation'; 22import { BottomNavigation } from '../components/BottomNavigation'; 23import { VideoPage } from '../components/VideoPage'; 24import { SmallVideo } from '../components/SmallVideo'; 25import { SWIPER_PICTURE_DATA } from '../mock/DetailData'; 26import { ButtonDialogBuilder } from '@ohos/sharecomponent'; 27import { ProductDataModel } from '../../../../../navigationHome/src/main/ets/model/GoodsModel' 28import { logger } from '../utils/Logger'; 29 30const SRC_IMG: string = 'https://res5.vmallres.com/pimages/uomcdn/CN/pms/202207/gbom/6941487270880/428_428_1142FAB7EA4DCBDD8C64BF54486A7D4Bmp.png'; 31let context = getContext(this) as common.UIAbilityContext; 32 33function getResourceString(resourceData: Resource): string { 34 let stringData: string = context.resourceManager.getStringSync(resourceData); 35 logger.info(`getResourceString start`); 36 logger.info(`getResourceString stringData ${stringData}`); 37 return stringData; 38} 39 40@Component 41export struct DetailPage { 42 @State sOpacity: number = 1; 43 @State isPanel: boolean = false; 44 @State goodDetailData: ProductDataModel = new ProductDataModel(0, '', '', '', '', ''); 45 @State currentLocation: string = ''; 46 @State recommend: string = ''; 47 @State commodity: string = ''; 48 @State swiperIndex: number = 0; 49 // Video组件 50 @State isHidden: boolean = false; 51 @State isState: boolean = true; 52 @State isCancel: boolean = true; 53 @State activeVideo: number = 0; 54 @State openFirst: boolean = false; 55 @Provide('playTime') playNum: number = 20; 56 @StorageProp('curBp') curBp: string = 'md'; 57 private shareDialog?: CustomDialogController; 58 private scroller: Scroller = new Scroller(); 59 @State isShowImage: boolean = true; 60 @State animateAppear: boolean = false; 61 @State animateScale: boolean = false; 62 @State animatePath: boolean = false; 63 @State breakPoints: string | undefined = AppStorage.get('breakPoint'); 64 @Consume('pageStack') pageStack: NavPathStack; 65 66 build() { 67 Stack({ alignContent: Alignment.Top }) { 68 Stack() { 69 Scroll(this.scroller) { 70 Column({ space: 12 }) { 71 Stack({ alignContent: Alignment.BottomEnd }) { 72 Swiper() { 73 VideoPage({ isStart: $openFirst, coverUrl: this.goodDetailData.uri as string }) 74 .id('VideoPage') 75 ForEach(SWIPER_PICTURE_DATA, () => { 76 Column() { 77 Image(this.goodDetailData.uri) 78 .objectFit(ImageFit.Contain); 79 } 80 .aspectRatio(1.12) 81 .backgroundColor('#ffffff') 82 .width('100%'); 83 }) 84 } 85 .height(this.breakPoints === 'sm' ? 400 : 300) 86 .index(this.swiperIndex) 87 .indicator(false) 88 .onChange((index: number) => { 89 this.swiperIndex = index; 90 }); 91 92 Row() { 93 Text(`${this.swiperIndex + 1}/${SWIPER_PICTURE_DATA.length + 1}`) 94 .fontSize(12) 95 .fontColor($r('app.color.white')); 96 } 97 .width(46) 98 .height(24) 99 .borderRadius(12) 100 .justifyContent(FlexAlign.Center) 101 .backgroundColor($r('app.color.bg3')) 102 .margin({ right: 16, bottom: 16 }); 103 } 104 .width('100%') 105 .height(this.breakPoints === 'sm' ? 400 : 300) 106 .backgroundColor($r('app.color.white')); 107 108 Column() { 109 Information({ goodDetailData: $goodDetailData }) 110 .margin({ top: 12 }); 111 Choice() 112 .margin({ top: 12 }); 113 AddressService({ currentLocation: $currentLocation, isPanel: $isPanel }) 114 .margin({ top: 12 }); 115 Valuation() 116 .margin({ top: 12 }); 117 } 118 .padding({ left: 12, right: 12 }); 119 } 120 .id('goodsDetail' + this.goodDetailData.id) 121 .width('100%'); 122 } 123 .width('100%') 124 .align(Alignment.Top) 125 .scrollBar(BarState.Off) 126 .padding({ bottom: this.curBp === 'sm' ? 86 : 106 }) 127 .onScroll(() => { 128 if (this.activeVideo === 0 && this.openFirst) { 129 if (this.scroller.currentOffset().yOffset > 450) { 130 if (this.isState) { 131 this.isHidden = true; 132 this.isState = false; 133 } 134 } else { 135 this.isHidden = false; 136 this.isState = true; 137 } 138 } 139 }); 140 141 Image($r('app.media.back')) 142 .width(32) 143 .aspectRatio(1) 144 .position({ x: 20, y: 20 }) 145 .onClick(() => { 146 this.pageStack.pop(); 147 }); 148 149 Image($r("app.media.share")) 150 .width(32) 151 .aspectRatio(1) 152 .position({ x: '100%', y: 20 }) 153 .translate({ x: -62, y: 0 }) 154 .onClick(() => { 155 this.shareDialog = new CustomDialogController({ 156 builder: ButtonDialogBuilder({ 157 controller: this.shareDialog, 158 detailTitleText: this.recommend, 159 detailPriceText: '9800', 160 title: this.commodity, 161 srcImage: SRC_IMG 162 }), 163 cancel: undefined, 164 autoCancel: true, 165 alignment: DialogAlignment.Bottom, 166 customStyle: true 167 }); 168 this.shareDialog?.open(); 169 }); 170 171 Column({ space: 12 }) { 172 Image($r('app.media.broadcast')) 173 .width(32) 174 .height(32); 175 176 Text($r('app.string.broadcast')) 177 .fontSize(14) 178 .fontColor($r('app.color.blank')); 179 } 180 .id('directVideo') 181 .width(62) 182 .height(78) 183 .borderWidth(0.5) 184 .borderColor($r('app.color.border')) 185 .borderRadius(16) 186 .padding(6) 187 .backgroundColor($r('app.color.light_white')) 188 .position({ x: '100%', y: 160 }) 189 .translate({ x: -82, y: 0 }) 190 .onClick(() => { 191 this.pageStack.pushPath({ name: 'LivePage' }) 192 }); 193 194 BottomNavigation({ 195 goodItemData: $goodDetailData, 196 animateAppear: $animateAppear, 197 animateScale: $animateScale, 198 animatePath: $animatePath 199 }) 200 .position({ x: 0, y: '100%' }) 201 .translate({ x: 0, y: -56 }); 202 SmallVideo({ isHidden: $isHidden, isCancel: $isCancel }) 203 .position({ x: '100%', y: '60%' }) 204 .translate({ x: -180, y: 0 }); 205 Panel(this.isPanel) { 206 Location({ isPanel: $isPanel, currentLocation: $currentLocation }); 207 } 208 .mode(PanelMode.Half) 209 .dragBar(false) 210 .halfHeight(this.curBp === 'sm' ? 650 : 530) 211 .miniHeight(0) 212 .onChange(() => { 213 this.isPanel = false; 214 }); 215 216 Column() { 217 Image(this.goodDetailData.uri) 218 .borderRadius(this.animateScale ? 1000 : 0) 219 .transition(TransitionEffect.OPACITY); 220 } 221 .width('100%') 222 .height(300) 223 .enabled(this.animatePath) 224 .visibility(this.animateAppear ? 0 : 1) 225 .scale(this.animateScale ? (this.animatePath ? { x: 0.1, y: 0.1, centerY: '50%' } : { 226 x: 0.2, 227 y: 0.2, 228 centerY: '50%' 229 }) : { x: 1, y: 1, centerY: '100%' }) 230 .opacity(this.animatePath ? 0.3 : 1) 231 .translate(this.animatePath ? { x: -80, y: 100 } : { x: 0 }) 232 .motionPath({ 233 path: 'Mstart.x start.y C -200 50, -150 200, end.x end.y', 234 from: 0.0, 235 to: 1.0, 236 rotatable: false 237 }); 238 } 239 .height('100%') 240 .width('100%') 241 .backgroundColor($r('app.color.divider')) 242 .align(this.animatePath ? Alignment.Bottom : Alignment.Top); 243 244 // 通过isShowImage变量开关控制页面跳转动效,默认为true 245 if (this.isShowImage) { 246 Column() { 247 Image(this.goodDetailData.uri) 248 .objectFit(ImageFit.Contain) 249 .sharedTransition('goods' + this.goodDetailData.id, { duration: 600, curve: Curve.Linear, delay: 100 }) 250 .onComplete(() => { 251 setTimeout(() => { 252 this.isShowImage = false; 253 }, 800); 254 }); 255 } 256 .width('100%') 257 .aspectRatio(1.12) 258 .backgroundColor('#ffffff'); 259 } 260 } 261 } 262 263 aboutToAppear() { 264 this.goodDetailData = this.pageStack.getParamByName('DetailPage')[0] as ProductDataModel; 265 logger.info('-------------------'); 266 logger.info(`Get AllPathName: ${JSON.stringify(this.pageStack.getAllPathName())}`); 267 logger.info(`Get params by Index:${JSON.stringify(this.pageStack.getParamByIndex(0))}`); 268 logger.info(`Get params by Name: ${JSON.stringify(this.pageStack.getParamByName('DetailPage'))}`); 269 logger.info(`Get index by Name: ${JSON.stringify(this.pageStack.getIndexByName('DetailPage'))}`); 270 logger.info(`Get stack size: ${JSON.stringify(this.pageStack.size())}`); 271 let context: Context = getContext(this); 272 this.currentLocation = context.resourceManager.getStringSync($r('app.string.address')); 273 this.recommend = context.resourceManager.getStringSync($r('app.string.recommend')); 274 this.commodity = context.resourceManager.getStringSync($r('app.string.commodity')); 275 } 276}