1/** 2 * Copyright (c) 2021-2022 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 SEARCH_DATA_CONFIG from '../model/search/SearchDataConfig'; 17import LogUtil from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogUtil'; 18import Log from '../../../../../../common/utils/src/main/ets/default/baseUtil/LogDecorator'; 19import SearchData from '../../../../../../common/search/src/main/ets/default/model/SearchData'; 20import SearchUtil from '../../../../../../common/search/src/main/ets/default/common/SearchUtil'; 21import ConfigData from '../../../../../../common/utils/src/main/ets/default/baseUtil/ConfigData'; 22import SearchModel from '../../../../../../common/search/src/main/ets/default/model/SearchModel'; 23import SearchHeader from '../../../../../../common/search/src/main/ets/default/page/searchHeader'; 24import ResourceUtil from '../../../../../../common/search/src/main/ets/default/common/ResourceUtil'; 25import ResultComponent from '../../../../../../common/search/src/main/ets/default/page/resultComponent'; 26 27 28interface SearchDataItem { 29 index: number; 30 data: SearchData; 31} 32 33/** 34 * search page 35 */ 36@Entry 37@Component 38struct SearchPage { 39 @State @Watch('setSearchKeyword') inputKeyword: string = ''; 40 @State @Watch('doSearch') searchKeyword: string = ''; 41 @State searchResultList: SearchData[][] = []; 42 @State data: SearchData = new SearchData(); 43 @State listSpace: string = '12vp'; 44 private searchModel?: SearchModel; 45 46 build() { 47 Column() { 48 GridContainer({ gutter: ConfigData.GRID_CONTAINER_GUTTER_24, margin: ConfigData.GRID_CONTAINER_MARGIN_24 }) { 49 Column() { 50 SearchHeader({ inputKeyword: $inputKeyword }) 51 52 if (this.searchKeyword) { 53 // search result exist 54 if (this.searchResultList && this.searchResultList.length > 0) { 55 List({ space: this.listSpace }) { 56 // search result list 57 ForEach(this.searchResultList, (eachBlock: SearchData[]) => { 58 ListItem() { 59 List() { 60 // item 61 ForEach(eachBlock.map((item2: SearchData, index2: number) => { 62 let searchDataItem: SearchDataItem = { index: index2, data: item2 } 63 return searchDataItem; 64 }), (item: SearchDataItem) => { 65 ListItem() { 66 Flex({ alignItems: ItemAlign.Center }) { 67 Navigator({ target: item.data.uri }) { 68 ResultComponent({ 69 highlightKeyword: $searchKeyword, 70 icon: item.index == 0 ? item.data.icon : '', 71 data: item.data 72 }); 73 } 74 } 75 .padding({ 76 top: $r('app.float.wh_value_8'), 77 bottom: $r('app.float.wh_value_8') 78 }) 79 } 80 .constraintSize({ 81 minHeight: this.data.summary ? $r('app.float.wh_value_64') : $r('app.float.wh_value_56') 82 }) 83 }) 84 } 85 .padding({ top: $r('app.float.wh_value_4'), bottom: $r('app.float.wh_value_4') }) 86 .width(ConfigData.WH_100_100) 87 .divider({ 88 strokeWidth: $r('app.float.divider_wh'), 89 color: $r('app.color.color_E3E3E3_grey'), 90 startMargin: $r('app.float.wh_value_52'), 91 endMargin: $r('app.float.wh_value_20') 92 }) 93 .borderRadius($r("sys.float.ohos_id_corner_radius_default_l")) 94 .backgroundColor($r("sys.color.ohos_id_color_foreground_contrary")) 95 } 96 }) 97 } 98 .width(ConfigData.WH_100_100) 99 } else { 100 // search no match 101 Column() { 102 Image($r("app.media.img_search_no_result")) 103 .width($r("app.float.search_no_result_image_size")) 104 .height($r("app.float.search_no_result_image_size")) 105 106 // search no match 107 Text($r("app.string.searchNoResult")) 108 .fontFamily('HarmonyHeiTi') 109 .fontSize($r("app.float.search_no_result_text_font_size")) 110 .fontColor($r("sys.color.ohos_id_color_tertiary")) 111 .fontWeight(FontWeight.Regular) 112 .lineHeight($r('app.float.wh_value_19')) 113 .alignSelf(ItemAlign.Center); 114 } 115 .alignItems(HorizontalAlign.Center) 116 .margin({ top: $r("app.float.search_no_result_margin_top") }) 117 } 118 } 119 } 120 .padding({ 121 left: $r('sys.float.ohos_id_card_margin_start'), 122 right: $r('sys.float.ohos_id_card_margin_end') 123 }) 124 .useSizeType({ 125 sm: { span: 4, offset: 0 }, 126 md: { span: 6, offset: 1 }, 127 lg: { span: 8, offset: 2 } 128 }) 129 } 130 .width(ConfigData.WH_100_100) 131 .height(ConfigData.WH_100_100) 132 } 133 .backgroundColor($r("sys.color.ohos_id_color_sub_background")) 134 .width(ConfigData.WH_100_100) 135 .height(ConfigData.WH_100_100) 136 } 137 138 aboutToAppear(): void { 139 ResourceUtil.getString($r('app.float.distance_12')).then(value => this.listSpace = value); 140 141 // init search data 142 this.searchModel = new SearchModel(SEARCH_DATA_CONFIG); 143 this.searchModel.initSearchData() 144 .then(() => { 145 LogUtil.debug(ConfigData.TAG + 'searchPage aboutToAppear initSearchData complete'); 146 this.doSearch() 147 }) 148 } 149 150 onBackPress() { 151 LogUtil.info('settings SearchPage onBackPress'); 152 } 153 154 /** 155 * set search keyword 156 */ 157 setSearchKeyword() { 158 this.searchKeyword = SearchUtil.stripKeyword(this.inputKeyword).trim() 159 } 160 161 /** 162 * search 163 */ 164 doSearch() { 165 if (this.searchModel) { 166 this.searchModel.search(this.searchKeyword) 167 .then((result: SearchData[]) => { 168 LogUtil.debug(ConfigData.TAG + 'searchPage doSearch : search : searchKeyword = ' + 169 this.searchKeyword + '; => then data = ' + JSON.stringify(result)); 170 this.searchResultList = []; 171 this.searchResultList = this.makeViewData(result); 172 LogUtil.debug(ConfigData.TAG + 'searchPage doSearch : searchResultList = ' + JSON.stringify(this.searchResultList)); 173 }) 174 } 175 } 176 177 /** 178 * make data for view 179 * 180 * @param result Search result 181 * @return Data for show to view 182 */ 183 makeViewData(result: SearchData[]): SearchData[][] { 184 let list: SearchData[][] = []; 185 let group: SearchData[] = []; 186 187 let lastUri: string = ''; 188 for (let i = 0; i < result.length; i++) { 189 let data = result[i]; 190 191 if (data.uri !== lastUri) { 192 if (group) { 193 let g = group; 194 list.push(g); 195 } 196 group = []; 197 lastUri = data.uri; 198 } 199 group.push(data); 200 201 if (i == result.length - 1) { 202 list.push(group); 203 } 204 } 205 return list; 206 } 207} 208