1/**
2 * Copyright (c) 2023 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
16/**
17 * @file: User list component
18 */
19
20import CallStateConst from '../constant/CallStateConst';
21import CallServiceProxy from '../../model/CallServiceProxy';
22import LogUtils from '../utils/LogUtils';
23import DefaultCallData from '../struct/TypeUtils';
24import CallListStruct from '../struct/CallListStruct'
25import CallTimeListStruct from '../struct/CallTimeListStruct'
26
27const TAG = 'CallList';
28
29@Component
30export default struct CallList {
31  @Link callList: Array<CallListStruct>;
32  @Link callData: DefaultCallData;
33  @StorageLink('CallTimeList') callTimeList: Array<CallTimeListStruct> = [];
34  private mCallStateConst: CallStateConst;
35  private mCallServiceProxy: CallServiceProxy;
36
37  public aboutToAppear(): void {
38    LogUtils.i(TAG, 'aboutToAppear');
39    this.mCallStateConst = new CallStateConst();
40    this.mCallServiceProxy = CallServiceProxy.getInstance();
41  }
42
43  /**
44   * Three-way call list
45   *
46   * @return {boolean} - Three-way call list
47   */
48  getCallList() {
49    let arr = this.callList.map((item) => {
50      const obj = {};
51      return Object.assign({}, {
52        ...obj,
53        ...item
54      });
55    });
56    return arr.filter((v) => v.callState !== CallStateConst.CALL_STATUS_WAITING);
57  }
58
59  /**
60   * Phone number display
61   *
62   * @return {string} Phone number
63   */
64  public getContactName(item) {
65    return (item.contactName ? item.contactName : item.accountNumber) || $r('app.string.unknownNumber');
66  }
67
68  /**
69   * Phone number display
70   *
71   * @return {string} Phone number
72   */
73  public getCallTime(item) {
74    let callTimeObj = this.callTimeList.find((o) => o.callId === item.callId);
75    return callTimeObj ? callTimeObj.callTime : null;
76  }
77
78  /**
79   * Call status
80   *
81   * @return {number} -  callState
82   */
83  private callState() {
84    return this.callData.callState;
85  }
86
87  /**
88   * Hang up call
89   *
90   * @param {number} callId - callId
91   */
92  public onHangUp(callId) {
93    LogUtils.i(TAG, 'onHangUp : ' + callId);
94    this.mCallServiceProxy.hangUpCall(callId);
95    if (this.callList.length === 1) {
96      globalThis.calluiAbilityContext?.terminateSelf().then((data) => {
97        LogUtils.i(TAG, 'onHangUp terminateSelfCallBack');
98      });
99    }
100  }
101
102  /**
103   * UnHold call
104   *
105   * @param {number} callId - callId
106   */
107  public onUnHold(callId) {
108    LogUtils.i(TAG, 'onUnHold : ' + callId);
109
110    this.getCallList().forEach((item) => {
111      if (item.callState === CallStateConst.CALL_STATUS_HOLDING) {
112        this.mCallServiceProxy.unHoldCall(item.callId);
113        return;
114      }
115    });
116  }
117
118  getInComingCallState() {
119    let incomingState = false;
120    this.callList.forEach((v) => {
121      if (v.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING ||
122        v.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING) {
123        incomingState = true;
124      }
125    });
126    LogUtils.i(TAG, 'getInComingCallState incomingState:' + JSON.stringify(incomingState));
127    return incomingState;
128  }
129
130  build() {
131    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
132      List() {
133        ForEach(this.getCallList(), (item) => {
134          ListItem() {
135            Column() {
136              Row() {
137                Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
138                  Text(this.getContactName(item))
139                    .fontColor('#FFFFFF')
140                    .fontSize(16)
141                    .height(21)
142                    .lineHeight(19)
143
144                  Row() {
145                    if (item.callState === CallStateConst.callStateObj.CALL_STATUS_ACTIVE) {
146                      Text(this.getCallTime(item))
147                        .fontSize(14)
148                        .fontColor('#FFFFFF')
149                        .height(19)
150                        .lineHeight(19)
151                        .opacity(0.60)
152                    } else {
153                      Text(CallStateConst.callStateTextMap[item.callState])
154                        .fontSize(14)
155                        .fontColor('#FFFFFF')
156                        .height(19)
157                        .lineHeight(19)
158                        .opacity(0.60)
159                    }
160
161                    if (this.getInComingCallState()) {
162                      Image($r('app.media.ic_hangup_list'))
163                        .width(30)
164                        .height(30)
165                        .onClick(() => {
166                          this.onHangUp(item.callId);
167                        })
168                        .margin({ left: 16 })
169                    }
170                  }
171                }
172              }
173              .onClick(() => {
174                this.onUnHold(item.callId);
175              })
176              .height(64)
177            }
178          }
179        })
180      }
181      .divider({ strokeWidth: 1, color: $r('app.color.divider_calllist') })
182      .margin({ left: 24, right: 24 })
183      .width('100%')
184      .listDirection(Axis.Vertical)
185
186      Divider()
187        .color($r('app.color.divider_calllist'))
188        .strokeWidth(1)
189    }
190    .height(128)
191  }
192}