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 Method from '../utils/Method'; 17import FuncBtn from './FuncBtn'; 18import CallStateConst from '../constant/CallStateConst'; 19import CallServiceProxy from '../../model/CallServiceProxy'; 20import Clone from '../utils/Clone'; 21import BtnGroupConfig from '../configs/BtnGroupConfig'; 22import LogUtils from '../utils/LogUtils'; 23import screenLock from '@ohos.screenLock'; 24import DefaultCallData from '../struct/TypeUtils' 25import CallListStruct from '../struct/CallListStruct' 26import FunctonBtnVM from '../../viewmodel/FunctonBtnVIewModel'; 27 28const TAG = 'FuncBtnGroup'; 29 30class BtnStruct { 31 type 32 iconDisableUrl 33 iconDefaultUrl 34 iconActiveUrl 35 isDisable 36 isActive 37 iconText 38} 39const textMap = 40 { 41 'record': $r('app.string.recording'), 42 'keep': $r('app.string.keep'), 43 'add': $r('app.string.addCall'), 44 'video': $r('app.string.videoCall'), 45 'mute': $r('app.string.mute'), 46 'contact': $r('app.string.contactPerson'), 47 'exchange': $r('app.string.exchange'), 48 'merge': $r('app.string.mergeCall'), 49 }; 50 51@Component 52export default struct FuncBtnGroup { 53 @Link @Watch("updateBtnList") callData: DefaultCallData; 54 @Link @Watch("updateBtnList") callList: Array<CallListStruct>; 55 @State count: number = 0; 56 @State btnList: Array<BtnStruct> = []; 57 @State m: number = 0; 58 @State n: number = 0; 59 @State oldCallState: number = CallStateConst.CALL_STATUS_IDLE; 60 @State mFunctonBtnVM: FunctonBtnVM = FunctonBtnVM.getInstance(); 61 private mCallServiceProxy: CallServiceProxy; 62 private mBtnGroupConfig = BtnGroupConfig; 63 private timer: number = null; 64 private mClone: Clone; 65 private btnListCall; 66 private btnListDialing; 67 private btnListMulti; 68 69 aboutToAppear() { 70 this.mClone = Clone.getInstance() 71 this.mCallServiceProxy = CallServiceProxy.getInstance(); 72 this.mBtnGroupConfig.btnGroupList.forEach((v) => { 73 v.iconText = textMap[v.type]; 74 }); 75 this.mBtnGroupConfig.threePartyList.forEach((v) => { 76 v.iconText = textMap[v.type]; 77 }); 78 this.btnListCall = this.mClone.clone(this.mBtnGroupConfig.btnGroupList); 79 this.getBtnListCall(); 80 this.btnList = this.btnListCall; 81 this.getBtnListMulti(); 82 this.updateBtnList(); 83 LogUtils.i(TAG, "aboutToAppear :"); 84 } 85 86 /** 87 * Switching BtnList Based on CallStatus 88 */ 89 updateBtnList() { 90 if (this.callData.callState === CallStateConst.CALL_STATUS_DIALING || this.callData.callState === CallStateConst.CALL_STATUS_ALERTING) { 91 this.btnList = this.btnListDialing; 92 } else if (this.callList.length > 1){ 93 this.btnList = this.btnListMulti; 94 } else { 95 this.btnList = this.btnListCall; 96 } 97 this.onCallStateChange(this.callData.callState); 98 } 99 100 /** 101 * Get BtnList Based on CallStatus 102 */ 103 getBtnListCall() { 104 this.btnListDialing = this.mClone.clone(this.mBtnGroupConfig.btnGroupList); 105 this.btnListDialing[1].isDisable = true 106 this.btnListDialing[2].isDisable = true 107 } 108 109 /** 110 * Get BtnList for Multi Calls 111 */ 112 getBtnListMulti() { 113 this.btnListMulti = this.mClone.clone(this.mBtnGroupConfig.btnGroupList); 114 this.btnListMulti[1] = this.mClone.clone(this.mBtnGroupConfig.threePartyList[0]); 115 this.btnListMulti[2] = this.mClone.clone(this.mBtnGroupConfig.threePartyList[1]); 116 } 117 118 /** 119 * update state of group buttons 120 * 121 * @param {Object} callData - call data 122 */ 123 onCallStateChange(newVal) { 124 const BtnName = ['video', 'record', 'add', 'contact', 'merge'] 125 if (newVal === CallStateConst.CALL_STATUS_ACTIVE || newVal === CallStateConst.CALL_STATUS_HOLDING) { 126 this.btnList.forEach((item) => { 127 if (!Method.includes(BtnName, (item.type))) { 128 item.isDisable = false; 129 item.isActive = false; 130 } 131 }); 132 if (newVal === CallStateConst.CALL_STATUS_HOLDING) { 133 this.btnList[1].isActive = true; 134 this.btnList[4].isDisable = true; 135 } 136 } else { 137 this.btnList.forEach((item) => { 138 if (item.type === 'contact') { 139 item.isDisable = false; 140 } 141 }); 142 } 143 } 144 145 /** 146 * Display the buttons of the button group 147 * 148 * @param {Object} obj - object 149 */ 150 btnClick(obj) { 151 LogUtils.i(TAG, "btnClick get icon type : " + JSON.stringify(obj)); 152 const BtnName = ['record', 'video', 'mute'] 153 const type = obj.type; 154 const { callId } = this.callData; 155 if (Method.includes(BtnName, type)) { 156 this.btnList.forEach((item) => { 157 if (item.type === type) { 158 item.isActive = !item.isActive; 159 } 160 }); 161 if (type === 'record') { 162 if (this.btnList[0].isActive) { 163 } else { 164 this.count = 0; 165 clearInterval(this.timer); 166 this.btnList[0].iconText = $r('app.string.recording'); 167 } 168 } 169 } 170 171 switch (type) { 172 case 'record': 173 break; 174 case 'keep': 175 this.keepHandle('keep'); 176 break; 177 case 'exchange': 178 LogUtils.i(TAG, "exchange button clicked, callid: " + callId); 179 this.callList.forEach((item) => { 180 if (item.callState === CallStateConst.CALL_STATUS_HOLDING) { 181 this.mCallServiceProxy.unHoldCall(item.callId); 182 return; 183 } 184 }); 185 break; 186 case 'add': 187 this.startContact('page_flag_dialer') 188 break; 189 case 'video': 190 break; 191 case 'mute': 192 this.muteHandle('mute'); 193 break; 194 case 'contact': 195 this.startContact("page_flag_choose_contacts") 196 break; 197 case 'merge': 198 this.mCallServiceProxy.combineConference(callId); 199 break; 200 default: 201 break; 202 } 203 } 204 205 startContact(pageFlag) { 206 if (screenLock.isLocked()) { 207 screenLock.unlock((err, isUnlock) => { 208 if (isUnlock) { 209 this.startContactAbility(pageFlag) 210 } else { 211 LogUtils.i(TAG, "startContact screen isLocked") 212 } 213 }); 214 } else { 215 this.startContactAbility(pageFlag) 216 } 217 } 218 219 startContactAbility(pageFlag) { 220 globalThis.calluiAbilityContext?.startAbility({ 221 bundleName: 'com.ohos.contacts', 222 abilityName: 'com.ohos.contacts.MainAbility', 223 parameters: { 224 pageFlag: pageFlag 225 } 226 }); 227 } 228 229 /** 230 * Call hold interface 231 * 232 * @param {string} type - Click the hold button 233 */ 234 keepHandle(type) { 235 const awaitIsActive = this.btnList.find((v) => v.type === type).isActive; 236 LogUtils.i(TAG, "keep handle awaitIsActive : " + !awaitIsActive); 237 !awaitIsActive ? this.mCallServiceProxy.holdCall(this.callData.callId) : this.mCallServiceProxy.unHoldCall(this.callData.callId); 238 } 239 240 /** 241 * Call hold mute 242 * 243 * @param {string} type - Click the hold button 244 */ 245 muteHandle(type) { 246 const awaitIsActive = this.btnList.find((v) => v.type === type).isActive; 247 LogUtils.i(TAG, "mute Handle awaitIsActive : " + awaitIsActive); 248 awaitIsActive ? this.mCallServiceProxy.setMuted() : this.mCallServiceProxy.cancelMuted(); 249 } 250 251 /** 252 * Clear timer 253 */ 254 onDestroy() { 255 LogUtils.i(TAG, "onDestroy"); 256 this.timer && clearInterval(this.timer); 257 } 258 259 build() { 260 GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: 0 }) { 261 GridCol({ span: { sm: 4, md: 6, lg: 6 }, offset: { md: 1, lg: 3 } }) { 262 Grid() { 263 ForEach(this.btnList, (item) => { 264 GridItem() { 265 FuncBtn({ 266 btnType: item.type, 267 isDisable: item.isDisable, 268 isActive: item.isActive, 269 iconText: item.iconText, 270 iconDisableUrl: item.iconDisableUrl, 271 iconDefaultUrl: item.iconDefaultUrl, 272 iconActiveUrl: item.iconActiveUrl, 273 btnClick: () => { 274 this.btnClick(item) 275 } 276 }) 277 } 278 .height(51.5) 279 }) 280 } 281 .columnsGap(24) 282 .rowsGap(29.5) 283 .height(132.5) 284 .columnsTemplate('1fr 1fr 1fr') 285 .rowsTemplate('1fr 1fr') 286 } 287 } 288 .margin(24) 289 } 290}