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}