Add CallUI

Signed-off-by: ohos-lsw <lishiwei6@huawei.com>
This commit is contained in:
ohos-lsw 2021-10-26 15:38:27 +08:00
parent 6ad0019f3a
commit 6cd70b84d0
119 changed files with 4687 additions and 58 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
*.tgz filter=lfs diff=lfs merge=lfs -text
*.trp filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.asm filter=lfs diff=lfs merge=lfs -text
*.8svn filter=lfs diff=lfs merge=lfs -text
*.9svn filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
*.iml
.gradle
/local.properties
.DS_Store
/build
/captures
.externalNativeBuild
/entry/.preview
.cxx
/node_modules
/.idea

217
LICENSE Normal file
View File

@ -0,0 +1,217 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
***************************************************************
OAT uses Apache Creadur Rat framework api to read files and extends lot of capabilities to support OpenHarmony,
but there are several files is derived from Apache Creadur Rat because the original class/method in Apache Creadur
Rat is defined as final or private so that OAT cannot extend it and add capabilities, such as concurrent processing.
Apache Creadur Rat URL:
https://github.com/apache/creadur-rat/tree/apache-rat-project-0.13
***************************************************************
Apache Creadur Rat
Copyright 2006-2019 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).

91
OAT.xml Normal file
View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2021 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.
This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
All configurations in this file will be merged to OAT-Default.xml, if you have any questions or concerns, please create issue in OpenHarmony/tools_oat and @jalenchen or chenyaxun.
licensefile:
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
policylist:
1. policy: If the OAT-Default.xml policies do not meet your requirements, please add policies here.
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
3. policyitem type:
"compatibility" is used to check license compatibility in the specified path;
"license" is used to check source license header in the specified path;
"copyright" is used to check source copyright header in the specified path;
"import" is used to check source dependency in the specified path, such as import ... ,include ...
"filetype" is used to check file type in the specified path, supported file types: archive, binary
"filename" is used to check whether the specified file exists in the specified path(projectroot means the root dir of the project), supported file names: LICENSE, README, README.OpenSource
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
7. policyitem filefilter: Used to bind filefilter which define filter rules.
7. policyitem desc: Used to describe the reason of this policy item, committers will check this while merging the code.
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
Note:If the text contains special characters, please escape them according to the following rules:
" == &gt;
& == &gt;
' == &gt;
< == &gt;
> == &gt;
-->
<configuration>
<oatconfig>
<policylist>
<policy
desc=""
name="projectPolicy">
<policyitem
desc="file generated by development tool"
filefilter="copyrightPolicyFilter"
group="defaultGroup"
name="Copyright 2015 the original author or authors."
path="gradlew"
rule="may"
type="copyright"/>
<policyitem
desc="file generated by development tool"
filefilter="copyrightPolicyFilter"
group="defaultGroup"
name="Copyright 2015 the original author or authors."
path="gradlew.bat"
rule="may"
type="copyright"/>
</policy>
</policylist>
<filefilterlist>
<filefilter
desc="Filters for binary file policies"
name="binaryFileTypePolicyFilter">
<filteritem
desc="self developed image"
name="singleton/entry/src/main/js/default/assets/picture/.*.png"
type="filepath"/>
<filteritem
desc="self developed image"
name="callui/src/main/js/default/assets/picture/.*.png"
type="filepath"/>
<filteritem
desc="self developed image"
name="figures/.*.png"
type="filepath"/>
</filefilter>
</filefilterlist>
</oatconfig>
</configuration>

View File

@ -1,36 +1,51 @@
# applications_call
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
- [Introduction](#section11660541593)
- [Architecture](#section78574815486)
- [Directory Structure](#section161941989596)
- [Repositories Involved](#section1371113476307)
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
## Introduction<a name="section11660541593"></a>
Based on the capabilities of the system platform, design and develop call applications, providing voice calls, video calls, call settings, mobile network settings, SIM card management settings, emergency dialing, and the function of adding personal emergency information. Build models from different perspectives and design the architecture of the call application to ensure that the basic functions are met while ensuring safety, resilience, reliability, privacy, etc.
### Directory Structure<a name="section161941989596"></a>
<img src="figures/callui_en.png" alt="img" style="zoom:100%; position: absolute; left:0px;" />
## Repositories Involved<a name="section1371113476307"></a>
```
/applications
├── callui # Call application master Ability, providing access to the application
│ └── src
│ └── main
│ ├── js # js code directory
│ ├── default
│ ├── assets # Picture catalog
│ ├── i18n # Chinese and English configuration
│ ├── pages # Page directory
│ ├── common # Common component or method configuration directory
│ ├── components # Public component
│ ├── constant # Application Constant Object Directory
│ ├── utils # Public method
│ ├── ServiceAbilty # ServiceAbilty started
│ ├── callManagerService.js # ServiceAbilty method
│ ├── service.js # ServiceAbilty method
│ ├── telephonyApi.js # ServiceAbilty method
│ ├── resources # Resource catalog
│ ├── config.json # Project configuration information
├── figures # Architecture Diagram Directory
│ └── callui_en.png # Architecture design picture
├── signature # Signature file
│ └── com.ohos.callui.p7b # com.ohos.callui signature file
```
## Repositories Involved<a name="section1371113476307"></a>
System apps
**applications_standard_call**

View File

@ -1,39 +1,51 @@
# applications_call
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
- [简介](#section11660541593)
- [架构图](#section78574815486)
- [目录](#section161941989596)
- [相关仓](#section1371113476307)
1. xxxx
2. xxxx
3. xxxx
## 简介
#### 使用说明
基于系统平台能力设计和开发通话应用提供语音通话、视频通话、通话设置、移动网络设置、SIM卡管理设置、紧急拨号以及添加个人紧急信息的功能。从不同视角构建模型设计通话应用的架构确保在满足基本功能的同时确保安全、韧性、可靠、隐私等。
1. xxxx
2. xxxx
3. xxxx
### 架构图
#### 参与贡献
<img src="figures/callui_en.png" alt="img" style="zoom:100%;" />
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
## 目录
```
/applications
├── callui # 通话应用主Ability提供拉起应用入口
│ └── src
│ └── main
│ ├── js # js代码目录
│ ├── default
│ ├── assets # 图片目录
│ ├── i18n # 中英文配置
│ ├── pages # 页面目录
│ ├── common # 公共组件或方法配置目录
│ ├── components # 公共组件
│ ├── constant # 应用常量对象目录
│ ├── utils # 公共方法
│ ├── ServiceAbilty # ServiceAbilty启动
│ ├── callManagerService.js # ServiceAbilty方法
│ ├── service.js # ServiceAbilty方法
│ ├── telephonyApi.js # ServiceAbilty方法
│ ├── resources # 资源目录
│ ├── config.json # 项目配置信息
├── figures # 架构图目录
│ └── callui_en.png # 架构设计图片
├── signature # 签名文件
│ └── com.ohos.callui.p7b # com.ohos.callui签名文件
```
#### 特技
## 相关仓
系统应用
**applications_standard_call**
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

36
build.gradle Normal file
View File

@ -0,0 +1,36 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply plugin: 'com.huawei.ohos.app'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 7
supportSystem "standard"
defaultConfig {
compatibleSdkVersion 7
}
}
buildscript {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
}
dependencies {
classpath 'com.huawei.ohos:hap:2.4.5.5'
}
}
allprojects {
repositories {
maven {
url 'https://repo.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
}
}

2
callui/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
/node_modules

20
callui/build.gradle Normal file
View File

@ -0,0 +1,20 @@
apply plugin: 'com.huawei.ohos.hap'
//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510
ohos {
compileSdkVersion 7
defaultConfig {
compatibleSdkVersion 7
}
buildTypes {
release {
proguardOpt {
proguardEnabled false
rulesFiles 'proguard-rules.pro'
}
}
}
arkEnabled false
}
dependencies {}

1
callui/package.json Normal file
View File

@ -0,0 +1 @@
{}

1
callui/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1 @@
# config module specific ProGuard rules here.

View File

@ -0,0 +1,72 @@
{
"app": {
"bundleName": "com.ohos.callui",
"vendor": "ohos",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.ohos.callui",
"name": ".MyApplication",
"mainAbility": "com.ohos.callui.MainAbility",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "callui",
"moduleType": "entry",
"installationFree": true
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"visible": true,
"orientation": "unspecified",
"name": ".MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"formsEnabled": false,
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "singleton",
"srcPath": "default",
"srcLanguage": "js"
},
{
"name": ".ServiceAbility",
"icon": "$media:icon",
"description": "service",
"type": "service",
"srcPath": "ServiceAbility",
"srcLanguage": "js",
"visible": true
}
],
"js": [
{
"pages": [
"pages/index/index",
"pages/conferenceManage/conferenceManage"
],
"name": "default",
"window": {
"designWidth": 720,
"autoDesignWidth": false
}
}
]
}
}

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2021 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: call manager service
*/
import PA from '@ohos.ability.particleAbility';
import telephonyCall from './telephonyApi.js';
import commonEvent from '@ohos.commonevent';
let subscriber;
const CALL_BUNDLE_NAME = 'com.ohos.callui';
const ABILITY_NAME = 'com.ohos.callui.MainAbility';
const CALL_STATUS_INCOMING = 4;
const CALL_STATUS_DIALING = 2;
const CALL_STATUS_DISCONNECTED = 6;
const events = ['callui.event.callEvent'];
/**
* class CallManagerService
*/
export default class CallManagerService {
constructor() {
this.callData = null;
this.callList = [];
this.addRegisterListener();
this.addSubscriber();
}
/**
* add callui app subscriber
*/
async addSubscriber() {
subscriber = await new Promise((resolve) => {
commonEvent.createSubscriber({events},
(err, data) => {
resolve(data);
}
);
});
commonEvent.subscribe(subscriber, (err, res) => {
if (err.code === 0) {
const obj = JSON.parse(res.data);
const {key} = obj;
if (key === 'getInitCallData') {
this.publishData(this.callData);
}
} else {
console.error('callui service commonEvent.subscribe failed err: ' + JSON.stringify(err));
}
});
}
/**
* add register listener
*/
addRegisterListener() {
telephonyCall.registerCallStateCallback(this.getCallData.bind(this));
}
/**
* get callData
* @param { Object } callData - Object
*/
getCallData(callData) {
this.callData = callData;
this.updateCallList();
const {callState} = this.callData;
// single call or dialing pull up the application
if ((callState === CALL_STATUS_INCOMING && this.callList.length === 1) || callState === CALL_STATUS_DIALING) {
this.startAbility(callData);
} else {
this.publishData(callData);
}
}
/**
* start ability
* @param { Object } callData - Object
*/
startAbility(callData) {
PA.startAbility({
want: {
bundleName: CALL_BUNDLE_NAME,
abilityName: ABILITY_NAME,
parameters: callData
}
}).then((data) => {
console.log('callUI service PA.startAbility res: ' + JSON.stringify(data));
}).catch((err) => {
console.log('callUI service PA.startAbility err: ' + JSON.stringify(err));
});
}
/**
* update callList
*/
updateCallList() {
const {callState, callId} = this.callData;
const targetObj = this.callList.find((v) => v.callId === callId);
if (targetObj) {
Object.assign(targetObj, {...this.callData});
} else {
this.callList.push({...this.callData});
}
if (callState === CALL_STATUS_DISCONNECTED) {
const index = this.callList.findIndex((v) => v.callId === callId);
this.callList.splice(index, 1);
}
}
/**
* commonEvent publish data
* @param { Object } callData - Object
*/
publishData(callData) {
commonEvent.publish('callui.event.callDetailsChange', {
bundleName: CALL_BUNDLE_NAME,
isOrdered: false,
data: JSON.stringify(callData)
}, (res) => {
console.log('callUI service commonEvent.publish callback res: ' + res);
});
}
/**
* unsubscribe
*/
unsubscribe() {
commonEvent.unsubscribe(subscriber, (err) => {
if (err.code !== 0) {
console.error('callUI service commonEvent.unsubscribe err: ' + JSON.stringify(err));
}
});
}
/**
* remove register listener
*/
removeRegisterListener() {
telephonyCall.unRegisterCallStateCallback();
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 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: service entry
*/
import CallManagerService from './callManagerService.js';
export default {
/**
* onStart
*/
onStart() {
console.log('onStart callUI service');
this.callManagerService = new CallManagerService();
},
/**
* onStop
*/
onStop() {
console.log('onStop callUI service');
this.callManagerService.unsubscribe();
this.callManagerService.removeRegisterListener();
}
};

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 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: Voice call API interface call
*/
import call from '@ohos.telephony.call';
const prefixLog = 'callui service:@ohos.telephony.call:';
/**
* register call state callback
* @param { Function } callBack - inject an Function
*/
export function registerCallStateCallback(callBack) {
call.on('callDetailsChange', (err, res) => {
if (err) {
console.log(prefixLog + 'call.on registerCallStateCallback' + JSON.stringify(err));
return;
}
console.log(prefixLog + 'call.on registerCallStateCallback callState: ' + res.callState);
callBack(res);
});
console.log('call.on call end');
}
/**
* onRegister call state callback
*/
export function unRegisterCallStateCallback() {
call.off('callDetailsChange', (err, res) => {
if (err) {
console.log(prefixLog + 'call.off unRegisterCallStateCallback' + JSON.stringify(err));
return;
}
console.log(prefixLog + 'call.off unRegisterCallStateCallback' + JSON.stringify(res));
});
}
export default {
registerCallStateCallback,
unRegisterCallStateCallback,
};

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 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: Entry file
*/
import CallManager from './model/callManager.js';
import {defaultCallData} from './common/constant/callStateConst.js';
export default {
callData: {
...defaultCallData
},
callList: [],
callTimeList: [],
appInactiveState: false,
/**
* onCreate
*/
onCreate() {
console.info('callui app Application onCreate');
this.callManger = new CallManager(this);
},
/**
* onDestroy
*/
onDestroy() {
console.info('callui app Application onDestroy');
this.callManger.clearTimer();
this.callManger.unsubscribe();
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2021 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.
*/
.container {
flex-direction: column;
height: 289px;
}
.func-btn-group {
height: 100px;
padding: 0 40px;
justify-content: space-between;
}
.bottom-btn-wrap {
height: 112px;
margin-top: 72px;
padding: 0 40px;
justify-content: space-between;
}
.btn-item {
flex: 1;
height: 112px;
justify-content: center;
align-items: center;
}
.btn-box {
width: 112px;
height: 112px;
border-radius: 56px;
}
.dialog-box {
width: 656px;
}
.dialog-content {
flex-direction: column;
}
.dialog-title {
margin-left: 48px;
color: #000;
font-size: 36px;
font-weight: bold;
margin-top: 50px;
}
.backStyleMsg {
margin-left: 48px;
font-size: 32px;
color: #000;
width: 560px;
height: 100px;
border-bottom: 1px solid #989A9C;
}
.backStyle {
margin-left: 48px;
font-size: 32px;
color: #000;
width: 560px;
height: 100px;
border-bottom: 1px solid #989A9C;
}
.list-item {
width: 656px;
height: 96px;
}
.list {
width: 656px;
margin-top: 38px;
flex-direction: column;
}
.cancel-box {
width: 100%;
height: 80px;
justify-content: center;
align-items: center;
margin-bottom: 30px;
}
.cancel-box text {
color: #0A59F7;
}

View File

@ -0,0 +1,69 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<element name="func-btn" src="../funcBtn/funcBtn.hml"></element>
<div class="container">
<div class="func-btn-group" style="justify-content : space-around;">
<div for="btnList">
<func-btn
btn-type="{{ $item.type }}"
icon-default-url="{{ $item.iconDefaultUrl }}"
icon-text="{{ $item.iconText }}">
</func-btn>
</div>
</div>
<div class="bottom-btn-wrap">
<div class="btn-item">
<div class="btn-box" @click="onReject">
<image src="assets/picture/hangUP.png"></image>
</div>
</div>
<div class="btn-item">
<div class="btn-box" @click="onAnswer">
<image src="assets/picture/answer.png"></image>
</div>
</div>
</div>
<dialog id="msgDialog" class="dialog-box" oncancel="cancelDialog">
<div class="dialog-content">
<text class="dialog-title">{{ $t('strings.hangUpReply') }}</text>
<div class="list">
<div class="list-item" for="msgList">
<text class="{{ $idx == msgList.length - 1 ? 'backStyle' : '' }}backStyleMsg"
@click="msgItemClick($item.msg)">{{ $item.msg }}</text>
</div>
</div>
<div class="cancel-box" onclick="cancelHandle('msg')">
<text>{{ $t('strings.cancel') }}</text>
</div>
</div>
</dialog>
<dialog id="remindDialog" class="dialog-box" oncancel="cancelDialog">
<div class="dialog-content">
<text class="dialog-title">{{ $t('strings.callBackReminder') }}</text>
<div class="list">
<div class="list-item" for="remindList">
<text class="{{ $idx == remindList.length - 1 ? 'backStyle' : '' }} backStyleMsg"
@click="remindItemClick($item.msg)">{{ $item.msg }}</text>
</div>
</div>
<div class="cancel-box" onclick="cancelHandle('remind')">
<text>{{ $t('strings.cancel') }}</text>
</div>
</div>
</dialog>
</div>

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2021 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: Incoming call interface components
*/
import {acceptCall, rejectCall, hangUpCall} from '../../../model/callServiceProxy.js';
import {CALL_STATUS_WAITING} from '../../constant/callStateConst.js';
import {BASE_URL} from '../../constant/imagePathConst.js';
const SMS_REJECTION = `${BASE_URL}shortMessageDisabled.png`;
const SMS_REMINDER = `${BASE_URL}remindDisabled.png`;
export default {
props: {
callData: {
default: {}
},
},
data: {
btnList: [],
msgList: [],
remindList: [],
},
onInit() {
this.btnList = [
{
type: 'msg',
iconText: this.$t('strings.sms'),
iconDefaultUrl: SMS_REJECTION,
},
{
type: 'remind',
iconText: this.$t('strings.remind'),
iconDefaultUrl: SMS_REMINDER,
},
];
this.msgList = [
{
id: 1,
msg: this.$t('strings.backLater')
},
{
id: 2,
msg: this.$t('strings.answerThePhone')
},
{
id: 3,
msg: this.$t('strings.contactMeLater')
},
{
id: 4,
msg: this.$t('strings.beThereSoon')
},
{
id: 5,
msg: this.$t('strings.customSMS')
}
];
this.remindList = [
{
id: 1,
msg: this.$t('strings.minutes')
},
{
id: 2,
msg: this.$t('strings.oneHourLater')
},
{
id: 3,
msg: this.$t('strings.twoHoursLater')
},
];
},
/**
* Control the dialog box to close
* @param {string} type - string
*/
cancelHandle(type) {
if (type === 'msg') {
this.$element('msgDialog').close();
} else if (type === 'remind') {
this.$element('remindDialog').close();
}
},
/**
* Control the dialog box to open
* @param {Object} obj - Object
*/
btnClick(obj) {
const type = obj.detail;
if (type === 'msg') {
this.$element('msgDialog').show();
} else if (type === 'remind') {
this.$element('remindDialog').show();
}
},
/**
* Answer the phone interface
*/
onAnswer() {
console.log('onAnswer function start');
console.log('this.callData: ' + JSON.stringify(this.callData));
acceptCall(this.callData.callId);
},
/**
* Handling interface call hangup and rejection
*/
async onReject() {
const {callId, callState} = this.callData;
if (callState !== CALL_STATUS_WAITING) {
rejectCall(callId);
} else {
hangUpCall(callId);
}
},
/**
* Call rejection interface
* @param {string} msg - Send SMS content
*/
msgItemClick(msg) {
rejectCall(this.callData.callId, msg);
this.cancelHandle('msg');
}
};

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 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.
*/
.bott-btn-wrap {
padding: 0 20px;
justify-content: space-between;
align-items: center;
}
.btn-item {
width: 33.3%;
height: 112px;
justify-content: center;
align-items: center;
}
.btn-box {
width: 60px;
height: 60px;
}
.hang-up-btn {
width: 112px;
height: 112px;
border-radius: 56px;
}

View File

@ -0,0 +1,34 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<div class="bott-btn-wrap">
<div class="btn-item">
<div class="btn-box" @click="clickShowHandle">
<image src="assets/picture/keyboard.png"></image>
</div>
</div>
<div class="btn-item">
<div class="hang-up-btn" @click="onHangUp">
<image src="assets/picture/hangUP.png"></image>
</div>
</div>
<div class="btn-item">
<div class="btn-box">
<image src="assets/picture/audioChannel.png"></image>
</div>
</div>
</div>

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 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: bottom button component
*/
import {hangUpCall} from '../../../model/callServiceProxy.js';
export default {
props: {
callData: {
default: {}
},
},
data: {
showKeyboard: false,
isSpeaker: false
},
/**
* method to control the display of DTMF keyboard
* parent component pass by value child component
*/
clickShowHandle() {
this.showKeyboard = !this.showKeyboard;
this.$emit('showKeyboard', this.showKeyboard);
},
/**
* this method controls the change of the hands-free switch button
*/
clickSpeaker() {
this.isSpeaker = !this.isSpeaker;
},
/**
* this method is to call the hangup interface
*/
onHangUp() {
hangUpCall(this.callData.callId);
}
};

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2021 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.
*/
.list-wrap {
width: 100%;
flex-direction: column;
align-items: center;
height: 256px;
position: relative;
top: -100px;
}
.list-item {
width: 100%;
margin: 0 48px;
height: 128px;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid grey;
}
.left text {
color: #fff;
font-size: 30px;
}
.right div {
justify-content: center;
align-items: center;
}
.icon {
width: 30px;
height: 30px;
border-radius: 4px;
align-items: center;
justify-content: center;
text-align: center;
background-color: rgba(255, 255, 255, 0.60);
}
.icon text {
font-size: 18px;
}
.time {
margin-left: 16px;
font-size: 30px;
color: #fff;
}
.time text {
font-size: 30px;
color: rgba(255, 255, 255, 0.60);
}
.iconCall {
margin-left: 30px;
margin-bottom: 10px;
width: 50px;
height: 40px;
background-image: url(assets/picture/userCall.png);
background-repeat: no-repeat;
background-size: 50px;
}
.hold text {
color: rgba(255, 255, 255, 0.60);
font-size: 28px;
}

View File

@ -0,0 +1,34 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<div class="list-wrap">
<div class="list-item" for="{{ list }}">
<div class="left" >
<text>{{ phoneNumber }}</text>
</div>
<div class="right">
<div if="{{ $item.callState === callStateObj.CALL_STATUS_ACTIVE }}">
<div class="time">
<text>{{ $item.callTime }}</text>
</div>
<div if="{{ callState === callStateObj.CALL_STATUS_WAITING }}" class="iconCall" @click="onHangUp($item.callId)"></div>
</div>
<div else class="hold" >
<text>{{ $t(`strings.${callStateTextMap[$item.callState]}`) }}</text>
</div>
</div>
</div>

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 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 callStateObj, {CALL_STATUS_WAITING, CALL_STATUS_IDLE, getCallStateText, callStateTextMap
} from '../../../common/constant/callStateConst.js';
import {hangUpCall} from '../../../model/callServiceProxy.js';
export default {
props: {
callList: {
default: []
},
callTimeList: {
default: []
},
callState: {
default: CALL_STATUS_IDLE
},
},
data: {
callStateObj,
callStateTextMap,
},
computed: {
/**
* 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 !== CALL_STATUS_WAITING);
},
/**
* Phone number display
* @return {string} Phone number
*/
phoneNumber() {
return this.$item.accountNumber || this.$t('strings.unknownNumber');
},
/**
* Internationalized text
* @return {string} key - getCallStateText Internationalized text
*/
callStateText() {
const key = getCallStateText(this.callState) || '';
return key && this.$t(`strings.${key}`);
}
},
/**
* hang up
* @param {number} callId - callId
*/
onHangUp(callId) {
hangUpCall(callId);
}
};

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2021 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.
*/
.contact-card {
flex-direction: column;
align-items: center;
padding-top: 200px;
height: 600px;
}
.informationBar {
flex-direction: column;
align-items: center;
}
.phone-num {
align-items: center;
justify-content: center;
margin-bottom: 20px;
}
.phone-num text {
color: #fff;
text-align: center;
font-size: 52px;
}
.address {
justify-content: center;
}
.address text {
color: rgba(255, 255, 255, 0.60);
font-size: 28px;
}
.time {
height: 60px;
align-items: center;
justify-content: center;
}
.time text {
color: #fff;
color: rgba(255, 255, 255, 0.60);
}
.time .icon {
width: 30px;
height: 30px;
align-items: center;
justify-content: center;
margin-right: 20px;
background-color: rgba(255, 255, 255, 0.60);
}
.time .icon text {
font-size: 18px;
color: #000;
}
.call-state {
height: 60px;
justify-content: center;
align-items: center;
color: #fff;
}
.points {
height: 38px;
width: 30px;
justify-content: flex-start;
align-items: center;
color: #fff;
}
.nullCharacter {
height: 60px;
justify-content: center;
align-items: center;
color: #fff;
}
.call-state text {
font-size: 28px;
color: rgba(255, 255, 255, 0.60);
}
.iconGo {
margin-left: 20px;
margin-top: 8px;
height: 36px;
width: 20px;
background-image: url(assets/picture/messageGo.png);
background-repeat: no-repeat;
}
.conference {
justify-content: center;
align-items: center;
flex-direction: column;
}
.conferenceText {
justify-content: center;
align-items: center;
flex-direction: column;
}
.meetingBox {
align-items: center;
margin-bottom: 15px;
justify-content: center;
width: 330px;
}
.meetingBox image {
width: 24px;
height: 26px;
margin-left: 16px;
}
.meetingContent {
color: #fff;
font-size: 56px;
}
.inputFrame {
flex-direction: column;
}

View File

@ -0,0 +1,75 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<element name="call-list" src="../callList/callList.hml"></element>
<div class="contact-card">
<div class="conference" @click="userList" if="{{ isConference }}">
<div class="conferenceText" show="{{ !(isShowKeyboard && kbCommand) }}">
<div class="meetingBox">
<text class="meetingContent">{{ $t('strings.telephoneConference') }}</text>
<image src="../../../assets/picture/conference.png"></image>
</div>
<div class="time">
<div class="icon">
<text>HD</text>
</div>
<text>{{ callTimeList[0].callTime }}</text>
</div>
</div>
<div else>
<text show="{{ isShowKeyboard && kbCommand }}" id="codeBox" style="font-size : 52px; color: white;">
<span>{{ kbCommand }}</span>
</text>
</div>
</div>
<div else class="informationBar">
<div if="{{ isShowCallList }}">
<call-list call-list="{{ callList }}"
call-time-list="{{ callTimeList }}"
call-state="{{ callState }}">
</call-list>
</div>
<div if="{{ isShowCard || (kbCommand && isShowKeyboard) }}" style="flex-direction : column;">
<div class="phone-num">
<text show="{{ isShowKeyboard && kbCommand }}" id="codeBox" style="font-size : 52px;">
<span>{{ kbCommand }}</span>
</text>
<text show="{{! (isShowKeyboard && kbCommand) }}" style="font-size : 52px;">
<span>{{ phoneNumber }}</span>
</text>
</div>
<div class="address" if="{{ ! isShowKeyboard && callState !== callStateObj.CALL_STATUS_ALERTING }}">
<text>{{ address }} {{ simCardType }}</text>
</div>
</div>
<div if="{{ isShowTime }}" class="time">
<text>{{ callTimeList[0].callTime }}</text>
</div>
<div if="{{ !isShowTime && callList.length === 1 }}" class="call-state">
<div if="{{ callState === callStateObj.CALL_STATUS_DIALING }}">
<text>{{ callStateText }}</text>
<div class="points">
<text>{{ pointText }}</text>
</div>
</div>
<div else class="nullCharacter">
<text>{{ callStateText }}</text>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2021 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 router from '@system.router';
import callStateObj, {
defaultCallData,
CALL_STATUS_ACTIVE,
CALL_STATUS_DIALING,
CALL_STATUS_WAITING,
getCallStateText
} from '../../../common/constant/callStateConst.js';
import {formatPhoneNum} from '../../utils/utils.js';
import {TEL_CONFERENCE_ACTIVE} from '../../constant/conferenceConst.js';
const THREE_DOTS = 3;
const TIMER_TIMING = 1000;
export default {
props: {
callData: {
default: defaultCallData
},
callList: {
default: []
},
isShowKeyboard: {
default: false
},
kbCommand: {
default: ''
}
},
data: {
callStateObj,
address: '',
simCardType: '',
timer: null,
pointTimer: null,
callStateText: '',
pointText: '',
callTimeList: []
},
computed: {
/**
* Call status
* @return {number} - Call status
*/
callState() {
return this.callData.callState;
},
/**
* Phone number display
* @return {string} - phone number
*/
phoneNumber() {
return formatPhoneNum(this.callData.accountNumber) || this.$t('strings.unknownNumber');
},
/**
* Whether to display the time
* @return {boolean} - return success true fail false
*/
isShowTime() {
return this.callState === CALL_STATUS_ACTIVE && this.callList.length === 1;
},
/**
* Determine whether to display the call list or the input box
* @return {boolean} - return success true fail false
*/
isShowCard() {
return this.callList.length === 1
|| (this.callList.length > 1 && this.callList.some((v) => v.callState === CALL_STATUS_WAITING));
},
/**
* Conference call status
* @return {number} - Conference call status
*/
conferenceState() {
return this.callData.conferenceState;
},
/**
* Conference call
* @return {boolean} - return success true fail false
*/
isConference() {
return this.conferenceState === TEL_CONFERENCE_ACTIVE;
},
/**
* Reference call-list component
* @return {boolean} - return success true fail false
*/
isShowCallList() {
return (!this.kbCommand || (this.kbCommand && !this.isShowKeyboard))
&& (this.callState === this.callStateObj.CALL_STATUS_WAITING
|| this.callList.length >= 2);
}
},
onInit() {
this.callTimeList = this.$app.callTimeList;
},
/**
* Animation effect of three dots behind dialing
*/
addTextPoint() {
let count = 0;
this.pointTimer = setInterval(() => {
this.pointText = new Array(count % THREE_DOTS + 1).fill('.').join('');
if (count >= THREE_DOTS) {
count = 0;
}
count++;
}, TIMER_TIMING);
},
/**
* Internationalization display and adding three-point animation effect of dialing status
* @param {number} newVal - state
*/
onCallStateChange(newVal) {
const key = getCallStateText(newVal) || '';
this.callStateText = key ? this.$t(`strings.${key}`) : '';
this.pointTimer && clearInterval(this.pointTimer);
if (newVal === CALL_STATUS_DIALING) {
this.addTextPoint();
}
},
/**
* Jump to the conference call interface
*/
userList() {
router.push({
uri: 'pages/conferenceManage/conferenceManage'
});
}
};

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 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.
*/
.func-btn {
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
}
.img-box {
width: 100px;
height: 60px;
justify-content: center;
align-items: center;
}
.icon-img {
width: 60px;
height: 60px;
}
.icon-text-wrap {
padding-top: 20px;
justify-content: center;
}
.icon-text {
color: rgba(255, 255, 255, 0.60);
font-size: 24px;
}
.icon-text-disable {
color: grey;
}
.icon-text-Enable {
color: #007DFF;
}
.icon-text-default {
color: rgba(255, 255, 255, 0.60);
}

View File

@ -0,0 +1,28 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<div class="func-btn">
<div class="img-box" @click="btnClick">
<div class="icon-img"
disabled="{{ isDisable }}">
<image src="{{ iconUrl }}"></image>
</div>
</div>
<div class="icon-text-wrap">
<text class="icon-text icon-text-{{ iconClassName }}">{{ iconText }}</text>
</div>
</div>

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2021 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: Function button component
*/
export default {
props: {
btnType: {
default: '',
},
iconDisableUrl: {
default: '',
},
iconDefaultUrl: {
default: ''
},
iconActiveUrl: {
default: ''
},
isDisable: {
default: false
},
isActive: {
default: false
},
iconText: {
default: '',
}
},
data: {},
computed: {
/**
* Button group picture change control
* @return {string} - return iconUrl
*/
iconUrl() {
if (this.isDisable && this.iconDisableUrl) {
return this.iconDisableUrl;
}
return this.isActive && this.iconDefaultUrl ? this.iconActiveUrl : this.iconDefaultUrl;
},
/**
* Button group style display
* @return {string} - Button group style display
*/
iconClassName() {
if (this.isDisable) {
return 'disable';
}
if (this.isActive) {
return 'enable';
}
return 'default';
}
},
/**
* Click event carries parameters
*/
btnClick() {
this.$emit('btnHandle', this.btnType);
}
};

View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2021 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: Button group configuration file
*/
import {BASE_URL} from '../../constant/imagePathConst.js';
const firstBtns = [
{
type: 'record',
iconDisableUrl: 'soundRecordingGrey',
iconDefaultUrl: 'soundRecording',
iconActiveUrl: 'soundEnabled',
isDisable: true,
isActive: false,
iconText: ''
},
{
type: 'keep',
iconDisableUrl: 'waitForGrey',
iconDefaultUrl: 'waitFor',
iconActiveUrl: 'waitForEnabled',
isDisable: true,
isActive: false,
iconText: ''
},
{
type: 'add',
iconDisableUrl: 'addToGrey',
iconDefaultUrl: 'addTo',
iconActiveUrl: '',
isDisable: false,
isActive: false,
iconText: ''
},
{
type: 'video',
iconDisableUrl: 'videoGrayingGrey',
iconDefaultUrl: 'videoGraying',
iconActiveUrl: 'videoEnabled',
isDisable: true,
isActive: false,
iconText: ''
},
{
type: 'mute',
iconDisableUrl: 'muteGrey',
iconDefaultUrl: 'mute',
iconActiveUrl: 'muteEnabled',
isDisable: true,
isActive: false,
iconText: ''
},
{
type: 'contact',
iconDisableUrl: 'contacts',
iconDefaultUrl: 'contacts',
iconActiveUrl: '',
isDisable: false,
isActive: false,
iconText: ''
}
];
const secondBtns = [
{
type: 'exchange',
iconDisableUrl: 'exchangeGrey',
iconDefaultUrl: 'exchangeIcon',
iconActiveUrl: 'exchangeIcon',
isDisable: false,
isActive: false,
iconText: ''
},
{
type: 'merge',
iconDisableUrl: 'addCallGrey',
iconDefaultUrl: 'addCall',
iconActiveUrl: 'addCall',
isDisable: true,
isActive: false,
iconText: ''
}
];
/**
* Process the image text of the button group
* @param {Array} arr - Pass in an array
*/
function addIconUrl(arr) {
const regExp = /^icon.*.*Url$/;
arr.forEach((item) => {
for (let key in item) {
if (Object.prototype.hasOwnProperty.call(item, key) && regExp.test(key)) {
item[key] = `${BASE_URL}${item[key]}.png`;
}
}
});
}
addIconUrl(firstBtns);
addIconUrl(secondBtns);
export const btnGroupList = firstBtns;
export const threePartyList = secondBtns;

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021 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.
*/
.func-btn-group {
flex-wrap: wrap;
padding: 0 20px;
justify-content: space-between;
position: relative;
width: 720px;
}
.btn-wrap {
width: 33.33%;
height: 160px;
flex-direction: column;
justify-content: center;
align-items: center;
}

View File

@ -0,0 +1,34 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<element name="func-btn" src="../funcBtn/funcBtn.hml"></element>
<div class="func-btn-group">
<block for="{{ btnList }}">
<div class="btn-wrap">
<func-btn @btn-handle="btnClick"
btn-type="{{ $item.type }}"
is-disable="{{ $item.isDisable }}"
is-active="{{ $item.isActive }}"
icon-text="{{ $item.iconText }}"
icon-disable-url="{{ $item.iconDisableUrl }}"
icon-default-url="{{ $item.iconDefaultUrl }}"
icon-active-url="{{ $item.iconActiveUrl }}">
</func-btn>
</div>
</block>
</div>

View File

@ -0,0 +1,184 @@
/*
* Copyright (c) 2021 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: Function button group component
*/
import FA from '@ohos.ability.featureAbility';
import {btnGroupList, threePartyList} from './btnGroupConfig.js';
import {
CALL_STATUS_ACTIVE, CALL_STATUS_IDLE, CALL_STATUS_HOLDING, defaultCallData
} from '../../../common/constant/callStateConst.js';
import {holdCall, unHoldCall, switchCall, combineConference} from '../../../model/callServiceProxy.js';
import clone from '../../utils/clone.js';
import {TEL_CONFERENCE_ACTIVE} from '../../constant/conferenceConst.js';
const textMap = {
'record': 'recording',
'keep': 'keep',
'add': 'addCall',
'video': 'videoCall',
'mute': 'mute',
'contact': 'contactPerson',
'exchange': 'exchange',
'merge': 'mergeCall'
};
export default {
props: {
callData: {
default: defaultCallData
},
callList: {
default: []
}
},
data: {
timer: null,
count: 0,
btnGroupList,
threePartyList,
btnList: [],
oldCallState: CALL_STATUS_IDLE,
},
computed: {
/**
* @return {number} - call state
*/
callState() {
return this.callData.callState;
}
},
onInit() {
this.btnGroupList.forEach((v) => {
v.iconText = this.$t(`strings.${textMap[v.type]}`);
});
this.threePartyList.forEach((v) => {
v.iconText = this.$t(`strings.${textMap[v.type]}`);
});
this.btnList = clone(this.btnGroupList);
},
/**
* update state of group buttons
* @param {number} newVal - call state
*/
onCallStateChange(newVal) {
if (this.callList.length >= 2 && this.callList.every((v) => v.conferenceState !== TEL_CONFERENCE_ACTIVE)) {
this.btnList.splice(1, 2, ...clone(this.threePartyList));
} else {
this.btnList.splice(1, 2, ...clone(this.btnGroupList).splice(1, 2));
}
if (newVal === CALL_STATUS_ACTIVE || newVal === CALL_STATUS_HOLDING) {
this.btnList.forEach((item) => {
if (!['video', 'record', 'add', 'mute', 'contact'].includes(item.type)) {
item.isDisable = false;
}
});
if (newVal === CALL_STATUS_HOLDING) {
this.btnList[1].isActive = true;
this.btnList[4].isDisable = true;
}
} else {
this.btnList.forEach((item) => {
if (item.type === 'contact') {
item.isDisable = true;
}
});
}
},
/**
* Display the buttons of the button group
* @param {Object} obj - object
*/
btnClick(obj) {
const type = obj.detail;
const { callId } = this.callData;
if (['record', 'keep', 'video', 'mute'].includes(type)) {
this.btnList.forEach((item) => {
if (item.type === type) {
item.isActive = !item.isActive;
}
});
if (type === 'record') {
if (this.btnList[0].isActive) {
this.clockHandle();
} else {
this.count = 0;
clearInterval(this.timer);
this.btnList[0].iconText = this.$t('strings.recording');
}
}
}
switch (type) {
case 'record':
break;
case 'keep':
this.keepHandle('keep');
break;
case 'exchange':
switchCall(callId);
break;
case 'add':
FA.startAbility({
want: {
bundleName: 'com.ohos.contacts',
abilityName: 'com.ohos.contacts.MainAbility',
parameters: null
}
});
break;
case 'video':
break;
case 'mute':
break;
case 'contact':
FA.startAbility({
want: {
bundleName: 'com.ohos.contacts',
abilityName: 'com.ohos.contacts.MainAbility',
parameters: null
}
});
break;
case 'merge':
combineConference(callId);
break;
default:
break;
}
},
/**
* Call hold interface
* @param {string} type - Click the hold button
*/
keepHandle(type) {
const awaitIsActive = this.btnList.find((v) => v.type === type).isActive;
awaitIsActive ? holdCall(this.callData.callId) : unHoldCall(this.callData.callId);
},
/**
* Clear timer
*/
onDestroy() {
this.timer && clearInterval(this.timer);
}
};

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2021 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.
*/
.container {
width: 100%;
margin-bottom: 15px;
}
.container .cell-warp {
justify-content: center;
align-items: center;
flex-wrap: wrap;
height: 600px;
padding: 0 20px;
}
.cell {
width: 33.3%;
height: 150px;
text-align: center;
justify-content: center;
align-items: center;
color: #fff;
}
.btn {
width: 120px;
height: 120px;
border-radius: 60px;
margin: 10px;
align-items: center;
justify-content: center;
border-radius: 120px;
flex-direction: column;
position: relative;
}
.btn:active {
background-color: rgba(255, 255, 255, 0.1);
}
@keyframes waveCircle {
0% {
width: 0;
height: 0;
background-color: rgba(255, 255, 255, 0.1);
}
100% {
background-color: transparent;
width: 120px;
height: 120px;
}
}
.number {
height: 60px;
font-size: 52px;
justify-content: center;
text-align: center;
}
.sign {
height: 40px;
font-size: 50px;
justify-content: center;
}
.number text {
font-size: 52px;
color: #fff;
}
.sign text {
font-size: 24px;
color: rgba(255, 255, 255, 0.60);
}
.voicemail {
width: 32px;
height: 14px;
}

View File

@ -0,0 +1,39 @@
<!--
/*
* Copyright (c) 2021 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.
*/
-->
<div class="container">
<div class="cell-warp">
<div class="cell"
for="{{ dataList }}"
tid="$idx"
onclick="cellClick($item)">x
<div class="btn {{ curIdx === $idx ? activeClass : '' }}"
onclick="btnClick($item)"
on:touchstart="onBtnTouchStart($item)"
on:touchend="onBtnTouchEnd($item)"
onlongpress="btnLongPress($item)">
<div class="number">
<text>{{ $item.value }}</text>
</div>
<div class="sign">
<text if="{{$item.value !== 1}}">{{ $item.sign }}</text>
<image else class="voicemail" src="assets/picture/voicemail.png"></image>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2021 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: DTMF keyboard assembly
*/
import {startDTMF, stopDTMF} from '../../../model/callServiceProxy.js';
export default {
props: {
callData: {
default: {}
}
},
data: {
dataList: [
{
value: 1,
sign: 'o_o'
},
{
value: 2,
sign: 'ABC'
},
{
value: 3,
sign: 'DEF'
},
{
value: 4,
sign: 'GHI'
},
{
value: 5,
sign: 'JKL'
},
{
value: 6,
sign: 'MNO'
},
{
value: 7,
sign: 'PQRS'
},
{
value: 8,
sign: 'TUV'
},
{
value: 9,
sign: 'WXYZ'
},
{
value: '*',
sign: '(P)'
},
{
value: 0,
sign: '+'
},
{
value: '#',
sign: '(W)'
},
]
},
/**
* Click to get the value of the array
* @param {Object} obj - Object
*/
btnClick(obj) {
this.$emit('cellHandle', obj.value);
},
/**
* Get the value of the sign of the array
* @param {Object} obj - Object
*/
btnLongPress(obj) {
if (['(p)', '+', '(w)'].includes(obj.sign)) {
this.$emit('cellHandle', obj.sign);
}
},
/**
* Call and press the DTMF interface
* @param {Object} obj - Object
*/
onBtnTouchStart(obj) {
startDTMF(this.callData.callId, String(obj.value));
},
/**
* Call release and send DTMF interface
* @param {Object} obj - Incoming value
*/
onBtnTouchEnd() {
stopDTMF(this.callData.callId);
},
};

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2021 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: Call mode
*/
// Voice calls
export const CALL_STATUS_VOICE = 0;
// video call
export const CALL_STATUS_VIDEO = 1;

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2021 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: Call status
*/
// calling
export const CALL_STATUS_ACTIVE = 0;
// State keeping
export const CALL_STATUS_HOLDING = 1;
// Dialing
export const CALL_STATUS_DIALING = 2;
// The other party is ringing
export const CALL_STATUS_ALERTING = 3;
// Call from the other party
export const CALL_STATUS_INCOMING = 4;
// Waiting for third-party calls
export const CALL_STATUS_WAITING = 5;
// Hung up
export const CALL_STATUS_DISCONNECTED = 6;
// Hanging up
export const CALL_STATUS_DISCONNECTING = 7;
// Idle state
export const CALL_STATUS_IDLE = 8;
const callStateObj = {
CALL_STATUS_ACTIVE,
CALL_STATUS_HOLDING,
CALL_STATUS_DIALING,
CALL_STATUS_ALERTING,
CALL_STATUS_INCOMING,
CALL_STATUS_WAITING,
CALL_STATUS_DISCONNECTED,
CALL_STATUS_DISCONNECTING,
CALL_STATUS_IDLE
};
export const callStateTextMap = {
[CALL_STATUS_ACTIVE]: '',
[CALL_STATUS_HOLDING]: 'callHold',
[CALL_STATUS_DIALING]: 'dialing',
[CALL_STATUS_ALERTING]: 'partyIsRinging',
[CALL_STATUS_INCOMING]: '',
[CALL_STATUS_WAITING]: 'thirdPartyCalls',
[CALL_STATUS_DISCONNECTED]: 'hangUpCompleted',
[CALL_STATUS_DISCONNECTING]: 'hangingUp',
[CALL_STATUS_IDLE]: 'callIdle'
};
const callStateTxtList = ['calling', 'callHold', 'dialing', 'partyIsRinging', '', 'thirdPartyCalls', 'hangUpCompleted',
'hangingUp', 'callIdle'];
export const defaultCallData = {
callId: 0,
callState: CALL_STATUS_IDLE,
accountNumber: '',
videoState: 0,
callType: 0,
conferenceState: 0
};
export const getCallStateText = (state) => callStateTxtList[state] !== undefined ? callStateTxtList[state] : '';
export default callStateObj;

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2021 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: Call type
*/
// CS call
export const CALL_TYPE_CS = 0;
// IMS call
export const CALL_TYPE_IMS = 1;
// OTT call
export const CALL_TYPE_OTT = 2;
// OTHER other types of calls
export const CALL_TYPE_OTHER = 3;

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 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: Conference call status
*/
// Free conference call
export const TEL_CONFERENCE_IDLE = 0;
// Conference call activation
export const TEL_CONFERENCE_ACTIVE = 1;
// The conference call is disconnecting
export const TEL_CONFERENCE_DISCONNECTING = 2;
// Conference call disconnected
export const TEL_CONFERENCE_DISCONNECTED = 3;
export const conferenceStateObj = {
TEL_CONFERENCE_IDLE,
TEL_CONFERENCE_ACTIVE,
TEL_CONFERENCE_DISCONNECTING,
TEL_CONFERENCE_DISCONNECTED
};

View File

@ -0,0 +1,5 @@
// Image preprocessing
export const BASE_URL = 'assets/picture/';
// Configure storage
export const PHONE_NUMBER = '/data/accounts/account_0/appdata/com.ohos.callui/sharedPreference/SettingPreferences';

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 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: sim card status
*/
// SIM card status unknown
export const SIM_STATE_UNKNOWN = 0;
// SIM card is not present
export const SIM_STATE_NOT_PRESEN = 1;
// SIM card is locked
export const SIM_STATE_LOCKED = 2;
// SIM card is not ready
export const SIM_STATE_NOT_READY = 3;
// SIM card is in ready state
export const SIM_STATE_READY = 4;
// M card is in loading state
export const SIM_STATE_LOADED = 5;
export const getSimStateObj = {
SIM_STATE_UNKNOWN,
SIM_STATE_NOT_PRESEN,
SIM_STATE_LOCKED,
SIM_STATE_NOT_READY,
SIM_STATE_READY,
SIM_STATE_LOADED
};

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2021 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: Deep copy
*/
const mapTag = '[object Map]';
const setTag = '[object Set]';
const arrayTag = '[object Array]';
const objectTag = '[object Object]';
const argsTag = '[object Arguments]';
const boolTag = '[object Boolean]';
const dateTag = '[object Date]';
const numberTag = '[object Number]';
const stringTag = '[object String]';
const symbolTag = '[object Symbol]';
const errorTag = '[object Error]';
const regexpTag = '[object RegExp]';
const funcTag = '[object Function]';
const deepTag = [mapTag, setTag, arrayTag, objectTag, argsTag];
/**
* forEach
* @param { array } array
* @param { function } iteratee
*/
function forEach(array, iteratee) {
let index = -1;
const length = array.length;
while (++index < length) {
iteratee(array[index], index);
}
return array;
}
/**
* is object
* @param { any } target
*/
function isObject(target) {
const type = typeof target;
return target !== null && (type === 'object' || type === 'function');
}
/**
* get type
* @param { any } target
*/
function getType(target) {
return Object.prototype.toString.call(target);
}
/**
* get init
* @param { any } target
*/
function getInit(target) {
const Ctor = target.constructor;
return new Ctor();
}
/**
* clone symbol
* @param { any } target
*/
function cloneSymbol(target) {
return Object(Symbol.prototype.valueOf.call(target));
}
/**
* clone reg
* @param { any } target
*/
function cloneReg(target) {
const reFlags = /\w*$/;
const result = new target.constructor(target.source, reFlags.exec(target));
result.lastIndex = target.lastIndex;
return result;
}
/**
* clone function
* @param { function } func
*/
function cloneFunction(func) {
const bodyReg = /(?<={)(.|\n)+(?=})/m;
const paramReg = /(?<=\().+(?=\)\s+{)/;
const funcString = func.toString();
if (func.prototype) {
const param = paramReg.exec(funcString);
const body = bodyReg.exec(funcString);
if (body) {
if (param) {
const paramArr = param[0].split(',');
return new Function(...paramArr, body[0]);
} else {
return new Function(body[0]);
}
} else {
return null;
}
} else {
return eval(funcString);
}
}
/**
* clone other type
* @param { any } target
* @param { any } type - data type
*/
function cloneOtherType(target, type) {
const Ctor = target.constructor;
switch (type) {
case boolTag:
case numberTag:
case stringTag:
case errorTag:
case dateTag:
return new Ctor(target);
case regexpTag:
return cloneReg(target);
case symbolTag:
return cloneSymbol(target);
case funcTag:
return cloneFunction(target);
default:
return null;
}
}
/**
* clone
* @param { any } target
* @param { map } map
*/
function clone(target, map = new WeakMap()) {
if (!isObject(target)) {
return target;
}
const type = getType(target);
let cloneTarget;
if (deepTag.includes(type)) {
cloneTarget = getInit(target, type);
} else {
return cloneOtherType(target, type);
}
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
if (type === setTag) {
target.forEach((value) => {
cloneTarget.add(clone(value, map));
});
return cloneTarget;
}
if (type === mapTag) {
target.forEach((value, key) => {
cloneTarget.set(key, clone(value, map));
});
return cloneTarget;
}
const keys = type === arrayTag ? undefined : Object.keys(target);
forEach(keys || target, (value, key) => {
if (keys) {
key = value;
}
cloneTarget[key] = clone(target[key], map);
});
return cloneTarget;
}
export default clone;

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 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: data storage
*/
import storage from '@ohos.data.storage';
import {PHONE_NUMBER} from '../constant/ImagePathConst.js';
const storageObj = storage.getStorageSync(PHONE_NUMBER);
/**
* set sync storage
* @param { string } key
* @param { string | number | boolean } value
*/
export function setSyncStorage(key, value) {
if (typeof value !== 'string') {
value = JSON.stringify(value);
}
storageObj.putSync(key, value);
storageObj.flushSync();
}
/**
* get sync storage
* @param { string } key
*/
export const getSyncStorage = (key) => storageObj.getSync(key, '');
/**
* get async storage
* @param { string } key
*/
export const getAsyncStorage = (key) => storageObj.get(key, '');
/**
* has sync storage
* @param { string } key
*/
export const hasSyncStorage = (key) => storageObj.hasSync(key);

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2021 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: Tools
*/
/**
* format phone number
* @param { string } phoneNumber
*/
export function formatPhoneNum(phoneNumber) {
if (/^1\d{10}$/.test(phoneNumber)) {
const str01 = phoneNumber.substring(0, 3);
const str02 = phoneNumber.substring(3, 7);
const str03 = phoneNumber.substring(7, 11);
return `${str01} ${str02} ${str03}`;
}
return phoneNumber;
}
// Carry when the time is greater than 9 seconds
const NINE_MAX = 9;
// Divide by 60 to get minutes and seconds
const SIXTY_SECONDS = 60;
/**
* format time
* @param { number } count
*/
export function formatTime(count) {
const second = count % SIXTY_SECONDS;
const minute = Math.floor(count / SIXTY_SECONDS) % SIXTY_SECONDS;
const hour = Math.floor(count / (SIXTY_SECONDS * SIXTY_SECONDS));
const secondStr = second <= NINE_MAX ? '0' + second : second;
const minuteStr = minute <= NINE_MAX ? '0' + minute : minute;
return hour > 0 ? `${hour}:${minuteStr}:${secondStr}` : `${minuteStr}:${secondStr}`;
}
/**
* debounce
* @param {Function} func
* @param {Number} delay
* @return function
*/
export function debounce(func, delay = 200) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}

View File

@ -0,0 +1,49 @@
{
"strings": {
"sms": "Message",
"remind": "Reminder",
"hangUpReply": "Respond with",
"backLater": "I'll call you back.",
"answerThePhone": "Sorry, I can't talk right now.",
"contactMeLater": "I'm in a meeting. I'll get back to you ASAP.",
"beThereSoon": "I'm on my way.",
"customSMS": "Custom...",
"cancel": "CANCEL",
"callBackReminder": "Callback reminder",
"minutes": "In 30 minutes",
"oneHourLater": "In 1 hour",
"twoHoursLater": "In 2 hours",
"dialing": "Dialing",
"calling": "calling",
"callHold": "Call hold",
"hangUpCompleted": "Hang up completed",
"hangingUp": "Hanging up",
"recording": "Record",
"keep": "Hold",
"addCall": "Add call",
"videoCall": "Video call",
"mute": "Mute",
"contactPerson": "Contacts",
"partyIsRinging": "Ringing",
"saveNumber": "Save number",
"addToBlacklist": "add to blacklist",
"shutDown": "shut down",
"speaker": "Speaker",
"phoneHandset": "Handset earpiece",
"mobileNetwork": "Unable to access the mobile network.",
"gotIt": "Got it",
"currentCall": "Current cal",
"hangUp": "hang up",
"handsFree": "Hands-free",
"incomingCall": "Incoming call",
"reject": "DECLINE",
"answer": "ANSWER",
"maintain": "On hold",
"exchange": "Swap",
"mergeCall": "Merge calls",
"manageUsers": "Manage users",
"telephoneConference": "Conference",
"unknownNumber": "Unknown number",
"noCard": "Can't access mobile network"
}
}

View File

@ -0,0 +1,49 @@
{
"strings": {
"sms": "短信",
"remind": "提醒",
"hangUpReply": "挂断并短信回复",
"backLater": "稍后给您回电话。",
"answerThePhone": "抱歉,现在不方便接电话。",
"contactMeLater": "正在开会,稍后联系。",
"beThereSoon": "稍等,马上到。",
"customSMS": "自定义短信",
"cancel": "取消",
"callBackReminder": "回拨提醒",
"minutes": "30分钟后",
"oneHourLater": "1小时后",
"twoHoursLater": "2小时后",
"dialing": "正在拨号",
"calling": "通话中",
"callHold": "保持",
"hangUpCompleted": "挂断完成",
"hangingUp": "正在挂断",
"recording": "录音",
"keep": "等待",
"addCall": "添加通话",
"videoCall": "视频通话",
"mute": "静音",
"contactPerson": "联系人",
"partyIsRinging": "对方已振铃",
"saveNumber": "保存号码",
"addToBlacklist": "加入黑名单",
"shutDown": "关闭",
"speaker": "扬声器",
"phoneHandset": "手机听筒",
"mobileNetwork": "无法访问移动网络。",
"gotIt": "知道了",
"currentCall": "当前通话",
"hangUp": "挂断",
"handsFree": "免提",
"incomingCall": "来电",
"reject": "拒接",
"answer": "接听",
"maintain": "保持",
"exchange": "交换",
"mergeCall": "合并通话",
"manageUsers": "管理用户",
"telephoneConference": "电话会议",
"unknownNumber": "未知号码",
"noCard": "无法访问移动网络"
}
}

View File

@ -0,0 +1,124 @@
/*
* Copyright (c) 2021 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: Call data management
*/
import CallStateManager from './callStateManager.js';
import {
CALL_STATUS_DIALING,
CALL_STATUS_ALERTING,
CALL_STATUS_DISCONNECTED,
CALL_STATUS_ACTIVE,
CALL_STATUS_WAITING
} from '../common/constant/callStateConst.js';
import app from '@system.app';
import {cancelNotification} from './sendNotification.js';
/**
* class CallDataManager
*/
export default class CallDataManager {
constructor(callData, callList, callTimeList) {
this.callData = callData;
this.callList = callList;
this.callTimeList = callTimeList;
this.callStateChange = (arg) => arg;
this.callStateManager = new CallStateManager(this.callData);
}
/**
* update callList and callData callTimeList
* @param { object } callData
*/
update(callData) {
const { callState, callId } = callData;
const targetObj = this.callList.find((v) => v.callId === callId);
if (targetObj) {
Object.assign(targetObj, {
...callData
});
} else {
this.addCallList({
...callData
});
}
if (callState === CALL_STATUS_ACTIVE) {
this.updateCallTimeList(callData);
}
const singleCallState = callState === CALL_STATUS_ACTIVE || callState === CALL_STATUS_WAITING || this.callList.length === 1;
const multiCallState = (callState === CALL_STATUS_DIALING || callState === CALL_STATUS_ALERTING) && this.callList.length > 1;
if (singleCallState || multiCallState) {
this.callStateManager.update(callData);
this.callStateChange(callState);
}
if (callState === CALL_STATUS_DISCONNECTED) {
if (this.callList.length === 1) {
cancelNotification();
app.terminate();
} else {
this.removeCallById(callId);
const activeCallData = this.callList.find((v) => v.callState === CALL_STATUS_ACTIVE);
if (activeCallData) {
this.callStateManager.update(activeCallData);
this.callStateChange(activeCallData);
} else if (this.callList[0]) {
this.callStateManager.update(this.callList[0]);
this.callStateChange(this.callList[0].callState);
}
}
}
}
/**
* addCallList
* @param { object } callData
*/
addCallList(callData) {
this.callList.push(callData);
}
/**
* remove call by call id
* @param { object } callId - call id
*/
removeCallById(callId) {
const index = this.callList.findIndex((v) => v.callId === callId);
this.callList.splice(index, 1);
if (this.callTimeList.find((v) => v.callId === callId)) {
this.callTimeList.splice(index, 1);
}
}
/**
* update callTimeList
* @param { object } callData
*/
updateCallTimeList(callData) {
const callTimeObj = this.callTimeList.find((v) => v.callId === callData.callId);
if (!callTimeObj && callData.callState === CALL_STATUS_ACTIVE) {
const obj = {
callId: callData.callId,
callTime: '00:00',
startTimestamp: callData.startTime || new Date().getTime(),
endTimestamp: 0,
};
this.callTimeList.push(obj);
}
}
}

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2021 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: Call management
*/
import CallDataManager from './callDataManager.js';
import {formatTime} from '../common/utils/utils.js';
import commonEvent from '@ohos.commonevent';
import featureAbility from '@ohos.ability.featureAbility';
import {publish} from './callServiceProxy.js';
let subscriber;
const TIMING = 1000;
const events = ['callui.event.callDetailsChange'];
/**
* class CallManager
*/
class CallManager {
constructor(ctx) {
this.callData = ctx.callData;
this.timer = null;
this.ctx = ctx;
this.callTimeList = ctx.callTimeList;
this.callDataManager = new CallDataManager(ctx.callData, ctx.callList, ctx.callTimeList);
this.openTimer(this.updateCallTimeList.bind(this));
this.sendNotificationHandle = (arg) => arg;
this.registerSubscriber();
this.initCallData();
}
initCallData() {
featureAbility.getWant().then((want) => {
if (want && want.parameters && ('callState' in want.parameters)) {
this.update(want.parameters);
} else {
publish({
key: 'getInitCallData',
params: []
});
}
}).catch((error) => {
console.error('Operation failed. Cause: ' + JSON.stringify(error));
});
}
async registerSubscriber() {
subscriber = await new Promise((resolve) => {
commonEvent.createSubscriber({events},
(err, data) => {
resolve(data);
}
);
});
commonEvent.subscribe(subscriber, (err, res) => {
if (err.code === 0) {
const callData = JSON.parse(res.data);
if (callData) {
this.update(callData);
}
} else {
console.error('callUI commonEvent.subscribe err: ' + JSON.stringify(err));
}
});
}
/**
* unsubscribe
*/
unsubscribe() {
commonEvent.unsubscribe(subscriber, (err) => {
if (err.code !== 0) {
console.error('callUI commonEvent.unsubscribe err: ' + JSON.stringify(err));
}
});
}
/**
* update callData callBack
* @param { Object } callData -Object
*/
update(callData) {
this.callDataManager.update(callData);
}
/**
* add callStateChange callBack
* @param { Function } callBack - Function
*/
addCallBack(callBack) {
this.callDataManager.callStateChange = callBack;
}
/**
* update call time list
*/
updateCallTimeList() {
this.callTimeList.forEach((item, i) => {
item.endTimestamp = new Date().getTime();
const diffSeconds = Math.floor((item.endTimestamp - item.startTimestamp) / TIMING);
item.callTime = formatTime(diffSeconds);
this.callTimeList.splice(i, 1, {
...item,
});
});
}
/**
* open timer
* @param { Function } callBack - add updateCallTimeList callBack
*/
openTimer(callBack) {
this.timer = setInterval(callBack, TIMING);
}
/**
* clear timer
*/
clearTimer() {
clearInterval(this.timer);
}
}
export default CallManager;

Some files were not shown because too many files have changed in this diff Show More