diff --git a/entry/src/main/ets/ServiceAbility/CallManagerService.ts b/entry/src/main/ets/ServiceAbility/CallManagerService.ts
index f64cc3e..0c717bb 100644
--- a/entry/src/main/ets/ServiceAbility/CallManagerService.ts
+++ b/entry/src/main/ets/ServiceAbility/CallManagerService.ts
@@ -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);
diff --git a/entry/src/main/ets/assets/picture/ic_merge.svg b/entry/src/main/ets/assets/picture/ic_merge.svg
new file mode 100644
index 0000000..02e5214
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_merge.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/assets/picture/ic_merge_Enabled.svg b/entry/src/main/ets/assets/picture/ic_merge_Enabled.svg
new file mode 100644
index 0000000..cd5e060
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_merge_Enabled.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/assets/picture/ic_merge_Grey.svg b/entry/src/main/ets/assets/picture/ic_merge_Grey.svg
new file mode 100644
index 0000000..0f937d7
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_merge_Grey.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/assets/picture/ic_public_shuffle.svg b/entry/src/main/ets/assets/picture/ic_public_shuffle.svg
new file mode 100644
index 0000000..59ccce2
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_public_shuffle.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/assets/picture/ic_public_shuffle_Enabled.svg b/entry/src/main/ets/assets/picture/ic_public_shuffle_Enabled.svg
new file mode 100644
index 0000000..e7d7448
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_public_shuffle_Enabled.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/assets/picture/ic_public_shuffle_Grey.svg b/entry/src/main/ets/assets/picture/ic_public_shuffle_Grey.svg
new file mode 100644
index 0000000..3902c77
--- /dev/null
+++ b/entry/src/main/ets/assets/picture/ic_public_shuffle_Grey.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/ets/common/components/ContactCard.ets b/entry/src/main/ets/common/components/ContactCard.ets
index ca4ae8b..05a37e0 100644
--- a/entry/src/main/ets/common/components/ContactCard.ets
+++ b/entry/src/main/ets/common/components/ContactCard.ets
@@ -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)
diff --git a/entry/src/main/ets/common/components/FuncBtnGroup.ets b/entry/src/main/ets/common/components/FuncBtnGroup.ets
index a2374b1..89980d3 100644
--- a/entry/src/main/ets/common/components/FuncBtnGroup.ets
+++ b/entry/src/main/ets/common/components/FuncBtnGroup.ets
@@ -38,8 +38,8 @@ const textMap =
@Component
export default struct FuncBtnGroup {
- @Link @Watch('updateBtnList') callData: any;
- @Link callList: Array;
+ @Link @Watch("updateBtnList") callData: any;
+ @Link @Watch("updateBtnList") callList: Array;
@State count: number = 0;
@State btnList: Array = [];
@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')
diff --git a/entry/src/main/ets/common/components/MultiContactCard.ets b/entry/src/main/ets/common/components/MultiContactCard.ets
new file mode 100644
index 0000000..a5a052f
--- /dev/null
+++ b/entry/src/main/ets/common/components/MultiContactCard.ets
@@ -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;
+ @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 })
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/ets/common/components/callList.ets b/entry/src/main/ets/common/components/callList.ets
deleted file mode 100644
index 63deddc..0000000
--- a/entry/src/main/ets/common/components/callList.ets
+++ /dev/null
@@ -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 })
- }
-}
\ No newline at end of file
diff --git a/entry/src/main/ets/common/components/callListlistlist.ets b/entry/src/main/ets/common/components/callListlistlist.ets
new file mode 100644
index 0000000..98e59ff
--- /dev/null
+++ b/entry/src/main/ets/common/components/callListlistlist.ets
@@ -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;
+ @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)
+
+ }
+}
\ No newline at end of file
diff --git a/entry/src/main/ets/common/configs/BtnGroupConfig.ets b/entry/src/main/ets/common/configs/BtnGroupConfig.ets
index cbb9a0a..f633230 100644
--- a/entry/src/main/ets/common/configs/BtnGroupConfig.ets
+++ b/entry/src/main/ets/common/configs/BtnGroupConfig.ets
@@ -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: ''
diff --git a/entry/src/main/ets/common/constant/CallStateConst.ets b/entry/src/main/ets/common/constant/CallStateConst.ets
index 181f52f..edb5dac 100644
--- a/entry/src/main/ets/common/constant/CallStateConst.ets
+++ b/entry/src/main/ets/common/constant/CallStateConst.ets
@@ -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 = {
diff --git a/entry/src/main/ets/model/CallDataManager.ets b/entry/src/main/ets/model/CallDataManager.ets
index e8587e6..d4d02c1 100644
--- a/entry/src/main/ets/model/CallDataManager.ets
+++ b/entry/src/main/ets/model/CallDataManager.ets
@@ -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
*
diff --git a/entry/src/main/ets/model/CallManager.ets b/entry/src/main/ets/model/CallManager.ets
index 3a00186..1ff402a 100644
--- a/entry/src/main/ets/model/CallManager.ets
+++ b/entry/src/main/ets/model/CallManager.ets
@@ -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();
diff --git a/entry/src/main/ets/pages/index.ets b/entry/src/main/ets/pages/index.ets
index 4de678a..aee8ba2 100644
--- a/entry/src/main/ets/pages/index.ets
+++ b/entry/src/main/ets/pages/index.ets
@@ -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)
diff --git a/entry/src/main/resources/base/element/color.json b/entry/src/main/resources/base/element/color.json
index e0477ac..0eb74c4 100644
--- a/entry/src/main/resources/base/element/color.json
+++ b/entry/src/main/resources/base/element/color.json
@@ -11,6 +11,10 @@
{
"name": "divider_gray",
"value": "#1A000000"
+ },
+ {
+ "name": "divider_calllist",
+ "value": "#14FFFFFF"
}
]
}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json
index 7a2716e..30bc7be 100644
--- a/entry/src/main/resources/base/element/string.json
+++ b/entry/src/main/resources/base/element/string.json
@@ -203,6 +203,10 @@
{
"name": "emergency",
"value": "Emergency"
+ },
+ {
+ "name": "end_holding_call",
+ "value": "Answering this call will end the one currently on hold"
}
]
}
\ No newline at end of file
diff --git a/entry/src/main/resources/base/media/ic_hangup_list.svg b/entry/src/main/resources/base/media/ic_hangup_list.svg
new file mode 100644
index 0000000..5df95cf
--- /dev/null
+++ b/entry/src/main/resources/base/media/ic_hangup_list.svg
@@ -0,0 +1,18 @@
+
+
\ No newline at end of file
diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json
index 5439868..b6fbdb1 100644
--- a/entry/src/main/resources/zh_CN/element/string.json
+++ b/entry/src/main/resources/zh_CN/element/string.json
@@ -203,6 +203,10 @@
{
"name": "emergency",
"value": "紧急通话"
+ },
+ {
+ "name": "end_holding_call",
+ "value": "接听来电将挂断之前保持的通话"
}
]
}
\ No newline at end of file