• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
15import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
16import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
17import audio from '@ohos.multimedia.audio';
18import router from '@ohos.router';
19import observer from '@ohos.telephony.observer';
20import PreferencesUtil from '../../util/PreferencesUtil';
21import { PhoneNumber } from '../../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
22import IndexPresenter from '../IndexPresenter';
23import CallRecordListDataSource from '../../model/bean/CallRecordListDataSource';
24const TAG = 'DialerPresenter';
25const SECRET_CODE_START: string = '*#*#';
26const SECRET_CODE_END: string = '#*#*';
27
28/**
29 * dialer presenter
30 */
31export default class DialerPresenter {
32  private static mPresenter: DialerPresenter;
33  private _isCallStateChangeObserved = false;
34  readonly NUM_TEXT_MAX_LENGTH = 20;
35  readonly NUM_TEXT_MAXSIZE_LENGTH = 14;
36  readonly NUM_TEXT_FONT_SIZE_MAX = 38;
37  private timer: any = null;
38  btnShow: boolean = true;
39  isEmergencyNum: boolean = false;
40  tele_number: string = '';
41  tele_num_size: number = this.NUM_TEXT_FONT_SIZE_MAX;
42  all_number: string = '';
43  call_p: number = 134;
44  call_y: number = 6;
45  moveY: number = 336;
46  dialerButtonWidth = 48;
47  dialerButtonHeight = 48;
48  dialerRadius = 24;
49  refreshView: boolean;
50  callBtnClick: boolean;
51  secretCode: string = '';
52  isPalyAudioing: boolean = false;
53  mAllCallRecordListDataSource: CallRecordListDataSource = new CallRecordListDataSource();
54  callLogSearchList: any[] = [];
55  static getInstance() {
56    if (this.mPresenter == null) {
57      this.mPresenter = new DialerPresenter();
58    }
59    return this.mPresenter;
60  }
61
62  aboutToAppear() {
63    if (!PreferencesUtil.isUsed() && !this._isCallStateChangeObserved) {
64      observer.on('callStateChange', (callback: {
65        state,
66        number,
67      }) => {
68        HiLog.i(TAG, 'callStateChange state' + callback.state);
69        if (callback.state === 0) {
70          HiLog.i(TAG, 'callback.state:' + callback.state);
71          this.refresh();
72        }
73      });
74      this._isCallStateChangeObserved = true;
75    }
76  }
77
78  refresh() {
79    if (!PreferencesUtil.isUsed()) {
80      PreferencesUtil.setIsUsed(true);
81      this.refreshView = !this.refreshView;
82    }
83  }
84
85  editPhoneNumber(phoneNum): void {
86    if (StringUtil.isEmpty(phoneNum)) {
87      return;
88    }
89    HiLog.i(TAG, 'editPhoneNumber');
90    AppStorage.SetOrCreate('tele_number', phoneNum);
91    this.all_number = phoneNum;
92    this.viewNumberTextProc();
93    this.deleteAddSpace();
94//    this.callHistorySearch()
95  }
96
97  onDestroy() {
98  }
99
100  /*
101   * Change the font size when deleting a number.
102   */
103  deleteTeleNum() {
104//    this.callHistorySearch()
105    let number: string = AppStorage.Get('tele_number');
106    if (this.all_number.length < this.NUM_TEXT_MAX_LENGTH) {
107      AppStorage.SetOrCreate('tele_number', this.all_number);
108    } else {
109      AppStorage.SetOrCreate('tele_number', this.all_number.substr(this.all_number.length - this.NUM_TEXT_MAX_LENGTH));
110    }
111    if (number.length > this.NUM_TEXT_MAXSIZE_LENGTH) {
112      this.tele_num_size = this.NUM_TEXT_FONT_SIZE_MAX * this.NUM_TEXT_MAXSIZE_LENGTH / number.length;
113    } else if (number.length <= this.NUM_TEXT_MAXSIZE_LENGTH) {
114      this.tele_num_size = this.NUM_TEXT_FONT_SIZE_MAX;
115    }
116  }
117
118  /*
119   * Add formatting spaces when deleting a number.
120   */
121  deleteAddSpace() {
122    let number: string = AppStorage.Get('tele_number');
123    let teleNumberNoSpace = StringUtil.removeSpace(number);
124    this.all_number = StringUtil.removeSpace(this.all_number);
125    if (teleNumberNoSpace.length > this.NUM_TEXT_MAXSIZE_LENGTH - 2) {
126      AppStorage.SetOrCreate('tele_number', teleNumberNoSpace);
127      return;
128    }
129    if (this.checkNeedNumberSpace(number)) {
130      if (teleNumberNoSpace.length <= 3) {
131        AppStorage.SetOrCreate('tele_number', teleNumberNoSpace);
132        return;
133      }
134      if (teleNumberNoSpace.length > 3) {
135        let split1 = teleNumberNoSpace.substr(0, 3);
136        let split2 = teleNumberNoSpace.substr(3, teleNumberNoSpace.length - 3);
137        AppStorage.SetOrCreate('tele_number', split1 + ' ' + split2);
138        if (teleNumberNoSpace.length > 7) {
139          split2 = teleNumberNoSpace.substr(3, 4);
140          let split3 = teleNumberNoSpace.substr(7, teleNumberNoSpace.length - 7);
141          AppStorage.SetOrCreate('tele_number', split1 + ' ' + split2 + ' ' + split3);
142        }
143      }
144    } else {
145      if (teleNumberNoSpace.length > 8) {
146        let split4 = teleNumberNoSpace.substr(0, 8);
147        let split5 = teleNumberNoSpace.substr(8, teleNumberNoSpace.length - 8);
148        AppStorage.SetOrCreate('tele_number', split4 + ' ' + split5);
149      }
150    }
151  }
152
153  /*
154   * Check whether formatting spaces are required when entering a number.
155   */
156  checkNeedNumberSpace(numText) {
157    let isSpace = /[\+;,#\*]/g;
158    let isRule = /^\+.*/;
159    if (isSpace.test(numText)) {
160      // If the number string contains special characters, no space is added.
161      if (isRule.test(numText)) {
162        return true;
163      } else {
164        return false;
165      }
166    }
167    return true;
168  }
169
170  dialing(phoneNumber, options?: any) {
171    this.editPhoneNumber('');
172    PhoneNumber.fromString(phoneNumber).dial(options).then((rst) => {
173      this.refresh();
174    });
175  }
176
177  /*
178   * Key vibration
179   */
180  pressVibrate() {
181  }
182
183  /*
184   * Add a space when entering a number.
185   */
186  ifNeedSpace() {
187    let needNumber: string = AppStorage.Get('tele_number');
188    switch (needNumber.length) {
189      case 3:
190        if (this.checkNeedNumberSpace(needNumber)) {
191          AppStorage.SetOrCreate('tele_number', needNumber + ' ');
192        }
193        break;
194      case 8:
195        AppStorage.SetOrCreate('tele_number', needNumber + ' ');
196        break;
197      default:
198        break;
199    }
200  }
201
202  /*
203   * Processing of Overlong Input Numbers
204   */
205  viewNumberTextProc() {
206    let numStringNoSpace_all = StringUtil.removeSpace(this.all_number);
207    let number: string = AppStorage.Get('tele_number');
208    AppStorage.SetOrCreate('tele_number', numStringNoSpace_all.length > this.NUM_TEXT_MAX_LENGTH ?
209    numStringNoSpace_all.substr(numStringNoSpace_all.length - this.NUM_TEXT_MAX_LENGTH) : number
210    );
211    if (number.length > this.NUM_TEXT_MAXSIZE_LENGTH) {
212      AppStorage.SetOrCreate('tele_number', StringUtil.removeSpace(number));
213    }
214    if (number.length > this.NUM_TEXT_MAXSIZE_LENGTH) {
215      this.tele_num_size = this.NUM_TEXT_FONT_SIZE_MAX * this.NUM_TEXT_MAXSIZE_LENGTH / (number.length); // 可视号码在16-25位时,适配font-size
216    } else {
217      this.tele_num_size = this.NUM_TEXT_FONT_SIZE_MAX;
218    }
219  }
220
221  /*
222   * Play different audio resources based on key digits.
223   */
224  playAudio(number) {
225    switch (number.toString()) {
226      case '1':
227        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_1);
228        break;
229      case '2':
230        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_2);
231        break;
232      case '3':
233        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_3);
234        break;
235      case '4':
236        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_4);
237        break;
238      case '5':
239        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_5);
240        break;
241      case '6':
242        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_6);
243        break;
244      case '7':
245        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_7);
246        break;
247      case '8':
248        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_8);
249        break;
250      case '9':
251        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_9);
252        break;
253      case '0':
254        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_0);
255        break;
256      case '*':
257        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_S);
258        break;
259      case '#':
260        this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_P);
261        break;
262      default:
263        HiLog.e(TAG, 'keytone src is error');
264    }
265  }
266
267  async tonePlayer(type) {
268    HiLog.i(TAG, 'TonePlayer type: ' + type);
269    let that = this;
270    let tonePlayer = null;
271    let audioRendererInfo = {
272      content: audio.ContentType.CONTENT_TYPE_UNKNOWN,
273      usage: audio.StreamUsage.STREAM_USAGE_DTMF,
274      rendererFlags: 0
275    };
276
277    if (!this.isPalyAudioing) {
278      this.isPalyAudioing = true;
279      tonePlayer = await audio.createTonePlayer(audioRendererInfo);
280      await tonePlayer.load(type);
281      await tonePlayer.start();
282      setTimeout(async () => {
283        that.isPalyAudioing = false;
284        await tonePlayer.stop();
285        await tonePlayer.release();
286      }, 15)
287    }
288  };
289
290  /*
291   * Jump to New Contact
292   */
293  jumpToAccountants() {
294    router.push({
295      url: 'pages/contacts/accountants/Accountants',
296      params: {
297        updataShow: false,
298        phoneNumbers: [{
299                         phoneNumber: AppStorage.Get('tele_number')
300                       }]
301      },
302    })
303  }
304
305  sendMessage() {
306    let formatnum = PhoneNumber.fromString(this.all_number).format();
307    PhoneNumber.fromString(this.all_number).sendMessage(formatnum, formatnum);
308  }
309
310  saveCallRecordExistingContact() {
311    HiLog.i(TAG, 'saveCallRecordExistingContact start.');
312    router.pushUrl({
313      url: 'pages/contacts/batchselectcontacts/SingleSelectContactPage',
314      params: {
315        phoneNumberShow: AppStorage.Get('tele_number'),
316        editContact: 2,
317      }
318    });
319  }
320
321  dealSecretCode(value: string) {
322    let length = value.length;
323    if (length > 8 && value.startsWith(SECRET_CODE_START) && value.endsWith(SECRET_CODE_END)) {
324      let str = value.substring(SECRET_CODE_START.length, length - SECRET_CODE_END.length);
325      this.secretCode = str;
326    } else {
327      this.secretCode = '';
328    }
329  }
330
331  callHistorySearch() {
332    let teleNumber: string = AppStorage.Get('tele_number');
333    globalThis.DataWorker.sendRequest('getQueryT9PhoneNumbers', {
334      favoriteForm: JSON.stringify({favorite:{teleNumber:teleNumber.replace(/\s*/g,'')}}),
335      context: globalThis.context
336    }, (result) => {
337      let nameArray = [];
338      for (let i = 0; i < result.length; i++) {
339        nameArray.push(result[i].showName);
340        result[i].displayName = result[i]?.showName || result[i]?.phoneNumbers[0]?.phoneNumber || '';
341        result[i].phoneNumber = result[i]?.phoneNumbers[0]?.phoneNumber || '';
342      }
343      const queryCall = {context: globalThis.context,mergeRule: '', actionData: {teleNumber:teleNumber.replace(/\s*/g,''), nameArray}};
344      globalThis.DataWorker?.sendRequest('getCallHistorySearch', queryCall, (data) => {
345        this.callLogSearchList = [];
346        if(data.callLogList.length > 0 || result.length > 0){
347          this.callLogSearchList = [...this.callLogSearchList,...result]
348          for (let i = 0; i < data.callLogList.length; i++) {
349            const displayName = data?.callLogList[i]?.displayName || data?.callLogList[i]?.phoneNumber;
350            if(!nameArray.includes(displayName)){
351              nameArray.push(displayName)
352              this.callLogSearchList.push({...data.callLogList[i], displayName});
353            }
354          }
355        }
356        this.mAllCallRecordListDataSource.refreshAll(this.callLogSearchList.sort((a: any, b: any)=> (a.count || 0) - (b.count || 0)));
357      })
358    })
359  }
360
361  jumpToContactDetail(phoneNumber) {
362    router.pushUrl(
363      {
364        url: 'pages/contacts/details/ContactDetail',
365        params: {
366          sourceHasPhone: true,
367          phoneNumberShow: phoneNumber
368        }
369      }
370    )
371  }
372}