1/** 2 * Copyright (c) 2021 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 */ 15import ResourceUtil from '../common/ResourceUtil'; 16import SearchData from '../model/SearchData'; 17import LogUtil from '../../../../../../utils/src/main/ets/default/baseUtil/LogUtil'; 18import Log from '../../../../../../utils/src/main/ets/default/baseUtil/LogDecorator'; 19import ConfigData from '../../../../../../utils/src/main/ets/default/baseUtil/ConfigData'; 20 21/** 22 * result component 23 */ 24@Component 25export default struct ResultComponent { 26 private TEXT_TYPE_NORMAL = 1 27 private TEXT_TYPE_KEYWORD = 2 28 @Link highlightKeyword: string 29 @State icon: string = '' 30 @State data: SearchData = new SearchData() 31 @State columnSpace: string = '2vp'; 32 33 @Builder HighlightText( 34 spans: string[], 35 fontColor: Color | Resource, 36 fontSize: Resource, 37 highlightFontColor: Color | Resource) { 38 39 Text() { 40 ForEach(spans.map((item1, index1) => { 41 return { index: index1, data: item1 }; 42 }), item => { 43 44 if (item.data.type == this.TEXT_TYPE_NORMAL) { 45 Span(item.data.text).fontColor(fontColor).fontSize(fontSize).fontWeight(FontWeight.Medium) 46 } else if (item.data.type == this.TEXT_TYPE_KEYWORD) { 47 Span(item.data.text).fontColor(highlightFontColor).fontSize(fontSize).fontWeight(FontWeight.Regular) 48 } 49 }, 50 item => item.index) 51 } 52 .textAlign(TextAlign.Start) 53 .maxLines(3) 54 .textOverflow({ overflow: TextOverflow.Ellipsis }) 55 } 56 57 build() { 58 Row() { 59 Image(this.icon) 60 .width($r('app.float.item_icon_size')) 61 .height($r('app.float.item_icon_size')) 62 .margin({ right: $r('app.float.sys_elements_margin_horizontal_l') }) 63 .visibility(this.icon ? Visibility.Visible : Visibility.Hidden) 64 .objectFit(ImageFit.Contain); 65 66 Column({space: this.columnSpace}){ 67 this.HighlightText( 68 this.splitToHighlightText(this.data.keyword), 69 $r('app.color.search_result_text_color'), 70 $r('app.float.search_result_item_title_font_size'), 71 $r('app.color.search_result_text_color_highlight'), 72 ) 73 74 if (this.data.summary) { 75 this.HighlightText( 76 this.splitToHighlightText(this.data.summary), 77 $r('sys.color.ohos_id_color_text_secondary'), 78 $r('app.float.search_result_item_summary_font_size'), 79 $r('app.color.search_result_text_color_highlight'), 80 ) 81 } 82 } 83 .layoutWeight(1) 84 .alignItems(HorizontalAlign.Start); 85 86 Image("/res/image/ic_settings_arrow.svg") 87 .width($r('app.float.item_arrow_width')) 88 .height($r('app.float.item_icon_size')) 89 .margin({ left: $r('app.float.sys_elements_margin_horizontal_m') }) 90 .fillColor($r("sys.color.ohos_id_color_fourth")) 91 } 92 .padding({ 93 left: $r('sys.float.ohos_id_card_margin_start'), 94 right: $r('sys.float.ohos_id_card_margin_end') 95 }) 96 .flexShrink(0) 97 .alignItems(VerticalAlign.Center) 98 .align(Alignment.Start) 99 } 100 101 @Log 102 aboutToAppear(){ 103 ResourceUtil.getString($r('app.float.distance_2')).then(value => this.columnSpace = value); 104 } 105 106 /** 107 * split to highlight text 108 * @param text 109 */ 110 @Log 111 splitToHighlightText(text: string): any[] { 112 let spans: any[] = [] 113 114 var lowerSpans: string[] = text.toLowerCase().split(this.highlightKeyword.toLowerCase()) 115 var keywordStartIndex = 0 116 var keywordLength = this.highlightKeyword.length 117 118 for (var i = 0; i < lowerSpans.length; i++) { 119 var normalText = text.substr(keywordStartIndex, lowerSpans[i].length) 120 spans.push({ 121 type: this.TEXT_TYPE_NORMAL, 122 text: normalText 123 }) 124 LogUtil.debug(ConfigData.TAG + 'ResultComponent splitToHighlightText : i = [' + i + '] push normal : ' + 125 JSON.stringify(normalText)); 126 127 // if not at last, append highlight keyword 128 if (i != lowerSpans.length - 1) { 129 keywordStartIndex += lowerSpans[i].length 130 var keywordText = text.substr(keywordStartIndex, keywordLength) 131 spans.push({ 132 type: this.TEXT_TYPE_KEYWORD, 133 text: keywordText 134 }) 135 LogUtil.debug(ConfigData.TAG + 'ResultComponent splitToHighlightText : i = [' + i + '] push keyword : ' + 136 JSON.stringify(keywordText)); 137 keywordStartIndex += keywordLength 138 } 139 } 140 141 return spans 142 } 143}