• 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 { ChangelogInfo } from '@ohos/common/src/main/ets/manager/UpgradeInterface';
17import {
18  Changelog,
19  ChangelogType,
20  Feature,
21  Features,
22  Language
23} from '@ohos/common/src/main/ets/const/update_const';
24import { DeviceUtils } from '@ohos/common/src/main/ets/util/DeviceUtils';
25import { LogUtils } from '@ohos/common/src/main/ets/util/LogUtils';
26import ChangelogParseUtils from '../util/ChangelogParseUtils';
27
28/**
29 * changelog组件
30 *
31 * @since 2022-06-06
32 */
33@Component
34export struct ChangelogContent {
35  @State private changelogInfoList: Array<ChangelogInfo> = null;
36  private isCurrentPage: boolean;
37  isNeedFold: boolean;
38  @Prop @Watch('parseChangelog') description: string;
39  @State private isParseChangelogFinished: boolean = false;
40
41  @Builder buildChangelog() {
42    Column() {
43      if (this.changelogInfoList && this.isParseChangelogFinished) {
44        ForEach(this.changelogInfoList, (item: ChangelogInfo, index?: number) => {
45          ChangelogCard({
46            changelogInfo: item,
47            index: this.changelogInfoList?.length > 1 ? index + 1 : 0,
48            isCurrentPage: this.isCurrentPage
49          });
50        })
51      } else {
52        ChangelogCard();
53      }
54      if (this.changelogInfoList?.[0]?.endFeatures && !this.isCurrentPage && this.isParseChangelogFinished) {
55        Column() {
56          this.setEndFeature();
57        }
58        .alignItems(HorizontalAlign.Start)
59        .margin({
60          left: $r('app.float.changelog_end_content_margin_horizontal'),
61          right: $r('app.float.changelog_end_content_margin_horizontal'),
62          bottom: $r('app.float.changelog_tablet_end_content_margin_bottom')
63        })
64      }
65    }.width('100%')
66  }
67
68  @Builder setEndFeature() {
69    Text(this.changelogInfoList?.[0].endFeatures.title)
70      .fontSize($r('app.float.changelog_content_end_title'))
71      .fontColor($r('sys.color.ohos_fa_text_secondary'))
72      .fontWeight(FontWeight.Medium)
73      .width('100%')
74    ForEach(this.changelogInfoList?.[0].endFeatures.featureList, (feature: Feature) => {
75      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
76        ForEach(feature.contents, (content: string) => {
77          Text(content)
78            .fontColor($r('sys.color.ohos_fa_icon_secondary'))
79            .fontSize($r('app.float.changelog_end_word'))
80            .fontWeight(FontWeight.Regular)
81            .align(Alignment.Start)
82            .padding({ top: this.changelogInfoList?.[0].endFeatures.featureList.indexOf(feature) == 0 ?
83            $r('app.float.changelog_tablet_has_feature_padding_top') :
84            $r('app.float.changelog_tablet_no_feature_padding_top')
85            });
86        });
87      }
88    });
89  }
90
91  aboutToAppear() {
92    this.logInfo('aboutToAppear');
93    this.parseChangelog();
94  }
95
96  private parseChangelog(): void {
97    this.logInfo('parseChangelog');
98    let list: Array<ChangelogInfo> = null;
99    if (this.description) {
100      list = JSON.parse(this.description);
101    }
102    if (list) {
103      this.logInfo('aboutToAppear parseXml');
104      let isParseSuccess: boolean = true;
105      list?.forEach((changelogInfo: ChangelogInfo, index: number) => {
106        ChangelogParseUtils.parseXml(changelogInfo.content, (data) => {
107          if (!data) {
108            isParseSuccess = false;
109            this.logError('aboutToAppear parseXml error');
110            return;
111          }
112          let language = DeviceUtils.getSystemLanguage();
113          changelogInfo.headFeatures = this.getHeaderFeatures(data, language);
114          changelogInfo.endFeatures = this.getEndFeatures(data, language);
115          changelogInfo.contentFeatures = this.getContentFeatures(data, language);
116          if (data.displayType) {
117            changelogInfo.displayType = data.displayType;
118          }
119        });
120      });
121      this.isParseChangelogFinished = true;
122      this.changelogInfoList = isParseSuccess ? list : null;
123    } else {
124      this.logInfo('description is null');
125    }
126  }
127
128  private getHeaderFeatures(changelog: Changelog, language: string): Features {
129    return this.getTargetFeatures(changelog, language, 'header');
130  }
131
132  private getEndFeatures(changelog: Changelog, language: string): Features{
133    return this.getTargetFeatures(changelog, language, 'end');
134  }
135
136  private getContentFeatures(changelog: Changelog, language: string): Array<Features> {
137    let featuresList: Array<Features> = [];
138    if (changelog == null || language == null) {
139      return featuresList;
140    }
141    let lang: Language = changelog.language.get(language);
142    if (lang == null) {
143      return featuresList;
144    }
145
146    for (let index = 0; index < lang.featuresArray.length; index++) {
147      const features = lang.featuresArray[index];
148      if (features != null && features.featureModuleType != 'header' && features.featureModuleType != 'end') {
149        featuresList.push(features);
150      }
151    }
152    return featuresList;
153  }
154
155  private getTargetFeatures(changelog: Changelog, language: string, type: string): Features {
156    if (changelog == null || language == null) {
157      return null;
158    }
159    let lang: Language = changelog.language.get(language);
160    if (lang == null) {
161      return null;
162    }
163    for (let index = 0; index < lang.featuresArray.length; index++) {
164      const features = lang.featuresArray[index];
165      if (features != null && features.featureModuleType == type) {
166        return features;
167      }
168    }
169  }
170
171  build(): void{
172    this.buildChangelog();
173  }
174
175  private logInfo(message: string): void {
176    LogUtils.info('ChangelogContent', message);
177  }
178
179  private logError(message: string): void {
180    LogUtils.error('ChangelogContent', message);
181  }
182}
183
184/**
185 * 更新日志卡片
186 *
187 * @since 2022-12-01
188 */
189@Component
190struct ChangelogCard {
191  changelogInfo: ChangelogInfo;
192  index: number;
193  isCurrentPage: boolean = false;
194
195  aboutToAppear() {
196  }
197
198  build () {
199    Column() {
200      Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {
201        Text($r('app.string.title_change_log'))
202          .fontSize($r('sys.float.ohos_id_text_size_sub_title2'))
203          .fontWeight(FontWeight.Medium)
204          .width('100%')
205      }
206
207      if (!this.changelogInfo) {
208        this.setDetailFeature($r('app.string.no_info_now'));
209      }
210
211      if (this.changelogInfo?.headFeatures) {
212        this.setStartFeature(this.changelogInfo);
213      }
214      if (this.changelogInfo?.contentFeatures) {
215        this.setContentFeatures(this.changelogInfo);
216      }
217    }
218    .padding({
219      left: $r('app.float.changelog_tablet_start_content_padding_horizontal'),
220      right: $r('app.float.changelog_tablet_start_content_padding_horizontal'),
221      top: $r('app.float.changelog_tablet_start_content_padding_top'),
222      bottom: $r('app.float.changelog_tablet_start_content_padding_bottom')
223    })
224    .margin({
225      left: $r('app.float.changelog_detail_content_margin_horizontal'),
226      right: $r('app.float.changelog_detail_content_margin_horizontal'),
227      bottom: $r('app.float.changelog_tablet_start_content_margin_bottom')
228    })
229    .backgroundColor(Color.White)
230    .alignItems(HorizontalAlign.Start)
231    .borderRadius($r('app.float.card_border_radius'))
232  }
233
234  @Builder setDetailFeature(content: string | Resource) {
235    Text(content)
236      .opacity(0.6)
237      .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
238      .fontWeight(FontWeight.Regular)
239      .align(Alignment.Start)
240      .padding({ top: $r('app.float.changelog_tablet_start_detail_padding_top') });
241  }
242
243  @Builder setStartFeature(changelogInfo: ChangelogInfo) {
244    if (changelogInfo.headFeatures.featureList) {
245      this.setFeatureContent(changelogInfo.headFeatures.featureList)
246    }
247  }
248
249  @Builder setFeatureContent(featureList: Array<Feature>) {
250    ForEach(featureList, (item: Feature) => {
251      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
252        ForEach(item.contents, (content: string) => {
253          Text(content)
254            .opacity(0.6)
255            .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
256            .fontWeight(FontWeight.Regular)
257            .align(Alignment.Start)
258            .padding({ top: featureList.indexOf(item) == 0 ?
259            $r('app.float.changelog_tablet_has_feature_padding_top') :
260            $r('app.float.changelog_tablet_no_feature_padding_top')
261            });
262        });
263      }
264    });
265  }
266
267  @Builder setContentFeatures(changelogInfo: ChangelogInfo) {
268    if (this.changelogInfo?.displayType == ChangelogType.TEXT) {
269      ForEach(changelogInfo.contentFeatures, (features: Features) => {
270        Text(features.title)
271          .opacity(0.6)
272          .fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
273          .fontWeight(FontWeight.Regular)
274          .align(Alignment.Start)
275          .padding({ top: $r('app.float.changelog_tablet_start_content_padding_top')})
276        Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
277          if (features.featureList) {
278            this.setFeatureContent(features.featureList)
279          }
280        }
281      })
282    }
283  }
284}