1/** 2 * Copyright (c) 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 router from '@ohos.router'; 17import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog'; 18import { ContactVo } from '../../model/bean/ContactVo'; 19import { ArrayUtil } from '../../../../../../common/src/main/ets/util/ArrayUtil'; 20import { CallLogRepository } from '../../../../../../feature/call/src/main/ets/repo/CallLogRepository'; 21import { ContactRepository } from '../../../../../../feature/contact/src/main/ets/repo/ContactRepository'; 22import ContactListDataSource from '../../model/bean/ContactListDataSource'; 23import WorkerWrapper from '../../workers/base/WorkerWrapper'; 24 25const TAG = 'ContactListPresenter '; 26const DELAY_TIME: number = 1000; 27/** 28 * Type of the control that is clicked in the contact list. 29 */ 30export enum ContactClickType { 31 LOGIN_IN, 32 IMPORT_CONTACT, 33 CREATE_CONTACT, 34 SCAN_CARD 35} 36 37/** 38 * Contact List Logical Interface Model 39 */ 40export default class ContactListPresenter { 41 private static sInstance: ContactListPresenter; 42 indexs: string[] = ['#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '…']; 43 contactListPages: Array<number> = []; 44 curItem: ContactVo = new ContactVo("", "", "", "", "", "", true, "", ""); 45 page: number = 0; 46 limit: number = 0; 47 refreshIndex: number = 0; 48 queryContactsType: string = 'all'; 49 isEmptyGroup: boolean = true; 50 shareList: Resource[] = [$r("app.string.qr_code"), $r("app.string.v_card"), $r("app.string.text")]; 51 settingsMenu: Resource[] = [$r("app.string.contact_setting_type_scancard"), $r("app.string.call_setting_type_setting")]; 52 contactListDataSource: ContactListDataSource = new ContactListDataSource(); 53 isShow: boolean = false; 54 context: Context; 55 worker: WorkerWrapper; 56 loading: boolean; 57 initStarted: boolean = false; 58 taskId: number = undefined; 59 refreshState: () => void 60 onContactChange = () => { 61 HiLog.i(TAG, 'onContactChange refresh'); 62 this.setDelayTask(); 63 } 64 65 private constructor() { 66 } 67 68 public static getInstance(): ContactListPresenter { 69 if (globalThis.presenterManager?.contactListPresenter) { 70 return globalThis.presenterManager.contactListPresenter; 71 } 72 if (ContactListPresenter.sInstance == null) { 73 HiLog.i(TAG, 'Contact getInstance!'); 74 ContactListPresenter.sInstance = new ContactListPresenter(); 75 } 76 return ContactListPresenter.sInstance; 77 } 78 79 onCreate(context: Context, worker: WorkerWrapper) { 80 this.context = context; 81 this.worker = worker; 82 ContactRepository.getInstance().registerDataChangeObserver(this.onContactChange); 83 } 84 85 onDestroy() { 86 ContactRepository.getInstance().unRegisterDataChangeObserver(this.onContactChange); 87 } 88 89 bindUI(refreshState?: () => void) { 90 this.refreshState = refreshState; 91 } 92 93 startInit() { 94 if (this.initStarted) { 95 return; 96 } 97 HiLog.i(TAG, "startInit"); 98 this.initStarted = true; 99 if (this.page == 0) { 100 this.page++; 101 } 102 this.refreshContinue(); 103 } 104 105 cachePageOne() { 106 if (!this.initStarted && !this.loading) { 107 HiLog.i(TAG, "cachePageOne") 108 this.page = 1; 109 this.refreshIndex = 0; 110 this.refreshContinue(); 111 } else { 112 HiLog.i(TAG, "no need cachePageOne"); 113 } 114 } 115 116 aboutToAppear() { 117 HiLog.i(TAG, 'Contact aboutToAppear!'); 118 this.startInit(); 119 } 120 121 aboutToDisappear() { 122 HiLog.i(TAG, 'Contact aboutToDisappear!'); 123 } 124 125 setPageShow(isShow: boolean) { 126 if (this.isShow == isShow) { 127 return; 128 } 129 this.isShow = isShow; 130 if (this.isShow) { 131 this.startInit(); 132 } 133 this.contactListDataSource.setIsShow(isShow); 134 } 135 136 requestItem() { 137 HiLog.i(TAG, 'Contacts requestItem!'); 138 if (this.page == 0) { 139 this.page++; 140 this.refreshContinue(); 141 } else if (!this.initStarted && !this.loading) { 142 this.cachePageOne(); 143 } else { 144 HiLog.i(TAG, 'isLoading'); 145 } 146 } 147 148 setDelayTask() { 149 if (this.taskId != undefined) { 150 clearTimeout(this.taskId); 151 this.taskId = undefined; 152 } 153 let delay: number = 0; 154 if (this.page != 0) { 155 delay += DELAY_TIME; 156 } 157 if (!this.isShow) { 158 delay += DELAY_TIME; 159 } 160 if (delay > 0) { 161 this.taskId = setTimeout(() => { 162 if (this.page != 0) { 163 this.setDelayTask(); 164 } else { 165 this.requestItem(); 166 } 167 }, delay); 168 } else { 169 this.requestItem(); 170 } 171 } 172 173 refreshContinue() { 174 if (this.loading) { 175 HiLog.i(TAG, 'refreshContinue is loading'); 176 return; 177 } 178 if (this.page == 0) { 179 HiLog.i(TAG, 'refreshContinue end'); 180 return; 181 } 182 if (this.page == 1) { 183 this.limit = 50; 184 } else { 185 this.limit = 500; 186 } 187 this.refreshPage(this.page, this.limit, () => { 188 if (this.initStarted) { 189 setTimeout(() => { 190 this.refreshContinue(); 191 },!this.isShow ? 700 : 1); 192 } 193 }) 194 } 195 196 refreshPage(page: number, limit: number, callback?: () => void) { 197 this.loading = true; 198 let actionData: any = {}; 199 actionData.page = page; 200 actionData.limit = limit; 201 this.worker.sendRequest("getAllContact", { 202 actionData: actionData, 203 context: this.context 204 }, (result) => { 205 HiLog.i(TAG, `refreshPage ${page} getAllContact, length is: ` + result.length); 206 if (Array.prototype.isPrototypeOf(result)) { 207 this.contactListDataSource.refresh(this.refreshIndex, this.contactListPages[page -1], result); 208 } 209 this.contactListPages[page -1] = result.length; 210 this.refreshIndex += this.contactListPages[page -1]; 211 if (this.refreshState) { 212 this.refreshState(); 213 } 214 let contactCount = result.length; 215 if (contactCount < limit) { 216 this.page = 0; 217 HiLog.i(TAG, 'Contacts load completed: ' + JSON.stringify(this.contactListDataSource.totalCount())); 218 if (this.contactListPages.length > page) { 219 this.contactListPages.splice(page, this.contactListPages.length - page); 220 } 221 if (this.contactListDataSource.totalCount() > this.refreshIndex) { 222 this.contactListDataSource.remove(this.refreshIndex, this.contactListDataSource.totalCount() - this.refreshIndex); 223 } 224 this.refreshIndex = 0; 225 this.loading = false; 226 } else { 227 this.page = page + 1; 228 this.loading = false; 229 if (callback) { 230 callback(); 231 } 232 } 233 }) 234 } 235 236 237 /** 238 * Touch and hold the current contact information saved by a contact item in the contact list. 239 * The information can be deleted or shared later. 240 * 241 * @param curItem 242 */ 243 setCurItem(curItem: ContactVo) { 244 HiLog.i(TAG, 'setCurItem'); 245 this.curItem = curItem; 246 } 247 248 /** 249 * Cancel button for deleting a dialog box. 250 */ 251 onDeleteDialogCancel() { 252 HiLog.i(TAG, 'onDeleteDialogCancel !!!'); 253 } 254 255 /** 256 * Confirm button for deleting a dialog box 257 * 258 * @param result 259 */ 260 onDeleteDialogConfirm(index, item) { 261 HiLog.i(TAG, 'onDeleteDialogConfirm !!! '); 262 this.worker.sendRequest("deleteContactById", { 263 context: this.context, 264 contactId: item.contactId 265 }, (result) => { 266 if (result) { 267 HiLog.w(TAG, "deleteContactById error:" + JSON.stringify(result)) 268 } 269 ContactRepository.getInstance().notifyChange(); 270 }); 271 this.contactListDataSource.remove(index); 272 } 273 274 /** 275 * Share Cancel Button 276 */ 277 onShareDialogCancel() { 278 HiLog.i(TAG, 'onShareDialogCancel !!! '); 279 } 280 281 /** 282 * Share confirmation button 283 */ 284 onShareDialogConfirm() { 285 HiLog.i(TAG, 'onShareDialogConfirm !!! '); 286 } 287 288 /** 289 * Event callback when an item is clicked in the sharing dialog box 290 * 291 * @param item item 292 * @param index index 293 */ 294 onShareItemClick(item: any, index: number | null) { 295 HiLog.i(TAG, 'onShareItemClick !!! index is %s' + index); 296 } 297 298 /** 299 * Log in to Huawei ID. 300 */ 301 loginAccount() { 302 HiLog.i(TAG, 'loginAccount !!'); 303 router.push( 304 { 305 url: "", 306 params: {} 307 } 308 ); 309 } 310 311 /** 312 * Import Contact dialog box 313 */ 314 importContact() { 315 HiLog.i(TAG, 'importContact !!'); 316 router.push( 317 { 318 url: "", 319 params: {} 320 } 321 ); 322 } 323 324 /** 325 * New Contact 326 */ 327 createContact() { 328 HiLog.i(TAG, 'createContact !!'); 329 router.push( 330 { 331 url: "pages/contacts/accountants/Accountants" 332 } 333 ); 334 } 335 336 /** 337 * Scan the business card. 338 */ 339 scanCard() { 340 HiLog.i(TAG, 'scanCard !!'); 341 router.push( 342 { 343 url: "" 344 } 345 ); 346 } 347}