• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}