@ -27,6 +27,7 @@ const TAG = "CallManagerService";
|
||||
const CALL_BUNDLE_NAME = 'com.ohos.callui';
|
||||
const ABILITY_NAME = 'com.ohos.callui.MainAbility';
|
||||
const CALL_STATUS_INCOMING = 4;
|
||||
const CALL_STATUS_WAITING = 5
|
||||
const CALL_STATUS_DIALING = 2;
|
||||
const CALL_STATUS_DISCONNECTED = 6;
|
||||
const CALL_STATUS_DISCONNECTING = 7;
|
||||
@ -129,7 +130,10 @@ export default class CallManagerService {
|
||||
/**
|
||||
* single call or dialing pull up the application
|
||||
*/
|
||||
if ((callState === CALL_STATUS_INCOMING && this.callList.length === 1) || callState === CALL_STATUS_DIALING) {
|
||||
if (callState === CALL_STATUS_INCOMING || callState === CALL_STATUS_WAITING || callState === CALL_STATUS_DIALING) {
|
||||
if (this.callList.length > 1) {
|
||||
this.publishData(callData)
|
||||
}
|
||||
this.startAbility(callData);
|
||||
} else if (callState !== CALL_STATUS_DISCONNECTING) {
|
||||
this.publishData(callData);
|
||||
|
8
entry/src/main/ets/assets/picture/ic_merge.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_merge</title>
|
||||
<g id="ic_merge" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M11.3773655,1.59318035 C11.9333544,1.27217997 12.6339647,1.42857611 13.0045353,1.93518376 L13.0787187,2.04905657 L16.2592478,7.55789461 C16.3685613,7.74723104 16.4261101,7.96200623 16.4261101,8.18063311 C16.4261101,8.82549994 15.9360152,9.35589898 15.3079759,9.41967985 L15.1806331,9.42611011 L12.765813,9.42611011 L12.7666285,11.6743596 C12.7666285,16.755889 16.1894212,21.1576237 21.024705,22.4572669 C21.4257877,22.5650713 21.6635368,22.9776058 21.5557325,23.3786885 C21.4479282,23.7797713 21.0353937,24.0175204 20.6343109,23.9097161 C16.5763509,22.8190044 13.3957223,19.8044379 12.0135386,15.9764756 C10.6336388,19.8044732 7.45311482,22.8190157 3.395197,23.9097161 C2.99411425,24.0175204 2.58157976,23.7797713 2.47377543,23.3786885 C2.3659711,22.9776058 2.60372024,22.5650713 3.004803,22.4572669 C7.74521115,21.1831246 11.1278873,16.9273765 11.2587188,11.9724744 L11.2626513,11.6743596 L11.261813,9.42611011 L8.81957486,9.42611011 C8.64467336,9.42611011 8.47223693,9.38927885 8.31331817,9.31857786 L8.19683636,9.25924783 C7.64084739,8.93824745 7.4259853,8.25330312 7.67943508,7.67907571 L7.74096014,7.55789461 L10.9214893,2.04905657 C11.0308027,1.85972014 11.1880291,1.70249379 11.3773655,1.59318035 Z" id="路径" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
8
entry/src/main/ets/assets/picture/ic_merge_Enabled.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_merge_Enabled</title>
|
||||
<g id="ic_merge_Enabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M11.3773655,1.59318035 C11.9333544,1.27217997 12.6339647,1.42857611 13.0045353,1.93518376 L13.0787187,2.04905657 L16.2592478,7.55789461 C16.3685613,7.74723104 16.4261101,7.96200623 16.4261101,8.18063311 C16.4261101,8.82549994 15.9360152,9.35589898 15.3079759,9.41967985 L15.1806331,9.42611011 L12.765813,9.42611011 L12.7666285,11.6743596 C12.7666285,16.755889 16.1894212,21.1576237 21.024705,22.4572669 C21.4257877,22.5650713 21.6635368,22.9776058 21.5557325,23.3786885 C21.4479282,23.7797713 21.0353937,24.0175204 20.6343109,23.9097161 C16.5763509,22.8190044 13.3957223,19.8044379 12.0135386,15.9764756 C10.6336388,19.8044732 7.45311482,22.8190157 3.395197,23.9097161 C2.99411425,24.0175204 2.58157976,23.7797713 2.47377543,23.3786885 C2.3659711,22.9776058 2.60372024,22.5650713 3.004803,22.4572669 C7.74521115,21.1831246 11.1278873,16.9273765 11.2587188,11.9724744 L11.2626513,11.6743596 L11.261813,9.42611011 L8.81957486,9.42611011 C8.64467336,9.42611011 8.47223693,9.38927885 8.31331817,9.31857786 L8.19683636,9.25924783 C7.64084739,8.93824745 7.4259853,8.25330312 7.67943508,7.67907571 L7.74096014,7.55789461 L10.9214893,2.04905657 C11.0308027,1.85972014 11.1880291,1.70249379 11.3773655,1.59318035 Z" id="路径" fill="#006CDE"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
8
entry/src/main/ets/assets/picture/ic_merge_Grey.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_merge_Grey</title>
|
||||
<g id="ic_merge_Grey" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M11.3773655,1.59318035 C11.9333544,1.27217997 12.6339647,1.42857611 13.0045353,1.93518376 L13.0787187,2.04905657 L16.2592478,7.55789461 C16.3685613,7.74723104 16.4261101,7.96200623 16.4261101,8.18063311 C16.4261101,8.82549994 15.9360152,9.35589898 15.3079759,9.41967985 L15.1806331,9.42611011 L12.765813,9.42611011 L12.7666285,11.6743596 C12.7666285,16.755889 16.1894212,21.1576237 21.024705,22.4572669 C21.4257877,22.5650713 21.6635368,22.9776058 21.5557325,23.3786885 C21.4479282,23.7797713 21.0353937,24.0175204 20.6343109,23.9097161 C16.5763509,22.8190044 13.3957223,19.8044379 12.0135386,15.9764756 C10.6336388,19.8044732 7.45311482,22.8190157 3.395197,23.9097161 C2.99411425,24.0175204 2.58157976,23.7797713 2.47377543,23.3786885 C2.3659711,22.9776058 2.60372024,22.5650713 3.004803,22.4572669 C7.74521115,21.1831246 11.1278873,16.9273765 11.2587188,11.9724744 L11.2626513,11.6743596 L11.261813,9.42611011 L8.81957486,9.42611011 C8.64467336,9.42611011 8.47223693,9.38927885 8.31331817,9.31857786 L8.19683636,9.25924783 C7.64084739,8.93824745 7.4259853,8.25330312 7.67943508,7.67907571 L7.74096014,7.55789461 L10.9214893,2.04905657 C11.0308027,1.85972014 11.1880291,1.70249379 11.3773655,1.59318035 Z" id="路径" fill="#8c8c8c"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
8
entry/src/main/ets/assets/picture/ic_public_shuffle.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_public_shuffle</title>
|
||||
<g id="ic_public_shuffle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M20.75,14.5 C21.1642136,14.5 21.5,14.8357864 21.5,15.25 C21.5,15.6642136 21.1642136,16 20.75,16 L5.74910678,15.9991068 L5.75,17.2928932 C5.75,17.5690356 5.52614237,17.7928932 5.25,17.7928932 C5.11739176,17.7928932 4.9902148,17.7402148 4.89644661,17.6464466 L2.60355339,15.3535534 C2.40829124,15.1582912 2.40829124,14.8417088 2.60355339,14.6464466 C2.69732158,14.5526784 2.82449854,14.5 2.95710678,14.5 L20.75,14.5 Z M18.75,6.45710678 C18.8826082,6.45710678 19.0097852,6.5097852 19.1035534,6.60355339 L21.3964466,8.89644661 C21.5917088,9.09170876 21.5917088,9.40829124 21.3964466,9.60355339 C21.3026784,9.69732158 21.1755015,9.75 21.0428932,9.75 L3.25,9.75 C2.83578644,9.75 2.5,9.41421356 2.5,9 C2.5,8.58578644 2.83578644,8.25 3.25,8.25 L18.2491068,8.24910678 L18.25,6.95710678 C18.25,6.68096441 18.4738576,6.45710678 18.75,6.45710678 Z" id="合并形状" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_public_shuffle_Enabled</title>
|
||||
<g id="ic_public_shuffle_Enabled" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M20.75,14.5 C21.1642136,14.5 21.5,14.8357864 21.5,15.25 C21.5,15.6642136 21.1642136,16 20.75,16 L5.74910678,15.9991068 L5.75,17.2928932 C5.75,17.5690356 5.52614237,17.7928932 5.25,17.7928932 C5.11739176,17.7928932 4.9902148,17.7402148 4.89644661,17.6464466 L2.60355339,15.3535534 C2.40829124,15.1582912 2.40829124,14.8417088 2.60355339,14.6464466 C2.69732158,14.5526784 2.82449854,14.5 2.95710678,14.5 L20.75,14.5 Z M18.75,6.45710678 C18.8826082,6.45710678 19.0097852,6.5097852 19.1035534,6.60355339 L21.3964466,8.89644661 C21.5917088,9.09170876 21.5917088,9.40829124 21.3964466,9.60355339 C21.3026784,9.69732158 21.1755015,9.75 21.0428932,9.75 L3.25,9.75 C2.83578644,9.75 2.5,9.41421356 2.5,9 C2.5,8.58578644 2.83578644,8.25 3.25,8.25 L18.2491068,8.24910678 L18.25,6.95710678 C18.25,6.68096441 18.4738576,6.45710678 18.75,6.45710678 Z" id="合并形状" fill="#006CDE"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_public_shuffle_Grey</title>
|
||||
<g id="ic_public_shuffle_Grey" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
|
||||
<path d="M20.75,14.5 C21.1642136,14.5 21.5,14.8357864 21.5,15.25 C21.5,15.6642136 21.1642136,16 20.75,16 L5.74910678,15.9991068 L5.75,17.2928932 C5.75,17.5690356 5.52614237,17.7928932 5.25,17.7928932 C5.11739176,17.7928932 4.9902148,17.7402148 4.89644661,17.6464466 L2.60355339,15.3535534 C2.40829124,15.1582912 2.40829124,14.8417088 2.60355339,14.6464466 C2.69732158,14.5526784 2.82449854,14.5 2.95710678,14.5 L20.75,14.5 Z M18.75,6.45710678 C18.8826082,6.45710678 19.0097852,6.5097852 19.1035534,6.60355339 L21.3964466,8.89644661 C21.5917088,9.09170876 21.5917088,9.40829124 21.3964466,9.60355339 C21.3026784,9.69732158 21.1755015,9.75 21.0428932,9.75 L3.25,9.75 C2.83578644,9.75 2.5,9.41421356 2.5,9 C2.5,8.58578644 2.83578644,8.25 3.25,8.25 L18.2491068,8.24910678 L18.25,6.95710678 C18.25,6.68096441 18.4738576,6.45710678 18.75,6.45710678 Z" id="合并形状" fill="#8c8c8c"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
181
entry/src/main/ets/common/components/CallList.ets
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: User list component
|
||||
*/
|
||||
|
||||
import CallStateConst from '../constant/CallStateConst';
|
||||
import CallServiceProxy from '../../model/CallServiceProxy';
|
||||
import app from '@system.app';
|
||||
import LogUtils from '../utils/LogUtils';
|
||||
|
||||
const TAG = "CallList";
|
||||
|
||||
@Component
|
||||
export default struct CallList {
|
||||
@Link callList: Array<any>;
|
||||
@Link callData: any;
|
||||
@StorageLink("CallTimeList") callTimeList: any = [];
|
||||
|
||||
private mCallStateConst: CallStateConst;
|
||||
private mCallServiceProxy: CallServiceProxy;
|
||||
|
||||
public aboutToAppear(): void {
|
||||
LogUtils.i(TAG, "aboutToAppear");
|
||||
this.mCallStateConst = new CallStateConst();
|
||||
this.mCallServiceProxy = CallServiceProxy.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Three-way call list
|
||||
*
|
||||
* @return {boolean} - Three-way call list
|
||||
*/
|
||||
getCallList() {
|
||||
let arr = this.callList.map((item) => {
|
||||
const obj = {};
|
||||
return Object.assign({}, {
|
||||
...obj,
|
||||
...item
|
||||
});
|
||||
});
|
||||
return arr.filter((v) => v.callState !== CallStateConst.CALL_STATUS_WAITING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phone number display
|
||||
*
|
||||
* @return {string} Phone number
|
||||
*/
|
||||
public getContactName(item) {
|
||||
return (item.contactName ? item.contactName : item.accountNumber) || $r('app.string.unknownNumber');
|
||||
}
|
||||
|
||||
/**
|
||||
* Phone number display
|
||||
*
|
||||
* @return {string} Phone number
|
||||
*/
|
||||
public getCallTime(item) {
|
||||
let callTimeObj = this.callTimeList.find((o) => o.callId === item.callId);
|
||||
return callTimeObj ? callTimeObj.callTime : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call status
|
||||
*
|
||||
* @return {number} - callState
|
||||
*/
|
||||
private callState() {
|
||||
LogUtils.i(TAG, "callState : " + this.callData.callState)
|
||||
return this.callData.callState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hang up call
|
||||
*
|
||||
* @param {number} callId - callId
|
||||
*/
|
||||
public onHangUp(callId) {
|
||||
LogUtils.i(TAG, "onHangUp : " + callId);
|
||||
this.mCallServiceProxy.hangUpCall(callId);
|
||||
if (this.callList.length === 1) {
|
||||
globalThis.calluiAbilityContext?.terminateSelf().then((data) => {
|
||||
LogUtils.i(TAG, "onHangUp terminateSelfCallBack");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* UnHold call
|
||||
*
|
||||
* @param {number} callId - callId
|
||||
*/
|
||||
public onUnHold(callId) {
|
||||
LogUtils.i(TAG, "onUnHold : " + callId);
|
||||
|
||||
this.getCallList().forEach((item) => {
|
||||
if (item.callState === CallStateConst.CALL_STATUS_HOLDING) {
|
||||
this.mCallServiceProxy.unHoldCall(item.callId);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
|
||||
List() {
|
||||
ForEach(this.getCallList(), (item) => {
|
||||
ListItem() {
|
||||
Column() {
|
||||
Row() {
|
||||
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
|
||||
Text(this.getContactName(item))
|
||||
.fontColor('#FFFFFF')
|
||||
.fontSize(16)
|
||||
.height(21)
|
||||
.lineHeight(19)
|
||||
|
||||
Row() {
|
||||
if (item.callState === CallStateConst.callStateObj.CALL_STATUS_ACTIVE) {
|
||||
Text(this.getCallTime(item))
|
||||
.fontSize(14)
|
||||
.fontColor('#FFFFFF')
|
||||
.height(19)
|
||||
.lineHeight(19)
|
||||
.opacity(0.60)
|
||||
} else {
|
||||
Text(CallStateConst.callStateTextMap[item.callState])
|
||||
.fontSize(14)
|
||||
.fontColor('#FFFFFF')
|
||||
.height(19)
|
||||
.lineHeight(19)
|
||||
.opacity(0.60)
|
||||
}
|
||||
|
||||
if (this.callState() === CallStateConst.callStateObj.CALL_STATUS_WAITING
|
||||
|| this.callState() === CallStateConst.callStateObj.CALL_STATUS_INCOMING) {
|
||||
Image($r("app.media.ic_hangup_list"))
|
||||
.width(30)
|
||||
.height(30)
|
||||
.onClick(() => {
|
||||
this.onHangUp(item.callId);
|
||||
})
|
||||
.margin({ left: 16 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onClick(() => {
|
||||
this.onUnHold(item.callId);
|
||||
})
|
||||
.height(64)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
.divider({ strokeWidth: 1, color: $r('app.color.divider_calllist') })
|
||||
.margin({ left: 24, right: 24 })
|
||||
.width("100%")
|
||||
.listDirection(Axis.Vertical)
|
||||
Divider()
|
||||
.color($r('app.color.divider_calllist'))
|
||||
.strokeWidth(1)
|
||||
}
|
||||
.height(128)
|
||||
|
||||
}
|
||||
}
|
@ -104,7 +104,7 @@ export default struct ContactCard {
|
||||
}
|
||||
|
||||
if (this.isShowKeyboard && this.textInput.length === 0) {
|
||||
Text(this.callData.contactName ? this.callData.contactName : this.accountNumber)
|
||||
Text(this.callData.contactName ? this.callData.contactName : this.callData.accountNumber)
|
||||
.fontSize(30)
|
||||
.height(40)
|
||||
.lineHeight(40)
|
||||
@ -114,7 +114,7 @@ export default struct ContactCard {
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
} else if (!this.isShowKeyboard) {
|
||||
Text(this.isEmergencyPhoneNumber ? this.emergency : this.callData.contactName ? this.callData.contactName : this.accountNumber)
|
||||
Text(this.isEmergencyPhoneNumber ? this.emergency : this.callData.contactName ? this.callData.contactName : this.callData.accountNumber)
|
||||
.fontSize(30)
|
||||
.height(40)
|
||||
.lineHeight(40)
|
||||
@ -145,7 +145,7 @@ export default struct ContactCard {
|
||||
|
||||
Row() {
|
||||
if (!this.isShowKeyboard || this.isShowKeyboard && this.textInput.length === 0) {
|
||||
Text((this.callData.contactName || this.isEmergencyPhoneNumber) ? this.accountNumber : '')
|
||||
Text((this.callData.contactName || this.isEmergencyPhoneNumber) ? this.callData.accountNumber : '')
|
||||
.fontSize(14)
|
||||
.height(19)
|
||||
.lineHeight(16)
|
||||
|
@ -38,8 +38,8 @@ const textMap =
|
||||
|
||||
@Component
|
||||
export default struct FuncBtnGroup {
|
||||
@Link @Watch('updateBtnList') callData: any;
|
||||
@Link callList: Array<any>;
|
||||
@Link @Watch("updateBtnList") callData: any;
|
||||
@Link @Watch("updateBtnList") callList: Array<any>;
|
||||
@State count: number = 0;
|
||||
@State btnList: Array<any> = [];
|
||||
@State m: number = 0;
|
||||
@ -51,6 +51,7 @@ export default struct FuncBtnGroup {
|
||||
private mClone: Clone;
|
||||
private btnListCall;
|
||||
private btnListDialing;
|
||||
private btnListMulti;
|
||||
|
||||
aboutToAppear() {
|
||||
this.mClone = Clone.getInstance()
|
||||
@ -62,9 +63,10 @@ export default struct FuncBtnGroup {
|
||||
v.iconText = textMap[v.type];
|
||||
});
|
||||
this.btnListCall = this.mClone.clone(this.mBtnGroupConfig.btnGroupList);
|
||||
this.getBtnListCall()
|
||||
this.btnList = this.btnListCall
|
||||
this.updateBtnList()
|
||||
this.getBtnListCall();
|
||||
this.btnList = this.btnListCall;
|
||||
this.getBtnListMulti();
|
||||
this.updateBtnList();
|
||||
LogUtils.i(TAG, "aboutToAppear :");
|
||||
}
|
||||
|
||||
@ -73,11 +75,13 @@ export default struct FuncBtnGroup {
|
||||
*/
|
||||
updateBtnList() {
|
||||
if (this.callData.callState === CallStateConst.CALL_STATUS_DIALING || this.callData.callState === CallStateConst.CALL_STATUS_ALERTING) {
|
||||
this.btnList = this.btnListDialing
|
||||
this.btnList = this.btnListDialing;
|
||||
} else if (this.callList.length > 1){
|
||||
this.btnList = this.btnListMulti;
|
||||
} else {
|
||||
this.btnList = this.btnListCall
|
||||
this.btnList = this.btnListCall;
|
||||
}
|
||||
this.onCallStateChange(this.callData.callState)
|
||||
this.onCallStateChange(this.callData.callState);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,6 +93,15 @@ export default struct FuncBtnGroup {
|
||||
this.btnListDialing[2].isDisable = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BtnList for Multi Calls
|
||||
*/
|
||||
getBtnListMulti() {
|
||||
this.btnListMulti = this.mClone.clone(this.mBtnGroupConfig.btnGroupList);
|
||||
this.btnListMulti[1] = this.mClone.clone(this.mBtnGroupConfig.threePartyList[0]);
|
||||
this.btnListMulti[2] = this.mClone.clone(this.mBtnGroupConfig.threePartyList[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* update state of group buttons
|
||||
*
|
||||
@ -150,7 +163,13 @@ export default struct FuncBtnGroup {
|
||||
this.keepHandle('keep');
|
||||
break;
|
||||
case 'exchange':
|
||||
this.mCallServiceProxy.switchCall(callId);
|
||||
LogUtils.i(TAG, "exchange button clicked, callid: " + callId);
|
||||
this.callList.forEach((item) => {
|
||||
if (item.callState === CallStateConst.CALL_STATUS_HOLDING) {
|
||||
this.mCallServiceProxy.unHoldCall(item.callId);
|
||||
return;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'add':
|
||||
this.startContact('page_flag_dialer')
|
||||
|
137
entry/src/main/ets/common/components/MultiContactCard.ets
Normal file
@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: Header information display component
|
||||
*/
|
||||
import LogUtils from '../utils/LogUtils';
|
||||
import CallStateConst from '../constant/CallStateConst';
|
||||
import Utils from '../utils/utils'
|
||||
import CallList from './CallList'
|
||||
import callStateConst from '../constant/CallStateConst';
|
||||
import CallUtils from '../utils/CallUtils'
|
||||
|
||||
const TAG = "MultiContactCard";
|
||||
|
||||
@Component
|
||||
export default struct MultiContactCard {
|
||||
@State callStateText: string = '';
|
||||
@State dialing: string = '.';
|
||||
@Prop isShowKeyboard: boolean;
|
||||
@Link callList: Array<any>;
|
||||
@Link callData: any;
|
||||
@StorageLink("TextInput") textInput: string = '';
|
||||
@StorageLink("TextInputValue") textInputValue: string = '';
|
||||
@StorageLink("CallTimeList") callTimeList: any = [];
|
||||
@StorageLink("AccountNumber") accountNumber: string = '';
|
||||
@StorageLink("IsEmergencyPhoneNumber") isEmergencyPhoneNumber: boolean = false;
|
||||
@StorageLink("hasSimCard1") hasSimCard1: boolean = false;
|
||||
@StorageLink("hasSimCard2") hasSimCard2: boolean = false;
|
||||
private mUtils: Utils;
|
||||
private timer;
|
||||
private emergency = $r('app.string.emergency');
|
||||
|
||||
public aboutToAppear(): void {
|
||||
LogUtils.i(TAG, "aboutToAppear");
|
||||
this.mUtils = Utils.getInstance();
|
||||
this.timer = setInterval(() => {
|
||||
if (this.dialing === '...') {
|
||||
this.dialing = '';
|
||||
}
|
||||
this.dialing += '.';
|
||||
}, 500)
|
||||
if (this.callData.callState === 3) {
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
|
||||
if (this.callData.callState === 4 || this.callData.callState === 5) {
|
||||
CallUtils.hasSimeCard(0);
|
||||
CallUtils.hasSimeCard(1);
|
||||
}
|
||||
}
|
||||
|
||||
private isShowSim() {
|
||||
return (this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING
|
||||
|| this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING) && this.hasSimCard1 && this.hasSimCard2;
|
||||
}
|
||||
|
||||
build() {
|
||||
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: 24 }) {
|
||||
GridCol({ span: { sm: 4, md: 6, lg: 6 }, offset: { md: 1, lg: 3 } }) {
|
||||
Column() {
|
||||
if (!(this.isShowKeyboard && this.textInput.length != 0)) {
|
||||
CallList({
|
||||
callList: $callList,
|
||||
callData: $callData
|
||||
})
|
||||
|
||||
if (this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING
|
||||
|| this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING) {
|
||||
Column() {
|
||||
if (!this.isShowKeyboard || this.isShowKeyboard && this.textInput.length === 0) {
|
||||
Text(this.isEmergencyPhoneNumber ? this.emergency : this.callData.contactName ? this.callData.contactName : this.callData.accountNumber)
|
||||
.fontSize(30)
|
||||
.height(40)
|
||||
.lineHeight(40)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.fontColor('#FFFFFF')
|
||||
.margin({ bottom: 8 })
|
||||
|
||||
Text((this.callData.contactName || this.isEmergencyPhoneNumber) ? this.callData.accountNumber : '')
|
||||
.fontSize(14)
|
||||
.height(19)
|
||||
.lineHeight(19)
|
||||
.fontColor('#FFFFFF')
|
||||
.opacity(0.60)
|
||||
.visibility((this.callData.contactName || this.isEmergencyPhoneNumber) && !this.isShowKeyboard ? Visibility.Visible : Visibility.None)
|
||||
}
|
||||
}
|
||||
.margin({ top: 56 })
|
||||
|
||||
if (this.isShowSim()) {
|
||||
Image(this.callData.accountId == 1 ? $r("app.media.ic_public_phone_sim2") : $r("app.media.ic_public_phone_sim1"))
|
||||
.margin({ right: 4 })
|
||||
.width(12)
|
||||
.height(12)
|
||||
.opacity(0.6)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (this.isShowKeyboard && this.textInput.length != 0) {
|
||||
Scroll() {
|
||||
Text(this.textInputValue)
|
||||
.height(40)
|
||||
.fontSize(30)
|
||||
.lineHeight(40)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.margin({ bottom: 8 })
|
||||
.fontColor('#FFFFFF')
|
||||
.onTouch((event: TouchEvent) => {
|
||||
if (event.type === TouchType.Move) {
|
||||
this.textInputValue = this.textInput
|
||||
}
|
||||
})
|
||||
}
|
||||
.scrollable(ScrollDirection.Horizontal)
|
||||
.scrollBar(BarState.Off)
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.margin({ left: 24, right: 24 })
|
||||
}
|
||||
}
|
@ -1,153 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: User list component
|
||||
*/
|
||||
|
||||
import CallStateConst from '../constant/CallStateConst';
|
||||
import CallServiceProxy from '../../model/CallServiceProxy';
|
||||
import app from '@system.app';
|
||||
import LogUtils from '../utils/LogUtils';
|
||||
|
||||
const TAG = "CallList";
|
||||
const font_color = "rgba(255, 255, 255, 0.60)";
|
||||
|
||||
@Component
|
||||
export default struct callList {
|
||||
@State callList: any = [];
|
||||
@State callTimeList: any = [];
|
||||
@State callState: number = CallStateConst.CALL_STATUS_IDLE;
|
||||
@State callStateObj: any = {};
|
||||
@State callStateTextMap: object = {};
|
||||
private mCallStateConst: CallStateConst;
|
||||
private mCallServiceProxy: CallServiceProxy;
|
||||
|
||||
public aboutToAppear(): void {
|
||||
LogUtils.i(TAG, "aboutToAppear");
|
||||
this.mCallStateConst = new CallStateConst();
|
||||
this.mCallServiceProxy = CallServiceProxy.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Three-way call list
|
||||
*
|
||||
* @return {boolean} - Three-way call list
|
||||
*/
|
||||
list() {
|
||||
let arr = this.callList.map((item) => {
|
||||
const obj = {};
|
||||
const callTimeObj = this.callTimeList.find((o) => o.callId === item.callId);
|
||||
callTimeObj && Object.assign(obj, {
|
||||
...callTimeObj
|
||||
});
|
||||
return Object.assign({}, {
|
||||
...obj,
|
||||
...item
|
||||
});
|
||||
});
|
||||
return arr.filter((v) => v.callState !== CallStateConst.CALL_STATUS_WAITING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phone number display
|
||||
*
|
||||
* @return {string} Phone number
|
||||
*/
|
||||
public phoneNumber(item) {
|
||||
return item.accountNumber || $r('app.string.unknownNumber');
|
||||
}
|
||||
|
||||
/**
|
||||
* Internationalized text
|
||||
*
|
||||
* @return {string} key - getCallStateText Internationalized text
|
||||
*/
|
||||
public callStateText() {
|
||||
const key = this.mCallStateConst.getCallStateText(this.callState) || '';
|
||||
return key && $r(`app.string.${key}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* hang up
|
||||
*
|
||||
* @param {number} callId - callId
|
||||
*/
|
||||
public onHangUp(callId) {
|
||||
this.mCallServiceProxy.hangUpCall(callId);
|
||||
if (this.callList.length === 1) {
|
||||
globalThis.calluiAbilityContext?.terminateSelf().then((data) => {
|
||||
LogUtils.i(TAG, "onHangUp terminateSelfCallBack");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
|
||||
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
|
||||
List() {
|
||||
ForEach(this.list(), (item) => {
|
||||
ListItem() {
|
||||
Row() {
|
||||
Text(this.phoneNumber(item))
|
||||
.fontColor('#fff')
|
||||
.fontSize(30)
|
||||
|
||||
Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
|
||||
if (item.callState === CallStateConst.callStateObj.CALL_STATUS_ACTIVE) {
|
||||
Text(item.callTime)
|
||||
.margin({ left: 18 })
|
||||
.fontColor('#fff')
|
||||
.fontSize(30)
|
||||
.opacity(0.60)
|
||||
|
||||
if (this.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING) {
|
||||
Column() {
|
||||
}
|
||||
.margin({ left: 30, bottom: 10 })
|
||||
.width(50)
|
||||
.height(40)
|
||||
.backgroundImage("/assets/picture/userCall.png", ImageRepeat.NoRepeat)
|
||||
.backgroundImageSize(50)
|
||||
.onClick(() => {
|
||||
this.onHangUp(this);
|
||||
})
|
||||
} else {
|
||||
Column() {
|
||||
Text(CallStateConst.callStateTextMap[item.callState])
|
||||
.fontSize(28)
|
||||
.fontColor(font_color)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.margin({ left: 48, right: 48 })
|
||||
.height(128)
|
||||
|
||||
Divider()
|
||||
.color(Color.Gray)
|
||||
}
|
||||
}
|
||||
.backgroundColor(Color.Green)
|
||||
.width('100%')
|
||||
.height(256)
|
||||
.padding({ top: -100 })
|
||||
}
|
||||
}
|
@ -79,18 +79,18 @@ const firstBtns = [
|
||||
const secondBtns = [
|
||||
{
|
||||
type: 'exchange',
|
||||
iconDisableUrl: 'exchangeGrey',
|
||||
iconDefaultUrl: 'exchangeIcon',
|
||||
iconActiveUrl: 'exchangeIcon',
|
||||
iconDisableUrl: 'ic_public_shuffle_Grey',
|
||||
iconDefaultUrl: 'ic_public_shuffle',
|
||||
iconActiveUrl: 'ic_public_shuffle_Enabled',
|
||||
isDisable: false,
|
||||
isActive: false,
|
||||
iconText: ''
|
||||
},
|
||||
{
|
||||
type: 'merge',
|
||||
iconDisableUrl: 'addCallGrey',
|
||||
iconDefaultUrl: 'addCall',
|
||||
iconActiveUrl: 'addCall',
|
||||
iconDisableUrl: 'ic_merge_Grey',
|
||||
iconDefaultUrl: 'ic_merge',
|
||||
iconActiveUrl: 'ic_merge_Enabled',
|
||||
isDisable: false,
|
||||
isActive: false,
|
||||
iconText: ''
|
||||
|
@ -57,16 +57,17 @@ export default class CallStateConst {
|
||||
CALL_STATUS_DISCONNECTING: CallStateConst.CALL_STATUS_DISCONNECTING,
|
||||
CALL_STATUS_IDLE: CallStateConst.CALL_STATUS_IDLE
|
||||
};
|
||||
|
||||
public static callStateTextMap = {
|
||||
[CallStateConst.CALL_STATUS_ACTIVE]: '',
|
||||
[CallStateConst.CALL_STATUS_HOLDING]: 'callHold',
|
||||
[CallStateConst.CALL_STATUS_DIALING]: 'dialing',
|
||||
[CallStateConst.CALL_STATUS_ALERTING]: 'partyIsRinging',
|
||||
[CallStateConst.CALL_STATUS_HOLDING]: $r('app.string.callHold'),
|
||||
[CallStateConst.CALL_STATUS_DIALING]: $r("app.string.dialing"),
|
||||
[CallStateConst.CALL_STATUS_ALERTING]: $r("app.string.partyIsRinging"),
|
||||
[CallStateConst.CALL_STATUS_INCOMING]: '',
|
||||
[CallStateConst.CALL_STATUS_WAITING]: 'thirdPartyCalls',
|
||||
[CallStateConst.CALL_STATUS_DISCONNECTED]: 'hangUpCompleted',
|
||||
[CallStateConst.CALL_STATUS_DISCONNECTING]: 'hangingUp',
|
||||
[CallStateConst.CALL_STATUS_IDLE]: 'callIdle'
|
||||
[CallStateConst.CALL_STATUS_WAITING]: '',
|
||||
[CallStateConst.CALL_STATUS_DISCONNECTED]: $r("app.string.hangUpCompleted"),
|
||||
[CallStateConst.CALL_STATUS_DISCONNECTING]: $r("app.string.hangingUp"),
|
||||
[CallStateConst.CALL_STATUS_IDLE]: ''
|
||||
};
|
||||
|
||||
public static defaultCallData = {
|
||||
|
@ -128,6 +128,22 @@ export default class CallDataManager {
|
||||
return callData !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge whether the call exists.
|
||||
*/
|
||||
public hasActiveCall(): boolean {
|
||||
return this.callList.find((call) => call.callState === CallStateConst.CALL_STATUS_ACTIVE
|
||||
|| call.callState === CallStateConst.CALL_STATUS_HOLDING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge whether the call is active or holding.
|
||||
*/
|
||||
public isActiveCall(callId): boolean {
|
||||
return this.callList.find((call) => call.callId === callId && (call.callState === CallStateConst.CALL_STATUS_ACTIVE
|
||||
|| call.callState === CallStateConst.CALL_STATUS_HOLDING));
|
||||
}
|
||||
|
||||
/**
|
||||
* addCallList
|
||||
*
|
||||
|
@ -154,19 +154,23 @@ export default class CallManager {
|
||||
* update call time list
|
||||
*/
|
||||
updateCallTimeList() {
|
||||
if (this.callData.callState != CallStateConst.CALL_STATUS_ACTIVE && this.callData.callState != CallStateConst.CALL_STATUS_HOLDING) {
|
||||
if (!this.mCallDataManager.hasActiveCall()) {
|
||||
LogUtils.i(TAG, "no active calls to update");
|
||||
return;
|
||||
}
|
||||
|
||||
this.callTimeList = AppStorage.Get("CallTimeList")
|
||||
this.callTimeList.forEach((item, i) => {
|
||||
item.endTimestamp = new Date().valueOf();
|
||||
const diffSeconds = item.endTimestamp - item.startTimestamp;
|
||||
this.diffSeconds = diffSeconds
|
||||
item.callTime = this.mUtils.formatTime(diffSeconds);
|
||||
this.callTimeList.splice(i, 1, {
|
||||
...item,
|
||||
});
|
||||
AppStorage.SetOrCreate("CallTimeList", this.callTimeList)
|
||||
if (this.mCallDataManager.isActiveCall(item.callId)) {
|
||||
item.endTimestamp = new Date().valueOf();
|
||||
const diffSeconds = item.endTimestamp - item.startTimestamp;
|
||||
this.diffSeconds = diffSeconds
|
||||
item.callTime = this.mUtils.formatTime(diffSeconds);
|
||||
this.callTimeList.splice(i, 1, {
|
||||
...item,
|
||||
});
|
||||
AppStorage.SetOrCreate("CallTimeList", this.callTimeList);
|
||||
}
|
||||
});
|
||||
this.mTimeMeter = setTimeout(() => {
|
||||
this.updateCallTimeList();
|
||||
|
@ -28,6 +28,7 @@ import CallManager from '../model/CallManager';
|
||||
import backgroundTaskManager from '@ohos.backgroundTaskManager';
|
||||
import Constants from '../common/utils/Constants';
|
||||
import CallDataManager from '../model/CallDataManager';
|
||||
import MultiContactCard from '../common/components/MultiContactCard';
|
||||
|
||||
const TAG = "Index";
|
||||
|
||||
@ -169,19 +170,41 @@ struct Index {
|
||||
return this.callData.callState;
|
||||
}
|
||||
|
||||
/**
|
||||
* is Triple Call
|
||||
*
|
||||
* @return {boolean} - isTripleCall
|
||||
*/
|
||||
private isTripleCall() {
|
||||
return (this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_WAITING
|
||||
|| this.callData.callState === CallStateConst.callStateObj.CALL_STATUS_INCOMING)
|
||||
&& this.callList.length === 3;
|
||||
}
|
||||
|
||||
build() {
|
||||
Flex({
|
||||
direction: FlexDirection.Column,
|
||||
alignItems: ItemAlign.Center,
|
||||
justifyContent: FlexAlign.SpaceBetween
|
||||
}) {
|
||||
ContactCard({
|
||||
callData: $callData,
|
||||
isShowKeyboard: this.isShowKeyboard,
|
||||
callList: $callList
|
||||
})
|
||||
.margin({ top: this.isShowKeyboard ? 0 : 56 })
|
||||
.layoutWeight(this.isShowKeyboard ? 1 : 0)
|
||||
if (this.callList.length > 1) {
|
||||
MultiContactCard({
|
||||
callData: $callData,
|
||||
isShowKeyboard: this.isShowKeyboard,
|
||||
callList: $callList
|
||||
})
|
||||
.margin({ top: this.isShowKeyboard ? 0 : 56 })
|
||||
.layoutWeight(this.isShowKeyboard ? 1 : 0)
|
||||
} else {
|
||||
ContactCard({
|
||||
callData: $callData,
|
||||
isShowKeyboard: this.isShowKeyboard,
|
||||
callList: $callList
|
||||
})
|
||||
.margin({ top: this.isShowKeyboard ? 0 : 56 })
|
||||
.layoutWeight(this.isShowKeyboard ? 1 : 0)
|
||||
}
|
||||
|
||||
if (this.callState() !== CallStateConst.callStateObj.CALL_STATUS_WAITING
|
||||
&& this.callState() !== CallStateConst.callStateObj.CALL_STATUS_INCOMING) {
|
||||
Column() {
|
||||
@ -200,10 +223,23 @@ struct Index {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
IncomingCom({ callData: $callData })
|
||||
Column() {
|
||||
IncomingCom({ callData: $callData })
|
||||
|
||||
if (this.isTripleCall()) {
|
||||
Column() {
|
||||
Text($r("app.string.end_holding_call"))
|
||||
.fontColor('#FFFFFF')
|
||||
.fontSize(14)
|
||||
.height(19)
|
||||
.lineHeight(19)
|
||||
}
|
||||
.margin({ top: 16 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding({ bottom: 106 })
|
||||
.padding({ bottom: this.isTripleCall() ? 71 : 106 })
|
||||
.width("100%")
|
||||
.height("100%")
|
||||
.backgroundImage('assets/picture/wallpaper.png', ImageRepeat.NoRepeat)
|
||||
|
@ -11,6 +11,10 @@
|
||||
{
|
||||
"name": "divider_gray",
|
||||
"value": "#1A000000"
|
||||
},
|
||||
{
|
||||
"name": "divider_calllist",
|
||||
"value": "#14FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
@ -203,6 +203,10 @@
|
||||
{
|
||||
"name": "emergency",
|
||||
"value": "Emergency"
|
||||
},
|
||||
{
|
||||
"name": "end_holding_call",
|
||||
"value": "Answering this call will end the one currently on hold"
|
||||
}
|
||||
]
|
||||
}
|
18
entry/src/main/resources/base/media/ic_hangup_list.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="30px" height="30px" viewBox="0 0 30 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>ic_hangup_list</title>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="0" width="30" height="30"></rect>
|
||||
<path d="M27.4299071,11.0275823 C28.8221439,11.8994724 29.6635772,13.4295392 29.6568661,15.0757549 C29.7133057,16.0500283 29.5758198,16.7813356 29.2444084,17.2696768 C28.7472914,18.0021887 27.8751429,18.3890934 26.9980904,18.2941097 L23.6898357,17.9475723 L23.6898357,17.9475723 L23.6266778,17.9425666 C22.5543955,17.8787494 21.714079,17.0120506 21.675955,15.946424 L21.6746039,15.8717628 L21.7254516,14.1261753 C21.7264841,13.4132797 21.2365944,12.7958844 20.5425408,12.6355992 C19.1923485,12.3205457 17.0998986,12.1677545 15.0000575,12.1860668 C12.9001014,12.1677545 10.8076515,12.3205457 9.45745922,12.6355992 C8.76340562,12.7958844 8.27351588,13.4132797 8.27454844,14.1261753 L8.32539611,15.8717628 L8.32404502,15.946424 C8.28695142,16.9832499 7.49044101,17.8317555 6.45974445,17.9356447 L5.89793067,17.9879298 L5.89793067,17.9879298 L3.00190965,18.2941097 L3.00190965,18.2941097 C2.12485713,18.3890934 1.25270859,18.0021887 0.75559158,17.2696768 C0.424180238,16.7813356 0.286694339,16.0500283 0.343133884,15.0757549 C0.336422775,13.4295392 1.17785607,11.8994724 2.57009292,11.0275823 C5.54093449,9.1768754 10.2811351,8.2155067 14.9999425,8.19149999 C19.7188649,8.2155067 24.4590655,9.1768754 27.4299071,11.0275823 Z" id="path-3"></path>
|
||||
</defs>
|
||||
<g id="ic_hangup_list" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="none">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="矩形"></g>
|
||||
<mask id="mask-4" fill="none">
|
||||
<use xlink:href="#path-3"></use>
|
||||
</mask>
|
||||
<use id="路径" fill="#E84026" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -203,6 +203,10 @@
|
||||
{
|
||||
"name": "emergency",
|
||||
"value": "紧急通话"
|
||||
},
|
||||
{
|
||||
"name": "end_holding_call",
|
||||
"value": "接听来电将挂断之前保持的通话"
|
||||
}
|
||||
]
|
||||
}
|