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