Signed-off-by: wangwei30043812 <wangwei1033@huawei.com>
This commit is contained in:
wangwei30043812
2023-05-29 16:14:32 +08:00
parent 874b59f4fc
commit f1e1f97e98
72 changed files with 4818 additions and 505 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
"app": {
"bundleName": "com.ohos.contacts",
"vendor": "example",
"versionCode": 10004024,
"versionName": "1.0.4.024",
"versionCode": 10004032,
"versionName": "1.0.4.032",
"icon": "$media:app_icon",
"label": "$string:app_name",
"distributedNotificationEnabled": true
+1 -1
View File
@@ -1,3 +1,3 @@
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
module.exports = require('@ohos/hvigor-ohos-plugin').HarTasks
module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
@@ -55,9 +55,16 @@ export default class StaticSubscriber extends StaticSubscriberExtensionAbility {
onReceiveEvent(event) {
HiLog.i(TAG, 'onReceiveEvent, event:' + JSON.stringify(event));
const missCallData = JSON.parse(JSON.stringify(event));
const parameters = JSON.parse(JSON.stringify(missCallData.parameters));
let updateMissedCallNotificationsMap: Map<string, string> = new Map();
MissedCallService.getInstance().init(this.context);
if ("usual.event.INCOMING_CALL_MISSED" == event.event) {
MissedCallService.getInstance().updateMissedCallNotifications();
if (parameters.countList != null) {
updateMissedCallNotificationsMap.set("missedPhoneJson", missCallData.parameters);
MissedCallService.getInstance().unreadCallNotification(updateMissedCallNotificationsMap);
}
} else if ("contact.event.CANCEL_MISSED" == event.event) {
if (event.parameters?.missedCallData) {
if ('notification.event.dialBack' == event.parameters?.action) {
@@ -63,7 +63,8 @@ export default struct ContactListItemView {
autoCancel: false,
alignment: (EnvironmentProp.isTablet() ? DialogAlignment.Center : DialogAlignment.Bottom),
offset: { dx: 0, dy: -16 },
gridCount: 4
gridCount: 4,
closeAnimation: { duration: 100 }
});
onDeleteClick() {
@@ -21,7 +21,7 @@ import { Birthday } from '../../../../../../../feature/contact/src/main/ets/cont
@CustomDialog
export struct ShowDayTime {
private date = new Date(2000, 0, 1);
private date = new Date(1970, 0, 31);
@Link mPresent: AccountantsPresenter;
@Prop itemIndex: number;
@Prop itemType: number;
@@ -29,6 +29,9 @@ import { StringUtil } from '../../../../../common/src/main/ets/util/StringUtil';
import { ArrayUtil } from '../../../../../common/src/main/ets/util/ArrayUtil';
import { CallLogRepository } from '../../../../../feature/call/src/main/ets/repo/CallLogRepository';
import { PhoneNumber } from '../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
import { FavoriteBean } from './bean/FavoriteBean';
import { CallLog } from '../../../../../feature/call/src/main/ets/entity/CallLog';
import { SearchContactsBean } from './bean/SearchContactsBean';
const TAG = "ContactAbility: ";
const PROFILE_CONTACT_DATA_URI = 'datashare:///com.ohos.contactsdataability/profile/contact_data';
@@ -595,13 +598,14 @@ export default {
*
* @param {string} DAHelper 数据库地址
* @param {Object} callBack 回调
* @param {Object} addParams Contact Information
*/
getAllContactWithPhoneNumbers: function (callBack, context?) {
getAllContactWithPhoneNumbers: function (callBack, addParams, context?) {
HiLog.i(TAG, 'Start to query all contacts with PhoneNumbers');
if (context) {
ContactRepository.getInstance().init(context);
}
ContactRepository.getInstance().findByPhoneIsNotNull(contactList => {
ContactRepository.getInstance().findByPhoneIsNotNull(addParams.favorite, addParams.editContact, contactList => {
if (ArrayUtil.isEmpty(contactList)) {
HiLog.i(TAG, 'getAllContactWithPhoneNumbers-SelectcontactsModel queryContact resultSet is empty!');
let emptyResult: ContactVo[] = [];
@@ -668,6 +672,7 @@ export default {
* @param {Object} actionData Contact data
*/
dealResult: function (dataItem: DataItem, contactDetailInfo) {
contactDetailInfo.favorite = dataItem.getFavorite();
switch (dataItem.getContentTypeId()) {
case DataItemType.NAME:
contactDetailInfo.display_name = dataItem.getData();
@@ -875,4 +880,252 @@ export default {
data_row.close();
HiLog.i(TAG, 'End to query contactID by phone number.');
},
/**
* Edit Contact Favorite
*
* @param {string} DAHelper
* @param {Object} addParams Contact Information
* @param {Object} callBack Contact ID
*/
updateFavorite: async function (DAHelper, addParams, callBack, context?) {
HiLog.i(TAG, 'updateFavorite start.');
if (DAHelper == undefined || DAHelper == null || DAHelper.length == 0) {
DAHelper = await dataShare.createDataShareHelper(context ? context : globalThis.context, Contacts.CONTENT_URI);
}
let condition = new dataSharePredicates.DataSharePredicates();
condition.equalTo('contact_id', addParams.id);
const va = {
'favorite': addParams.favorite,
}
DAHelper.update(
RawContacts.CONTENT_URI,
condition,
va
).then(data => {
if (data == -1) {
HiLog.e(TAG, 'updateFavorite data failed!');
}
HiLog.i(TAG, 'updateFavorite data success!');
callBack(addParams.favorite)
}).catch(err => {
HiLog.e(TAG, 'updateFavorite failed. Cause: ' + JSON.stringify(err.message));
});
HiLog.i(TAG, 'updateFavorite end.');
},
/**
* Querying the Mobile Numbers of All Favorites
*
* @param {string} DAHelper
* @param {Object} callBack
*/
getAllFavorite: async function (actionData, callBack, context?) {
HiLog.i(TAG, 'getAllFavorite start.');
if (context) {
ContactRepository.getInstance().init(context);
ContactRepository.getInstance().findAllFavorite(actionData, favoriteList => {
if (ArrayUtil.isEmpty(favoriteList)) {
let emptyResult: FavoriteBean[] = [];
callBack(emptyResult);
return;
}
let resultList = [];
for (let contactItem of favoriteList) {
let jsonObj: FavoriteBean = new FavoriteBean('', -1, '', '', '', '', '', true, '', false, 0, '');
jsonObj.contactId = contactItem.id.toString();
jsonObj.isCommonUseType = 0;
jsonObj.displayName = contactItem.displayName;
jsonObj.namePrefix = contactItem.sortFirstLetter;
jsonObj.nameSuffix = contactItem.photoFirstName;
jsonObj.position = contactItem.position;
jsonObj.portraitColor = MorandiColor.Color[Math.abs(parseInt(jsonObj.contactId)) % 6];
jsonObj.show = contactItem.show;
jsonObj.isUsuallyShow = false;
jsonObj.favorite = 1;
jsonObj.setShowName();
resultList.push(jsonObj);
}
HiLog.i(TAG, 'getAllFavorite data success!');
callBack(resultList);
});
}
HiLog.i(TAG, 'getAllFavorite end.');
},
/**
* Query call records
*
* @param {string} DAHelper
* @param {Object} callBack call records
*/
getAllUsually: async function (actionData, callBack, context?) {
HiLog.i(TAG, 'getAllUsually start.');
if (context) {
ContactRepository.getInstance().init(context);
ContactRepository.getInstance().findAllUsually(actionData, callLog => {
if (ArrayUtil.isEmpty(callLog)) {
let emptyResult: CallLog[] = [];
callBack(emptyResult);
return;
}
let resultList = [];
resultList = callLog;
HiLog.i(TAG, 'getAllUsually data success! ');
callBack(resultList);
});
}
HiLog.i(TAG, 'getAllUsually end.');
},
/**
* DisplayName Query Favorite
*
* @param {string} DAHelper
* @param {Object} addParams Contact Information
* @param {Object} callBack Contact Information
*/
getDisplayNamesFindUsually: async function (displayName, usuallyPhone, callBack, context?){
HiLog.i(TAG, 'getDisplayNamesFindUsually start.');
if (context) {
ContactRepository.getInstance().init(context);
ContactRepository.getInstance().getDisplayNameByFavorite(displayName, usuallyPhone, favoriteList => {
if (ArrayUtil.isEmpty(favoriteList)) {
let emptyResult: FavoriteBean[] = [];
callBack(emptyResult);
return;
}
let resultList = [];
for (let i = 0; i < favoriteList.length; i++) {
let jsonObj: FavoriteBean = new FavoriteBean('', -1, '', '', '', '', '', false, '', false, 0, '');
jsonObj.contactId = favoriteList[i].id.toString();
jsonObj.isCommonUseType = 1;
jsonObj.displayName = favoriteList[i].displayName;
jsonObj.namePrefix = favoriteList[i].sortFirstLetter;
jsonObj.nameSuffix = favoriteList[i].photoFirstName;
jsonObj.position = favoriteList[i].position;
jsonObj.portraitColor = MorandiColor.Color[Math.abs(parseInt(jsonObj.contactId)) % 6];
jsonObj.show = favoriteList[i].show;
jsonObj.isUsuallyShow = false;
jsonObj.favorite = 0;
jsonObj.phoneNum = favoriteList[i].detailInfo;
jsonObj.setShowName();
resultList.push(jsonObj);
}
HiLog.i(TAG, 'getDisplayNamesFindUsually sc.');
callBack(resultList);
})
}
HiLog.i(TAG, 'getDisplayNamesFindUsually end! ');
},
/**
* Move Favorite Data Sorting
*
* @param {string} DAHelper
* @param {Object} addParams Contact Information
* @param {Object} callBack favoriteOrder
*/
moveSortFavorite: async function (DAHelper, addParams, callBack, context?) {
HiLog.i(TAG, 'moveSortFavorite start.');
if (DAHelper == undefined || DAHelper == null || DAHelper.length == 0) {
DAHelper = await dataShare.createDataShareHelper(context ? context : globalThis.context, Contacts.CONTENT_URI);
}
let condition = new dataSharePredicates.DataSharePredicates();
condition.equalTo('contact_id', addParams.id);
const va = {
'favorite_order': addParams.favoriteOrder > 9 ? addParams.favoriteOrder : '0' + addParams.favoriteOrder
}
DAHelper.update(
RawContacts.CONTENT_URI,
condition,
va
).then(data => {
if (data == -1) {
HiLog.e(TAG, 'moveSortFavorite data failed!');
callBack('')
return;
}
HiLog.i(TAG, 'moveSortFavorite data success!');
callBack(addParams.favoriteOrder);
}).catch(err => {
HiLog.e(TAG, 'moveSortFavorite failed. Cause: ' + JSON.stringify(err.message));
});
HiLog.i(TAG, 'End to update moveSortFavorite.');
},
/**
* Querying the Mobile Numbers of Search Contacts
*
* @param {string} DAHelper
* @param {Object} callBack
*/
getSearchContact: async function (actionData, callBack, context?) {
HiLog.i(TAG, 'getSearchContact start.');
if (context) {
ContactRepository.getInstance().init(context);
}
ContactRepository.getInstance().searchContact(actionData, contactList => {
if (ArrayUtil.isEmpty(contactList)) {
HiLog.i(TAG, 'getSearchContact resultSet is empty!');
let emptyResult: SearchContactsBean[] = [];
callBack(emptyResult);
return;
}
let resultList = [];
for (let contactItem of contactList) {
let jsonObj: SearchContactsBean = new SearchContactsBean('', '', '', '', '', '', '', '', '', 0,'', '', '', '', '', '');
jsonObj.id = contactItem.id.toString();
jsonObj.accountId = contactItem.accountId;
jsonObj.contactId = contactItem.contactId;
jsonObj.rawContactId = contactItem.rawContactId;
jsonObj.searchName = contactItem.searchName;
jsonObj.displayName = contactItem.displayName;
jsonObj.phoneticName = contactItem.phoneticName;
jsonObj.photoId = contactItem.photoId;
jsonObj.photoFileId = contactItem.photoFileId;
jsonObj.isDeleted = contactItem.isDeleted;
jsonObj.position = contactItem.position;
jsonObj.sortFirstLetter = contactItem.sortFirstLetter;
jsonObj.photoFirstName = contactItem.photoFirstName;
jsonObj.portraitColor = MorandiColor.Color[Math.abs(parseInt(jsonObj.contactId)) % 6];
jsonObj.detailInfo = contactItem.detailInfo;
jsonObj.hasPhoneNumber = contactItem.hasPhoneNumber;
resultList.push(jsonObj);
}
callBack(resultList);
HiLog.i(TAG, 'getSearchContact end.');
});
},
getQueryT9PhoneNumbers: function (callBack, addParams, context?) {
if (context) {
ContactRepository.getInstance().init(context);
}
ContactRepository.getInstance().queryT9PhoneIsNotNull(addParams.favorite, contactList => {
if (ArrayUtil.isEmpty(contactList)) {
HiLog.i(TAG, 'getQueryT9PhoneNumbers queryContact resultSet is empty!');
let emptyResult: ContactVo[] = [];
callBack(emptyResult);
return;
}
let resultList = [];
for (let contactItem of contactList) {
let jsonObj: ContactVo = new ContactVo("", "", "", "", "", "", true, "", "");
jsonObj.contactId = contactItem.id.toString();
jsonObj.emptyNameData = contactItem.displayName;
jsonObj.namePrefix = contactItem.sortFirstLetter;
jsonObj.nameSuffix = contactItem.photoFirstName;
jsonObj.company = contactItem.company;
jsonObj.position = contactItem.position;
jsonObj.portraitColor = MorandiColor.Color[Math.abs(parseInt(jsonObj.contactId)) % 6];
jsonObj.show = false;
jsonObj.phoneNumbers = contactItem.phoneNumbers;
jsonObj.setShowName();
resultList.push(jsonObj);
}
callBack(resultList);
HiLog.i(TAG, 'End of querying all contacts');
});
},
}
@@ -37,11 +37,12 @@ export class ContactInfo {
relationships: AssociatedPersonBean[];
events: EventBean[];
groups: GroupBean[];
favorite: number;
constructor(id: string, display_name: string,
nickname: string, phones: PhoneNumBean[],
emails: EmailBean[], position: string, company: string, remarks: string,
aims: AIMBean[], houses: HouseBean[], websites: string[],
relationships: AssociatedPersonBean[], events: EventBean[], groups: GroupBean[]) {
relationships: AssociatedPersonBean[], events: EventBean[], groups: GroupBean[], favorite: number) {
this.id = id;
this.display_name = display_name;
this.nickname = nickname;
@@ -56,6 +57,7 @@ export class ContactInfo {
this.relationships = relationships;
this.events = events;
this.groups = groups;
this.favorite = favorite;
}
setID(id: string) {
@@ -0,0 +1,82 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
/**
* Favorite List Data Structure Entity
*/
export class FavoriteBean {
contactId: string;
/**
* 0 Favorite 1 Usually
*/
isCommonUseType: number;
/**
* Contact Name
*/
displayName: string;
phoneNum: string;
nameSuffix: string;
namePrefix: string;
portraitColor: string;
/**
* Display Usually
*/
isUsuallyShow: boolean;
portraitPath: string;
isEditSelect: boolean
favorite: number;
company: string;
position: string;
show: boolean;
showName: string;
phoneNumbers: object[];
title: string;
subTitle: string;
favoriteOrder: string;
constructor(
contactId: string,
isCommonUseType: number,
displayName: string,
phoneNum: string,
nameSuffix: string,
namePrefix: string,
portraitColor: string,
isUsuallyShow: boolean,
portraitPath: string,
isEditSelect: boolean,
favorite: number,
favoriteOrder: string,
) {
this.contactId = contactId;
this.isCommonUseType = isCommonUseType;
this.displayName = displayName;
this.phoneNum = phoneNum;
this.nameSuffix = nameSuffix;
this.namePrefix = namePrefix;
this.portraitColor = portraitColor;
this.isUsuallyShow = isUsuallyShow;
this.portraitPath = portraitPath;
this.isEditSelect = isEditSelect;
this.favorite = favorite;
this.favoriteOrder = favoriteOrder;
}
public setShowName() {
this.showName = !StringUtil.isEmpty(this.displayName) ? this.displayName : (!StringUtil.isEmpty(this.company) ? this.company : (!StringUtil.isEmpty(this.position) ? this.position : ""))
}
}
@@ -0,0 +1,58 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import BasicDataSource from './BasicDataSource';
import type { FavoriteBean } from '../bean/FavoriteBean';
import { FavoriteListBean } from '../bean/FavoriteListBean';
import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
import { ArrayUtil } from '../../../../../../common/src/main/ets/util/ArrayUtil';
const TAG = 'FavoriteDataSource ';
export default class FavoriteDataSource extends BasicDataSource {
private favoriteList: FavoriteBean[] = [];
public totalCount(): number {
return this.favoriteList.length;
}
public getFavoriteList(): FavoriteBean[] {
return this.favoriteList;
}
public getData(index: number): FavoriteListBean {
if (ArrayUtil.isEmpty(this.favoriteList) || index >= this.favoriteList.length) {
HiLog.i(TAG, 'getData contactlist is empty');
return null;
} else {
let favorite: FavoriteBean = this.favoriteList[index];
let preContact: FavoriteBean = this.favoriteList[index - 1];
let addContact: FavoriteBean = this.favoriteList[index + 1];
let showIndex: boolean = (index === 0 || !(favorite.namePrefix === preContact.namePrefix));
let showDivider: boolean = false;
if (index < this.favoriteList.length - 1) {
showDivider = !addContact.isUsuallyShow;
} else {
showDivider = false;
}
return new FavoriteListBean(index, showIndex, showDivider, favorite, null);
}
}
public refresh(favoriteList: FavoriteBean[]): void {
HiLog.i(TAG, 'refresh!');
this.favoriteList = favoriteList;
this.notifyDataReload();
}
}
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FavoriteBean } from './FavoriteBean';
import { SearchContactsBean } from './SearchContactsBean';
export class FavoriteListBean {
index: number;
showIndex: boolean;
showDivider: boolean;
favorite: FavoriteBean;
contact: SearchContactsBean;
constructor(index: number, showIndex: boolean, showDivider: boolean, favorite: FavoriteBean, contact: SearchContactsBean) {
this.index = index;
this.showIndex = showIndex;
this.showDivider = showDivider;
this.favorite = favorite;
this.contact = contact;
}
}
@@ -0,0 +1,74 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* SearchContactsBean List Data Structure Entity
*/
export class SearchContactsBean {
id: string;
accountId: string;
contactId: string;
rawContactId: string;
searchName: string;
displayName: string;
phoneticName: string;
photoId: string;
photoFileId: string;
isDeleted: number;
position: string;
photoFirstName: string;
sortFirstLetter: string;
portraitColor: string;
portraitPath: string;
detailInfo: string;
hasPhoneNumber: string;
constructor(
id: string,
accountId: string,
contactId: string,
rawContactId: string,
searchName: string,
displayName: string,
phoneticName: string,
photoId: string,
photoFileId: string,
isDeleted: number,
position: string,
photoFirstName: string,
sortFirstLetter: string,
portraitColor: string,
detailInfo: string,
hasPhoneNumber: string,
) {
this.id = id;
this.accountId = accountId;
this.contactId = contactId;
this.rawContactId = rawContactId;
this.searchName = searchName;
this.displayName = displayName;
this.phoneticName = phoneticName;
this.photoId = photoId;
this.photoFileId = photoFileId;
this.isDeleted = isDeleted;
this.position = position;
this.photoFirstName = photoFirstName;
this.sortFirstLetter = sortFirstLetter;
this.portraitColor = portraitColor;
this.detailInfo = detailInfo;
this.detailInfo = hasPhoneNumber;
}
}
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SearchContactsBean } from '../bean/SearchContactsBean';
import { FavoriteListBean } from '../bean/FavoriteListBean';
import BasicDataSource from './BasicDataSource';
import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
import { ArrayUtil } from '../../../../../../common/src/main/ets/util/ArrayUtil';
const TAG = 'SearchContactsSource ';
export default class SearchContactsSource extends BasicDataSource {
private contactList: SearchContactsBean[] = [];
public contactObj: { [key: string]: SearchContactsBean[] } = {};
public contactIndexObj: { [key: string]: number } = {};
public totalCount(): number {
return this.contactList.length;
}
public getData(index: number): FavoriteListBean {
if (ArrayUtil.isEmpty(this.contactList) || index >= this.contactList.length) {
HiLog.i(TAG, 'getData contactlist is empty');
return null;
} else {
let contact: SearchContactsBean = this.contactList[index];
let preContact: SearchContactsBean = this.contactList[index - 1];
let showIndex: boolean = (index === 0 || !(contact.sortFirstLetter === preContact.sortFirstLetter));
let showDivider: boolean = false;
if (index < this.contactList.length - 1) {
let nextContact: SearchContactsBean = this.contactList[index + 1];
showDivider = (contact.sortFirstLetter === nextContact.sortFirstLetter);
} else {
showDivider = false;
}
return new FavoriteListBean(index, showIndex, showDivider, null, contact);
}
}
public refresh(contactList: SearchContactsBean[]): void {
HiLog.i(TAG, ' refresh!');
this.contactList = contactList;
this.notifyDataReload();
}
}
@@ -29,12 +29,12 @@ export default {
* @param {string} mergeRule Call Record Type
* @param {Object} callBack Call log data
*/
getAllCalls: async function (actionData, mergeRule, callBack, context?) {
getAllCalls: async function (param, actionData, mergeRule, callBack, context?) {
if (context) {
CallLogRepository.getInstance().init(context);
}
HiLog.i(TAG, 'getAllCalls in:' + JSON.stringify(actionData));
CallLogRepository.getInstance().findAll(actionData, result => {
CallLogRepository.getInstance().findAll(param.favorite, actionData, result => {
let resultData = {
callLogList: [], missedList: []
};
@@ -106,5 +106,30 @@ export default {
missed.displayName = "";
}
}
},
getCallHistorySearch: async function (actionData, mergeRule, callBack, context?) {
if (context) {
CallLogRepository.getInstance().init(context);
}
CallLogRepository.getInstance().findSearch(actionData, result => {
HiLog.i(TAG, 'getCallHistorySearch resultSet.rowCount :' + JSON.stringify(result.rowCount));
let resultData = {
callLogList: [], missedList: []
};
if (ArrayUtil.isEmpty(result)) {
HiLog.i(TAG, 'getCallHistorySearch logMessage callLog resultSet is empty!');
callBack(resultData);
return;
}
CallLogService.getInstance().init(context);
CallLogService.getInstance().setMergeRule(mergeRule)
resultData.callLogList = CallLogService.getInstance().mergeCallLogs(result);
resultData.missedList = CallLogService.getInstance().mergeMissedCalls(result);
let numberList = this.getNumberList(resultData);
this.queryContactsName(numberList, resultData, resultData => {
callBack(resultData);
}, context)
});
}
}
+159 -76
View File
@@ -19,8 +19,12 @@ import { HiLog, ArrayUtil } from '../../../../../../common';
import emitter from '@ohos.events.emitter';
import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
import Constants from '../../../../../../common/src/main/ets/Constants';
import { ContactSearch } from './search/ContactSearch';
import { AlphabetIndexerPage } from './alphabetindex/AlphabetIndexerPage';
import AlphabetIndexerPresenter from '../../presenter/contact/alphabetindex/AlphabetIndexerPresenter';
const TAG = 'ContactList ';
const EMITTER_SEARCH_ID: number = 105;
let storage = LocalStorage.GetShared();
/**
@@ -49,6 +53,13 @@ export default struct ContactListPage {
this.refresh()
})
this.refresh();
let innerEventSearch = {
eventId: EMITTER_SEARCH_ID,
priority: emitter.EventPriority.HIGH
};
emitter.on(innerEventSearch, (data) => {
this.mContactPresenter.isSearchPage = data.data['isSearchPage'];
})
}
aboutToDisappear() {
@@ -103,6 +114,12 @@ struct ContactContent {
@Link private presenter: ContactListPresenter;
@Link private contactListListLen: number;
@LocalStorageProp('breakpoint') curBp: string = 'sm';
private scroller: Scroller = new Scroller();
@State alphabetSelected: number = 0;
@State isAlphabetClicked: boolean = false;
@State dragList: boolean = true;
@State alphabetIndexPresenter: AlphabetIndexerPresenter = this.presenter.alphabetIndexPresenter;
@State type: number = 0;
@Builder
GroupsView(imageRes: Resource, title: string | Resource, showArrow: boolean) {
@@ -135,88 +152,154 @@ struct ContactContent {
}
build() {
Column() {
GridRow({columns: {sm: 4, md: 8, lg: 12}, gutter: {x: 12, y: 0}}) {
GridCol({span: {sm: 4, md:6, lg: 8}, offset: {sm: 0, md: 1, lg: 2}}) {
TitleGuide()
}
GridCol({span: {sm: 4, md:6, lg: 8}, offset: {sm: 0, md: 2, lg: 4}}) {
Column() {
Text($r("app.string.contact"))
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor($r("sys.color.ohos_id_color_text_primary"))
.margin({bottom: $r("app.float.id_card_margin_sm")} )
.lineHeight(42)
.margin({top:8, bottom: 2})
Text($r("app.string.contact_num", this.contactListListLen))
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Regular)
.fontColor($r("sys.color.ohos_id_color_text_tertiary"))
.lineHeight(19)
}
.alignItems(HorizontalAlign.Start)
.width('100%')
.height(82)
}
}
GridRow({columns: {sm: 4, md: 8, lg: 12}, gutter: {x: 12, y: 0}}) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ space: 0, initialIndex: 0 }) {
LazyForEach(this.presenter.contactListDataSource, (item, index: number) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex && !StringUtil.isEmpty(item.contact.namePrefix)) {
Row() {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
}
.alignItems(VerticalAlign.Bottom)
.direction(Direction.Ltr)
.padding({ left: this.curBp === 'lg' ? $r("app.float.id_card_margin_max") : 0,
bottom: $r("app.float.id_card_margin_large")})
.height($r("app.float.id_item_height_mid"))
}
ContactListItemView({
item: item.contact,
index: index,
showIndex: item.showIndex,
showDivifer: item.showDivifer
})
}
.alignItems(HorizontalAlign.Start)
if (item.showDivifer) {
Divider()
.color($r("sys.color.ohos_id_color_list_separator"))
.margin({right: this.curBp === 'lg' ? 24 : 0,
left: this.curBp === 'lg' ? 76 : 52
})
}
}
Stack({ alignContent: Alignment.TopStart }) {
Stack({ alignContent: Alignment.TopEnd }) {
Column() {
Stack({ alignContent: Alignment.Top }) {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
TitleGuide()
}
}, (item) => JSON.stringify(item))
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 2, lg: 4 } }) {
Column() {
Text($r("app.string.contact"))
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor($r("sys.color.ohos_id_color_text_primary"))
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.lineHeight(42)
.margin({ top: 8, bottom: 2 })
Text($r("app.string.contact_num", this.contactListListLen))
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontWeight(FontWeight.Regular)
.fontColor($r("sys.color.ohos_id_color_text_tertiary"))
.lineHeight(19)
Stack({ alignContent: Alignment.Bottom }) {
TextInput({ placeholder: $r('app.string.contact_list_search') })
.placeholderColor(Color.Grey)
.placeholderFont({
size: $r('sys.float.ohos_id_text_size_headline9'),
weight: FontWeight.Normal,
style: FontStyle.Normal
})
.type(InputType.Normal)
.caretColor($r('sys.color.ohos_id_color_text_primary_activated'))
.enterKeyType(EnterKeyType.Search)
.padding({ left: $r('app.float.id_card_margin_xxxxl') })
.height($r("app.float.id_item_height_mid"))
.enabled(false)
.border({
color: $r("sys.color.ohos_id_color_fourth"),
radius: $r('app.float.id_card_margin_max')
})
Column(){
Image($r('app.media.ic_public_search'))
.width($r('app.float.id_card_margin_xxxl'))
.height($r('app.float.id_card_margin_xxxl'))
.objectFit(ImageFit.Contain)
.margin({ left: $r('app.float.id_card_margin_large') })
}
.width('100%')
.margin({ bottom: $r('app.float.id_corner_radius_card_mid') })
.alignItems(HorizontalAlign.Start)
}
.onClick(() => {
this.presenter.isSearchPage = true;
this.presenter.sendEmitter(this.presenter.isSearchPage);
this.presenter.inputKeyword = '';
})
.margin({ top: $r('app.float.dialer_common_very_small_margin2') })
.width('100%')
}
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Start)
.width('100%')
}
}
}
.visibility(this.presenter.isSearchPage ? Visibility.None : Visibility.Visible)
.padding({ bottom: $r('app.float.id_card_margin_large') })
// .height(180)
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ space: 0, initialIndex: 0, scroller: this.scroller }) {
LazyForEach(this.presenter.contactListDataSource, (item, index: number) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex && !StringUtil.isEmpty(item.contact.namePrefix)) {
Row() {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
}
.alignItems(VerticalAlign.Bottom)
.direction(Direction.Ltr)
.padding({ left: this.curBp === 'lg' ? $r("app.float.id_card_margin_max") : 0,
bottom: $r("app.float.id_card_margin_large") })
.height($r("app.float.id_item_height_mid"))
}
ContactListItemView({
item: item.contact,
index: index,
showIndex: item.showIndex,
showDivifer: item.showDivifer
})
}
.alignItems(HorizontalAlign.Start)
if (item.showDivifer) {
Divider()
.color($r("sys.color.ohos_id_color_list_separator"))
.margin({ right: this.curBp === 'lg' ? 24 : 0,
left: this.curBp === 'lg' ? 76 : 52
})
}
}
}
}, (item) => JSON.stringify(item))
}
.width('100%')
.height('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.None)
.scrollBar(BarState.Off)
.onScrollIndex((firstIndex: number, lastIndex: number) => {
if (!this.isAlphabetClicked) {
this.alphabetSelected = this.alphabetIndexPresenter.getAlphabetSelected(firstIndex);
}
})
.onScrollStart(() => {
this.dragList = true;
})
.onScrollStop(() => {
this.isAlphabetClicked = false;
})
}
}
.width('100%')
.height('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.None)
.scrollBar(BarState.Off)
.flexShrink(1)
}
.padding({ left: 24, right: 24 })
.height("100%")
.width("100%")
ContactSearch({ presenter: $presenter, type: $type })
.visibility(this.presenter.isSearchPage ? Visibility.Visible : Visibility.None)
AlphabetIndexerPage({scroller: this.scroller, presenter: $alphabetIndexPresenter, selected: this.alphabetSelected,
isClicked: $isAlphabetClicked, drag: $dragList})
.margin({top: '30%', bottom: '10%'})
}
.height('100%')
.flexShrink(1)
}
.padding({left:24, right:24})
.height("100%")
.width("100%")
}
}
@@ -76,7 +76,17 @@ struct Accountants {
//Components shared by the TIP for creating or updating a contact by mistake and the TIP for deleting a contact
builder: DeleteDialogEx({
cancel: () => {
router.back();
if (0 === this.mPresenter.editContact){
router.replaceUrl({
url: 'pages/contacts/details/ContactDetail',
params: {
sourceHasPhone: true,
phoneNumberShow: this.mPresenter.phoneNumberShow
}
})
} else {
router.back();
}
},
confirm: () => {
this.mPresenter.saveContact();
@@ -132,6 +142,10 @@ struct Accountants {
let obj: any = router.getParams();
this.mPresenter.contactId = obj.contactId;
this.mPresenter.updateShow = true;
this.mPresenter.phones = obj.phones;
this.mPresenter.editContact = obj.editContact;
this.mPresenter.phoneNumberShow = obj.phoneNumberShow;
this.mPresenter.callId = obj.callId;
this.mPresenter.updatesInit();
}
}
@@ -0,0 +1,61 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import AlphabetIndexerPresenter from '../../../presenter/contact/alphabetindex/AlphabetIndexerPresenter';
@Component
export struct AlphabetIndexerPage {
scroller: Scroller;
@Link presenter: AlphabetIndexerPresenter;
private selectedAlphabetIndex: number = 0;
private popDataSource: string[] = [];
@Prop selected: number;
@Link isClicked: boolean;
@Link drag: boolean;
build() {
Column() {
AlphabetIndexer({ arrayValue: this.presenter.alphabetIndexList, selected: this.selected })
.selectedColor(0x1358e4)
.popupColor(0x0254f6)
.selectedBackgroundColor(0xe7eefe)
.popupBackground(0xf3f3f3)
.usingPopup(this.drag ? false : true)
.selectedFont({ size: 16 })
.popupFont({ size: 24 })
.itemSize(20)
.alignStyle(IndexerAlign.Right)
.onSelect((index: number) => {
this.drag = false;
this.isClicked = true;
this.selectedAlphabetIndex = index;
let scrollIndex = this.presenter.getListScrollIndex(this.selectedAlphabetIndex);
this.scroller.scrollToIndex(scrollIndex);
// Set the click status of the index bar, otherwise there will be issues with the list scroll
setTimeout(() => {
this.isClicked = false;
}, 200);
})
.onRequestPopupData((index: number) => {
this.popDataSource = this.presenter.getAlphabetPopData(index).slice();
return this.popDataSource;
})
.onPopupSelect((index: number) => {
let scrollIndex = this.presenter.getListScrollIndex(this.selectedAlphabetIndex, this.popDataSource, index);
this.scroller.scrollToIndex(scrollIndex);
})
}
}
}
@@ -19,6 +19,9 @@ import { ArrayUtil } from '../../../../../../../common/src/main/ets/util/ArrayUt
import BatchSelectRecentItemView from '../../../component/contact/batchselectcontacts/BatchSelectRecentItemView';
import BatchSelectContactItemView from '../../../component/contact/batchselectcontacts/BatchSelectContactItemView';
import BatchTabGuide from '../../../component/contact/batchselectcontacts/BatchTabGuide';
import router from '@ohos.router';
import AlphabetIndexerPresenter from '../../../presenter/contact/alphabetindex/AlphabetIndexerPresenter';
import { AlphabetIndexerPage } from '../alphabetindex/AlphabetIndexerPage';
const TAG = 'BatchSelectContactsPage ';
@@ -35,6 +38,8 @@ export default struct BatchSelectContactsPage {
aboutToAppear() {
HiLog.i(TAG, 'aboutToAppear')
let obj: any = router.getParams();
this.mPresenter.addFavorite = obj?.addFavorite;
this.mPresenter.aboutToAppear()
}
@@ -55,7 +60,7 @@ export default struct BatchSelectContactsPage {
onBackPress() {
HiLog.i(TAG, 'onBackPress')
this.mPresenter.cancel();
this.mPresenter.backCancel();
return true;
}
@@ -74,7 +79,7 @@ export default struct BatchSelectContactsPage {
.flexShrink(0)
.margin({ left: $r("app.float.id_card_margin_max"), right: $r("app.float.id_card_margin_xxl") })
.onClick(() => {
this.mPresenter.cancel()
this.mPresenter.backCancel();
})
Text(this.mPresenter.selectCount == 0 ? $r('app.string.no_select') : $r('app.string.select_num', this.mPresenter.selectCount))
@@ -93,7 +98,8 @@ export default struct BatchSelectContactsPage {
.enabled(!this.mPresenter.selectDisabled)
.fillColor(this.mPresenter.selectDisabled ? $r("sys.color.ohos_id_color_tertiary") : $r("sys.color.ohos_id_color_primary"))
.onClick(() => {
this.mPresenter.comfirm()
this.mPresenter.selectBatchContact();
this.mPresenter.contactsList = [];
})
if (this.curBp === 'lg') {
@@ -221,6 +227,7 @@ struct RecentList {
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
}
.height('100%')
.width('100%')
.backgroundColor(Color.White)
.padding({ top: $r("app.float.id_card_margin_mid"), bottom: $r("app.float.id_card_margin_mid") })
@@ -231,54 +238,74 @@ struct RecentList {
@Component
struct ContactsList {
@Link presenter: BatchSelectContactsPresenter;
private scroller: Scroller = new Scroller();
@State alphabetSelected: number = 0;
@State isAlphabetClicked: boolean = false;
@State dragList: boolean = true;
@State alphabetIndexPresenter: AlphabetIndexerPresenter = this.presenter.alphabetIndexPresenter;
build() {
Column() {
List({ initialIndex: this.presenter.initialIndex }) {
LazyForEach(this.presenter.contactsSource, (item, index) => {
Stack({ alignContent: Alignment.TopEnd }) {
List({ initialIndex: this.presenter.initialIndex, scroller: this.scroller }) {
LazyForEach(this.presenter.contactsSource, (item, index) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex) {
Flex({ direction: FlexDirection.Column,
justifyContent: FlexAlign.End,
alignItems: ItemAlign.Start }) {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex) {
Flex({ direction: FlexDirection.Column,
justifyContent: FlexAlign.End,
alignItems: ItemAlign.Start }) {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
}
.padding({ left: $r("app.float.id_card_margin_max"), bottom: $r("app.float.id_card_margin_large") })
.width('100%')
.height($r("app.float.id_item_height_mid"))
}
.padding({ left: $r("app.float.id_card_margin_max"), bottom: $r("app.float.id_card_margin_large") })
.width('100%')
.height($r("app.float.id_item_height_mid"))
BatchSelectContactItemView({
item: item.contact,
index: item.index,
onContactItemClicked: (index, indexChild) => this.presenter.onContactItemClicked(index, indexChild),
showIndex: item.showIndex,
showDivifer: item.showDivifer
})
}
BatchSelectContactItemView({
item: item.contact,
index: item.index,
onContactItemClicked: (index, indexChild) => this.presenter.onContactItemClicked(index, indexChild),
showIndex: item.showIndex,
showDivifer: item.showDivifer
})
}
if (item.showDivifer) {
Divider()
.color($r("sys.color.ohos_id_color_list_separator"))
.margin({ left: 76, right: $r("app.float.id_card_margin_max") })
if (item.showDivifer) {
Divider()
.color($r("sys.color.ohos_id_color_list_separator"))
.margin({ left: 76, right: $r("app.float.id_card_margin_max") })
}
}
}
}, (item) => JSON.stringify(item))
}
.width('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.scrollBar(BarState.Off)
.onScrollIndex((firstIndex: number, lastIndex: number) => {
this.presenter.resetInitialIndex(firstIndex);
if (!this.isAlphabetClicked) {
this.alphabetSelected = this.alphabetIndexPresenter.getAlphabetSelected(firstIndex);
}
}, (item) => JSON.stringify(item))
})
.onScrollStart(() => {
this.dragList = true;
})
.onScrollStop(() => {
this.isAlphabetClicked = false;
})
AlphabetIndexerPage({scroller: this.scroller, presenter: $alphabetIndexPresenter, selected: this.alphabetSelected,
isClicked: $isAlphabetClicked, drag: $dragList})
.margin({ top: '10%', bottom: '10%' })
}
.width('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((firstIndex: number, lastIndex: number) => {
this.presenter.resetInitialIndex(firstIndex);
})
}
.width('100%')
.padding({ top: $r("app.float.id_card_margin_mid"), bottom: $r("app.float.id_card_margin_mid") })
@@ -13,10 +13,13 @@
* limitations under the License.
*/
import router from '@ohos.router';
import BatchSelectContactsPresenter from '../../../presenter/contact/batchselectcontacts/BatchSelectContactsPresenter';
import { HiLog } from '../../../../../../../common/src/main/ets/util/HiLog';
import { ArrayUtil } from '../../../../../../../common/src/main/ets/util/ArrayUtil';
import BatchSelectContactItemView from '../../../component/contact/batchselectcontacts/BatchSelectContactItemView';
import { AlphabetIndexerPage } from '../alphabetindex/AlphabetIndexerPage';
import AlphabetIndexerPresenter from '../../../presenter/contact/alphabetindex/AlphabetIndexerPresenter';
const TAG = 'BatchSelectContactsPage ';
@@ -32,6 +35,12 @@ export default struct SingleSelectContactPage {
aboutToAppear() {
HiLog.i(TAG, 'aboutToAppear')
let obj: any = router.getParams();
this.mPresenter.editContact = obj?.editContact;
this.mPresenter.contactId = obj?.contactId;
this.mPresenter.callId = obj?.callId;
this.mPresenter.phones = obj?.phones;
this.mPresenter.phoneNumberShow = obj?.phoneNumberShow;
this.mPresenter.aboutToAppear()
}
@@ -52,7 +61,7 @@ export default struct SingleSelectContactPage {
onBackPress() {
HiLog.i(TAG, 'onBackPress')
this.mPresenter.cancel();
this.mPresenter.singleBackCancel();
return true;
}
@@ -85,7 +94,7 @@ struct TitleGuide {
.flexShrink(0)
.margin({ left: $r("app.float.id_card_margin_max"), right: $r("app.float.id_card_margin_xxl") })
.onClick(() => {
this.mPresenter.cancel()
this.mPresenter.singleBackCancel();
})
Text($r('app.string.select_contact'))
@@ -106,60 +115,80 @@ struct TitleGuide {
struct ContactsList {
@Link private presenter: BatchSelectContactsPresenter;
@LocalStorageProp('breakpoint') curBp: string = 'sm';
private scroller: Scroller = new Scroller();
@State alphabetSelected: number = 0;
@State isAlphabetClicked: boolean = false;
@State dragList: boolean = true;
@State alphabetIndexPresenter: AlphabetIndexerPresenter = this.presenter.alphabetIndexPresenter;
build() {
Column() {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: { sm: 12, md: 12, lg: 24 }, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
TitleGuide()
}
}
.height("100%")
.onBreakpointChange((breakpoint: string) => {
this.curBp = breakpoint
})
GridRow({columns: {sm: 4, md: 8, lg: 12}, gutter: {x: 12, y: 0}}) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ initialIndex: this.presenter.initialIndex }) {
LazyForEach(this.presenter.contactsSource, (item, index) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex) {
Column() {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
}
.alignItems(HorizontalAlign.Start)
.padding({ left: $r("app.float.id_card_margin_max"), bottom: $r("app.float.id_card_margin_large") })
.width('100%')
.height($r("app.float.id_item_height_mid"))
}
}
BatchSelectContactItemView({
single: item.single = true,
item: item.contact,
index: item.index,
onSingleContactItemClick: (num, name) => this.presenter.onSingleContactItemClick(num, name),
showIndex: item.showIndex,
})
}
}
}, (item) => JSON.stringify(item))
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: { sm: 12, md: 12, lg: 24 }, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
TitleGuide()
}
.scrollBar(BarState.Off)
.width('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((firstIndex: number, lastIndex: number) => {
this.presenter.resetInitialIndex(firstIndex);
})
}
.height("100%")
.onBreakpointChange((breakpoint: string) => {
this.curBp = breakpoint
})
Stack({ alignContent: Alignment.TopEnd }) {
GridRow({columns: {sm: 4, md: 8, lg: 12}, gutter: {x: 12, y: 0}}) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ initialIndex: this.presenter.initialIndex, scroller: this.scroller }) {
LazyForEach(this.presenter.contactsSource, (item, index) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (item.showIndex) {
Column() {
Text(item.contact.namePrefix)
.fontColor($r("sys.color.ohos_fa_text_secondary"))
.fontSize($r("sys.float.ohos_id_text_size_sub_title3"))
.fontWeight(FontWeight.Medium)
.textAlign(TextAlign.Start)
}
.alignItems(HorizontalAlign.Start)
.padding({ left: $r("app.float.id_card_margin_max"), bottom: $r("app.float.id_card_margin_large") })
.width('100%')
.height($r("app.float.id_item_height_mid"))
}
}
BatchSelectContactItemView({
single: item.single = true,
item: item.contact,
index: item.index,
onSingleContactItemClick: (num, name) => this.presenter.onSingleContactItemClick(num, name, item.contact),
showIndex: item.showIndex,
})
}
}
}, (item) => JSON.stringify(item))
}
.scrollBar(BarState.Off)
.width('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.onScrollIndex((firstIndex: number, lastIndex: number) => {
this.presenter.resetInitialIndex(firstIndex);
if (!this.isAlphabetClicked) {
this.alphabetSelected = this.alphabetIndexPresenter.getAlphabetSelected(firstIndex);
}
})
.onScrollStart(() => {
this.dragList = true;
})
.onScrollStop(() => {
this.isAlphabetClicked = false;
})
}
}
.height('93%')
AlphabetIndexerPage({scroller: this.scroller, presenter: $alphabetIndexPresenter, selected: this.alphabetSelected,
isClicked: $isAlphabetClicked, drag: $dragList})
.margin({ top: '10%', bottom: '10%' })
}
.height('100%')
.flexShrink(1)
@@ -35,6 +35,7 @@ let storage = LocalStorage.GetShared()
struct ContactDetail {
@State mPresenter: DetailPresenter = DetailPresenter.getInstance();
@LocalStorageProp('breakpoint') curBp: string = 'sm';
@StorageLink("params") params: { [key: string]: any } = {};
@State private mMoreMenu: Array<{
value: string,
action: () => void
@@ -69,14 +70,17 @@ struct ContactDetail {
this.isShow++;
}, 100);
let obj: any = router.getParams();
if (!obj) {
HiLog.i(TAG, "params is Miss or error!")
return;
if (obj != undefined) {
this.mPresenter.sourceHasId = obj.sourceHasId;
this.mPresenter.contactId = obj.contactId;
this.mPresenter.sourceHasPhone = obj.sourceHasPhone;
this.mPresenter.phoneNumberShow = obj.phoneNumberShow;
} else if (this.params != {}) {
this.mPresenter.sourceHasId = this.params.sourceHasId;
this.mPresenter.contactId = this.params.contactId;
this.mPresenter.sourceHasPhone = this.params.sourceHasPhone;
this.mPresenter.phoneNumberShow = this.params.phoneNumberShow;
}
this.mPresenter.sourceHasId = obj.sourceHasId;
this.mPresenter.contactId = obj.contactId;
this.mPresenter.sourceHasPhone = obj.sourceHasPhone;
this.mPresenter.phoneNumberShow = obj.phoneNumberShow;
this.mPresenter.aboutToAppear();
this.mMoreMenu = this.mPresenter.getSettingsMenus();
let that = this;
@@ -150,6 +154,28 @@ struct ContactDetail {
if (this.curBp !== 'lg') {
Row() {
Column() {
Image('1' === this.mPresenter.isFavorited ? $r('app.media.ic_public_collected') : $r('app.media.ic_public_collect'))
.objectFit(ImageFit.Contain)
.height($r("app.float.id_card_image_small"))
.width($r("app.float.id_card_image_small"))
.margin({ bottom: 3 })
Text('1' === this.mPresenter.isFavorited ? $r('app.string.cancel_favorite') : $r('app.string.favorite'))
.fontSize($r('sys.float.ohos_id_text_size_caption'))
.fontWeight(FontWeight.Medium)
.fontColor($r('sys.color.ohos_id_color_toolbar_text'))
}
.onClick(() => {
if ('0' === this.mPresenter.isFavorited) {
this.mPresenter.isFavorited = '1';
} else {
this.mPresenter.isFavorited = '0';
}
this.mPresenter.updateFavorite(parseInt(this.mPresenter.isFavorited));
})
.visibility(this.mPresenter.contactId != undefined ? Visibility.Visible : Visibility.None)
.width('33%')
Column() {
Image(this.mPresenter.contactId != undefined
? $r("app.media.ic_public_edit")
@@ -168,10 +194,27 @@ struct ContactDetail {
.onClick(() => {
this.mPresenter.updateContact();
})
.width(this.mPresenter.contactId != undefined ? '50%' : '100%')
.width(this.mPresenter.contactId != undefined ? '33%' : '50%')
Column() {
Image($r("app.media.ic_public_more"))
Image($r('app.media.ic_public_contacts_group'))
.objectFit(ImageFit.Contain)
.height($r('app.float.id_card_image_small'))
.width($r('app.float.id_card_image_small'))
.margin({ bottom: 3 })
Text($r('app.string.save_to_existing_contacts'))
.fontSize($r('sys.float.ohos_id_text_size_caption'))
.fontWeight(FontWeight.Medium)
.fontColor($r('sys.color.ohos_id_color_toolbar_text'))
}
.onClick(() => {
this.mPresenter.saveExistingContact()
})
.visibility(this.mPresenter.contactId != undefined ? Visibility.None : Visibility.Visible)
.width('50%')
Column() {
Image($r('app.media.ic_public_more'))
.objectFit(ImageFit.Contain)
.height($r("app.float.id_card_image_small"))
.width($r("app.float.id_card_image_small"))
@@ -183,7 +226,7 @@ struct ContactDetail {
.fontColor($r("sys.color.ohos_id_color_toolbar_text"))
}
.visibility(this.mPresenter.contactId != undefined ? Visibility.Visible : Visibility.None)
.width('50%')
.width('33%')
}
.alignItems(VerticalAlign.Center)
.height($r("app.float.id_item_height_large"))
@@ -0,0 +1,325 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import ContactListPresenter from '../../../presenter/contact/ContactListPresenter';
import { StringUtil } from '../../../../../../../common/';
import emitter from '@ohos.events.emitter';
import BatchSelectContactsPresenter from '../../../presenter/contact/batchselectcontacts/BatchSelectContactsPresenter';
import router from '@ohos.router';
const TAG = 'ContactSearch ';
@Component
export struct ContactSearch {
@State batchSelectContactsPresenter: BatchSelectContactsPresenter = BatchSelectContactsPresenter.getInstance();
@Link presenter: ContactListPresenter;
@Link type: number;
@State contactSearchNumber: number = 0;
emitterId: number = 102;
@State placeholder: string = '';
@State cancelIsTouch: boolean = false;
aboutToAppear() {
let innerEvent = {
eventId: this.emitterId,
priority: emitter.EventPriority.HIGH
};
emitter.on(innerEvent, (data) => {
this.contactSearchNumber = data.data['contactSearchList'];
})
}
build() {
Column() {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
Column() {
Row() {
Image($r('app.media.ic_public_back'))
.fillColor($r('sys.color.ohos_id_color_primary'))
.objectFit(ImageFit.Contain)
.height($r('app.float.id_card_image_small'))
.width($r('app.float.id_card_image_small'))
.onClick(() => {
this.presenter.isSearchPage = false;
this.presenter.sendEmitter(this.presenter.isSearchPage);
this.presenter.inputKeyword = '';
})
Stack({ alignContent: Alignment.Center }) {
TextInput({ text: this.presenter.inputKeyword, placeholder: $r('app.string.contact_list_search') })
.placeholderColor(Color.Grey)
.placeholderFont({
size: $r('sys.float.ohos_id_text_size_headline9'),
weight: FontWeight.Normal,
style: FontStyle.Normal
})
.type(InputType.Normal)
.caretColor($r('sys.color.ohos_id_color_text_primary_activated'))
.enterKeyType(EnterKeyType.Search)
.margin({ left: $r('app.float.id_card_image_small'), right: $r('app.float.id_card_image_small') })
.padding({ left: $r('app.float.id_card_margin_xxxxl') })
.height($r("app.float.id_item_height_mid"))
.border({
color: $r('sys.color.ohos_id_color_fourth'),
radius: $r('app.float.id_card_margin_max')
})
.onChange((value: string) => {
this.presenter.inputKeyword = value
this.presenter.getSearchContact(this.presenter.inputKeyword);
})
Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
Image($r("app.media.ic_public_search"))
.width($r('app.float.id_card_margin_xxxl'))
.height($r('app.float.id_card_margin_xxxl'))
.margin({ left: $r('app.float.id_card_margin_xxxxl') })
.objectFit(ImageFit.Contain)
if (this.presenter.inputKeyword != '') {
Image($r('app.media.ic_public_cancel'))
.width($r('app.float.id_card_margin_max'))
.height($r('app.float.id_card_margin_max'))
.objectFit(ImageFit.Contain)
.fillColor($r('sys.color.ohos_id_color_primary'))
.opacity(0.6)
.margin({ right: $r('app.float.id_card_margin_xxxxl') })
.align(Alignment.End)
.onClick(() => {
this.presenter.inputKeyword = '';
})
}
}
.hitTestBehavior(HitTestMode.Transparent)
}
.align(Alignment.Center)
}
.padding({ top: $r('app.float.id_card_image_xs'), bottom: $r('app.float.id_card_image_xs') })
.width('100%')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Start)
.align(Alignment.Start)
}
.width('100%')
.backgroundColor(Color.White)
.padding({ left: $r('app.float.id_card_image_small'), right: $r('app.float.id_card_image_small') })
}
}
.visibility(this.type === 1 || this.type === 2 ? Visibility.None : Visibility.Visible)
Column() {
Text($r('app.string.found_contacts', this.contactSearchNumber))
.fontColor(Color.Gray)
.margin({ top: $r('app.float.id_card_margin_xxl'), bottom: $r('app.float.id_card_margin_xxl') })
.width('100%')
.visibility(this.contactSearchNumber > 0 ? Visibility.Visible : Visibility.None)
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ space: 0, initialIndex: 0 }) {
LazyForEach(this.presenter.searchContactsSource, (item, index: number) => {
ListItem() {
Stack({ alignContent: Alignment.BottomEnd }) {
Row() {
Row() {
if (StringUtil.isEmpty(item?.contact?.photoFirstName)) {
Image(StringUtil.isEmpty(item?.contact?.portraitPath) ? $r("app.media.ic_user_portrait") : item?.contact?.portraitPath)
.width($r("app.float.id_card_image_mid"))
.height($r("app.float.id_card_image_mid"))
.objectFit(ImageFit.Contain)
.borderRadius($r("app.float.id_card_image_mid"))
.backgroundColor(item?.contact?.portraitColor)
} else {
Text(item?.contact?.photoFirstName.toUpperCase())
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.backgroundColor(item?.contact?.portraitColor)
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
.textAlign(TextAlign.Center)
.borderRadius($r("app.float.id_card_image_mid"))
}
}
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
Column() {
Row() {
ForEach(item?.contact?.displayName.split(this.presenter.inputKeyword), (itemData1, idx: number) => {
Row() {
Text(itemData1.toString())
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
if (idx === 0) {
if (item?.contact?.displayName.indexOf(this.presenter.inputKeyword) !== -1) {
Text(this.presenter.inputKeyword.toString())
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontColor(Color.Blue)
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
}
} else if (item?.contact?.displayName.split(this.presenter.inputKeyword)
.length - 1 !== idx) {
Text(this.presenter.inputKeyword.toString())
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
}
}
})
}
Row() {
if (!StringUtil.isEmpty(item?.contact?.detailInfo) && '0' !== item?.contact?.hasPhoneNumber) {
ForEach(item?.contact?.detailInfo?.split(this.presenter.inputKeyword), (itemData, idx: number) => {
Row() {
Text(itemData.toString())
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
if (idx === 0) {
if (item?.contact?.detailInfo.indexOf(this.presenter.inputKeyword) !== -1) {
Text(this.presenter.inputKeyword.toString())
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontColor(Color.Blue)
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
}
} else if (item?.contact?.detailInfo.split(this.presenter.inputKeyword)
.length - 1 !== idx) {
Text(this.presenter.inputKeyword.toString())
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.fontWeight(FontWeight.Medium)
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(2)
}
}
})
}
}
}
.alignItems(HorizontalAlign.Start)
.padding({
top: $r("app.float.id_card_margin_mid"),
bottom: $r("app.float.id_card_margin_mid"),
})
.margin({ left: $r("app.float.id_card_margin_xl") })
}
.constraintSize({ minHeight: $r("app.float.id_item_height_max") })
.width('100%')
.height($r("app.float.id_item_height_large"))
Divider()
.color($r("sys.color.ohos_id_color_list_separator"))
.visibility(this.contactSearchNumber > 1 && this.contactSearchNumber - item.index > 1 ? Visibility.Visible : Visibility.None)
.margin({
left: $r("app.float.id_item_height_large"),
right: $r('app.float.id_card_image_small')
})
}
}
.onClick(() => {
if (this.type === 0) {
router.pushUrl(
{
url: "pages/contacts/details/ContactDetail",
params: {
sourceHasId: true,
contactId: item.contact.contactId
}
}
);
} else if (this.type === 1) {
this.batchSelectContactsPresenter.onSingleContactItemClick(0, item.contact.displayName, item.contact.contactId);
} else if (this.type === 2) {
}
})
}, item => JSON.stringify(item))
}
.height('90%')
.width('100%')
.listDirection(Axis.Vertical)
}
}
.height('100%')
.flexShrink(1)
}
.height("100%")
.width("100%")
.padding({ left: this.type === 0 && this.contactSearchNumber > 0 ? $r('app.float.id_card_image_small') : 0 })
.visibility(this.contactSearchNumber > 0 && !this.presenter.isSearchBackgroundColor ? Visibility.Visible : Visibility.None)
ContactSearchEmptyPage({ contactSearchNumber: $contactSearchNumber, presenter: $presenter, type: $type });
}
.padding({ bottom: $r('app.float.dialer_calllog_item_height') })
.height("100%")
.width("100%")
.backgroundColor(this.type === 1 || this.type === 2 ? $r("sys.color.ohos_id_color_sub_background") : this.type === 0 && this.contactSearchNumber > 0 ? Color.White : '#450a0a0a')
}
}
@Component
export struct ContactSearchEmptyPage {
@Link contactSearchNumber: number;
@Link presenter: ContactListPresenter;
@Link type: number;
build() {
Column() {
Image($r('app.media.no_contacts_illustration'))
.objectFit(ImageFit.Contain)
.width($r("app.float.id_card_image_large"))
.height($r("app.float.id_card_image_large"))
.margin({ bottom: $r("app.float.id_card_margin_large") })
Text($r('app.string.contact_list_search_empty'))
.width($r('app.float.id_card_image_large'))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.textAlign(TextAlign.Center)
.margin({ bottom: $r('app.float.dialer_calllog_item_height') })
}
.padding({
left: $r('app.float.id_card_image_small'),
right: $r('app.float.id_card_image_small'),
bottom: $r('app.float.account_listItem_text_common_width')
})
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
.backgroundColor(this.type === 1 ? $r("sys.color.ohos_id_color_sub_background") : Color.White)
.visibility(this.contactSearchNumber > 0 ? (!this.presenter.isSearchBackgroundColor ? Visibility.Visible : Visibility.None) :
(this.presenter.isSearchBackgroundColor ? Visibility.None : Visibility.Visible))
}
}
@@ -24,8 +24,10 @@ import DetailPresenter from '../../../presenter/contact/detail/DetailPresenter';
import { PhoneNumber } from '../../../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
import IndexPresenter from '../../../presenter/IndexPresenter';
import { HiLog } from "../../../../../../../common"
import emitter from '@ohos.events.emitter'
const TAG = "AllRecord ";
const EMITTER_SAVE_ID = 103;
@Component
export default struct AllRecord {
@@ -49,10 +51,20 @@ export default struct AllRecord {
aboutToAppear() {
HiLog.i(TAG, 'aboutToAppear,recordType:' + this.recordType)
this.onChanged();
let innerEventContact = {
eventId: EMITTER_SAVE_ID,
priority: emitter.EventPriority.HIGH
};
emitter.on(innerEventContact, (data) => {
let phoneNumber: string = data.data['phoneNumber'];
let callId: string = data.data['callId'];
this.mPresenter.saveCallRecordExistingContact(phoneNumber, callId);
})
}
aboutToDisappear() {
HiLog.i(TAG, 'aboutToDisappear,recordType:' + this.recordType)
emitter.off(EMITTER_SAVE_ID);
}
build() {
@@ -125,7 +137,7 @@ struct EmptyView {
}
enum MenuType {
sendMessage, Copy, EditBeforeCall, BlockList, DeleteCallLogs
sendMessage, Copy, EditBeforeCall, BlockList, DeleteCallLogs, SaveExistingContacts
}
@Component
@@ -153,7 +165,8 @@ struct ContactItem {
}),
autoCancel: true,
alignment: (EnvironmentProp.isTablet() ? DialogAlignment.Center : DialogAlignment.Bottom),
offset: { dx: 0, dy: -16 }
offset: { dx: 0, dy: -16 },
closeAnimation: { duration: 100 }
});
build() {
@@ -242,7 +255,6 @@ struct ContactItem {
.margin({ top: $r("app.float.id_card_margin_sm"), right: 24 })
.onClick(() => {
this.mPresenter.jumpToContactDetail(this.item.phoneNumber);
DialerPresenter.getInstance().panelShow = true;
AppStorage.SetOrCreate<boolean>("showDialBtn", true);
})
}
@@ -275,7 +287,6 @@ struct ContactItem {
this.mPresenter.dialing(this.item.phoneNumber);
}
}
DialerPresenter.getInstance().panelShow = true;
AppStorage.SetOrCreate<boolean>("showDialBtn", true);
})
.bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
@@ -297,14 +308,15 @@ struct ContactItem {
.textOverflow({ overflow: TextOverflow.Ellipsis })
.height($r("app.float.id_item_height_max"))
}
this.MenuView($r("app.string.send_message"), MenuType.sendMessage)
this.MenuDivider()
this.MenuView($r("app.string.copy_phoneNumber"), MenuType.Copy)
this.MenuDivider()
this.MenuView($r("app.string.edit_beforeCall"), MenuType.EditBeforeCall)
this.MenuDivider()
this.MenuView($r("app.string.delete_call_logs"), MenuType.DeleteCallLogs)
this.MenuView($r("app.string.save_to_existing_contacts"), MenuType.SaveExistingContacts, this.item.displayName)
this.MenuDivider(MenuType.SaveExistingContacts, this.item.displayName)
this.MenuView($r("app.string.send_message"), MenuType.sendMessage, this.item.displayName)
this.MenuDivider(MenuType.sendMessage, this.item.displayName)
this.MenuView($r("app.string.copy_phoneNumber"), MenuType.Copy, this.item.displayName)
this.MenuDivider(MenuType.Copy, this.item.displayName)
this.MenuView($r("app.string.edit_beforeCall"), MenuType.EditBeforeCall, this.item.displayName)
this.MenuDivider(MenuType.EditBeforeCall, this.item.displayName)
this.MenuView($r("app.string.delete_call_logs"), MenuType.DeleteCallLogs, this.item.displayName)
}
.width("150vp")
.alignItems(HorizontalAlign.Start)
@@ -312,7 +324,7 @@ struct ContactItem {
.backgroundColor($r('sys.color.ohos_id_color_primary_contrary'))
}
@Builder MenuView(menuName, itemType) {
@Builder MenuView(menuName, itemType, displayName) {
Row() {
Text(menuName)
.fontSize($r("sys.float.ohos_id_text_size_body1"))
@@ -323,13 +335,14 @@ struct ContactItem {
.width("100%")
.height($r("app.float.id_item_height_mid"))
.backgroundColor($r('sys.color.ohos_id_color_primary_contrary'))
.visibility(itemType !== MenuType.SaveExistingContacts || itemType === MenuType.SaveExistingContacts &&
'' === displayName ? Visibility.Visible : Visibility.None)
.onClick(() => {
switch (itemType) {
case MenuType.DeleteCallLogs:
this.deleteDialogController.open();
break;
case MenuType.EditBeforeCall:
DialerPresenter.getInstance().isClickDelete = false;
DialerPresenter.getInstance().editPhoneNumber(this.item.phoneNumber);
AppStorage.SetOrCreate<boolean>("showDialBtn", true);
break;
@@ -342,16 +355,30 @@ struct ContactItem {
case MenuType.Copy:
this.mIndexPresenter.getCopy(this.item.phoneNumber);
break;
case MenuType.SaveExistingContacts:
let innerEvent = {
eventId: EMITTER_SAVE_ID,
priority: emitter.EventPriority.HIGH
};
emitter.emit(innerEvent, {
data: {
'callId': this.item.id,
'phoneNumber': this.item.phoneNumber
}
});
break;
}
})
}
@Builder MenuDivider() {
@Builder MenuDivider(itemType, displayName) {
Divider()
.color($r('sys.color.ohos_id_color_list_separator'))
.lineCap(LineCapStyle.Square)
.width(0)
.alignSelf(ItemAlign.Stretch)
.padding({ left: $r("app.float.id_card_margin_xxl"), right: $r("app.float.id_card_margin_xxl") })
.visibility(itemType !== MenuType.SaveExistingContacts || itemType === MenuType.SaveExistingContacts &&
'' === displayName ? Visibility.Visible : Visibility.None)
}
}
@@ -0,0 +1,143 @@
/**
* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HiLog, sharedPreferencesUtils } from '../../../../../../common';
const TAG = "SelectMultiNumDialog";
@CustomDialog
export struct SelectMultiNumDialog {
@Link builder: SelectNumDialogBuilder;
private controller: CustomDialogController;
private selectDefault: Boolean = false;
aboutToAppear() {
HiLog.i(TAG, JSON.stringify(this.builder));
sharedPreferencesUtils.init(globalThis.getContext())
}
build() {
Column() {
Text(this.builder.title)
.fontSize($r("sys.float.ohos_id_text_size_dialog_tittle"))
.fontColor($r("sys.color.ohos_id_color_text_primary"))
.fontWeight(FontWeight.Bold)
.alignSelf(ItemAlign.Center)
.width("100%")
.height("48vp")
.padding({ left: "16vp", })
List() {
ForEach(this.builder.multiNumCardItems, (item, index) => {
ListItem() {
Row() {
Image(item.img)
.height("30vp")
.width("30vp")
.margin({ right: "8vp" })
.onError((event => {
HiLog.e(TAG, "Num:" + index + " Image onError" + JSON.stringify(event))
}))
Column() {
Text(item.number)
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor($r("sys.color.ohos_id_color_text_primary"))
.fontWeight(FontWeight.Lighter)
Text(item.numType)
.fontSize($r("sys.float.ohos_id_text_size_body2"))
.fontColor($r('sys.color.ohos_dialog_text_alert_transparent'))
.fontWeight(FontWeight.Lighter)
.margin({ top: "4vp" })
}.alignItems(HorizontalAlign.Start)
}.width('100%')
.height("56vp")
.justifyContent(FlexAlign.Start)
.padding({ left: "16vp", })
}.onClick(() => {
this.confirm(item, this.builder.contactId);
})
})
}.divider({
strokeWidth: 0.8,
startMargin: 56,
endMargin: $r("app.float.id_card_margin_max"),
})
Row() {
Checkbox({ name: 'checkbox2', group: 'checkboxGroup' })
.select(false)
.selectedColor(0x39a2db)
.onChange((value: boolean) => {
this.selectDefault = value
console.info(' msz Checkbox2 change is' + value)
})
Column() {
Text($r("app.string.set_default_values"))
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor($r('sys.color.ohos_dialog_text_alert_transparent'))
.fontWeight(FontWeight.Lighter)
}.alignItems(HorizontalAlign.Start)
}.width('100%')
.height("56vp")
.justifyContent(FlexAlign.Start)
.padding({ left: "16vp", })
Text($r("app.string.cancel"))
.alignSelf(ItemAlign.Center)
.textAlign(TextAlign.Center)
.fontWeight(FontWeight.Medium)
.fontColor(0x39a2db)
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.width("100%")
.height("48vp")
.onClick(() => {
this.cancel()
});
}.backgroundColor(Color.White)
}
confirm(item, contactId) {
this.controller.close()
if (this.selectDefault) {
sharedPreferencesUtils.saveToPreferences(contactId + '', item.number);
}
if (this.builder.callback) {
this.builder.callback(item);
}
}
cancel() {
this.controller.close()
}
}
class MultiNumCardItems {
number: String;
numType: Resource;
img: Resource;
}
interface Controller {
close();
open();
}
export class SelectNumDialogBuilder {
title: string | Resource;
contactId: String
multiNumCardItems: Array<MultiNumCardItems>;
callback?: (item: MultiNumCardItems) => void;
controller?: Controller;
}
@@ -0,0 +1,540 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import EditFavoriteListPresenter from '../../presenter/favorite/EditFavoriteListPresenter';
import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
import router from '@ohos.router';
import { FavoriteBean } from '../../model/bean/FavoriteBean';
const TAG = 'EditFavoriteList';
@Entry
@Component
export default struct EditFavoriteList {
@State mFavoriteListPresenter: EditFavoriteListPresenter = EditFavoriteListPresenter.getInstance();
@State isEdit: boolean = true
@State favoriteList: FavoriteBean[] = [];
@State selectNumbers: number = 0;
@State favoriteNumbers: number = 0;
@State usuallyNumbers: number = 0;
aboutToAppear() {
HiLog.i(TAG, 'EditFavoriteList aboutToAppear!');
let obj: any = router.getParams();
this.mFavoriteListPresenter.favoriteList = obj.favoriteList;
this.mFavoriteListPresenter.isEditSelect = obj.isEditSelectList;
this.selectNumbers = obj.selectNumber;
this.favoriteNumbers = obj.favoriteNumber;
this.usuallyNumbers = obj.usuallyNumber;
this.mFavoriteListPresenter.selectFavoriteBean = obj.selectFavoriteBean;
this.mFavoriteListPresenter.aboutToAppear();
}
aboutToDisappear() {
HiLog.i(TAG, 'EditFavoriteList aboutToDisappear!');
this.mFavoriteListPresenter.aboutToDisappear();
}
onPageShow() {
HiLog.i(TAG, 'EditFavoriteList onPageShow')
this.mFavoriteListPresenter.onPageShow()
}
onPageHide() {
HiLog.i(TAG, 'EditFavoriteList onPageHide')
this.mFavoriteListPresenter.onPageHide()
}
build() {
Column() {
if (this.mFavoriteListPresenter.favoriteList.length > 0) {
FavoriteContent({
presenter: $mFavoriteListPresenter,
selectNumbers: $selectNumbers,
favoriteNumber: $favoriteNumbers,
usuallyNumber: $usuallyNumbers
})
} else {
FavoriteEmptyPage({ presenter: $mFavoriteListPresenter, isEdit: $isEdit })
}
}
.width('100%')
.height('100%')
}
}
@Component
struct FavoriteContent {
@Link presenter: EditFavoriteListPresenter;
isUsuallyShow: boolean = false;
@Link selectNumbers: number;
@Link favoriteNumber: number;
@Link usuallyNumber: number;
@State selectNumber: number = this.selectNumbers;
@State selectFavoriteIdList: string[] = [];
@State isEditSelectList: string[] = null != this.presenter.isEditSelect &&
this.presenter.isEditSelect.length > 0 ? this.presenter.isEditSelect : [];
@State favoriteListPresenter: EditFavoriteListPresenter = this.presenter;
@State isSelectAll: boolean = false;
@State isSelectAllStatus: boolean = false;
item: any = {};
@State text: string = '';
@State isEditDrag: boolean = false;
@State select: number = 0;
@State currentIndex: number = 0;
@State isDragShow: boolean = false;
@State offsetY: number = 50;
@State positionYDown: number = 0;
@State positionYUp: number = 0;
@Builder pixelMapBuilder() {
Column() {
FavoriteListItem({
item: this.item,
isEditSelectList: $isEditSelectList,
presenter: $favoriteListPresenter,
selectNumber: $selectNumber,
isSelectAll: $isSelectAll,
usuallyNumber: $usuallyNumber,
favoriteNumber: $favoriteNumber,
isEditDrag: this.isEditDrag
})
}
}
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
Stack({ alignContent: Alignment.TopStart }) {
Row() {
Text(this.selectNumber > 0 ? $r('app.string.select_num', this.selectNumber) : $r('app.string.no_select'))
.maxFontSize(22)
.minFontSize(18)
.maxLines(1)
.fontWeight(FontWeight.Bold)
.fontColor(Color.Black)
.margin({ top: $r('app.float.id_card_margin_large'), bottom: $r('app.float.id_card_margin_large') })
}
.margin({ left: this.offsetY < 0 ? 0 : $r('app.float.id_item_height_mid') })
.height(this.offsetY > 0 ? 56 : 138)
.animation({
duration: 200,
iterations: 1,
})
TitleGuide({
isDragShow: $isDragShow,
isEditSelectList: $isEditSelectList,
presenter: $favoriteListPresenter,
selectNumber: $selectNumber,
offsetY: $offsetY
})
}
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ space: 0, initialIndex: 0 }) {
LazyForEach(this.presenter.favoriteDataSource, (item, index: number) => {
ListItem() {
FavoriteListItem({
item: item,
isEditSelectList: $isEditSelectList,
presenter: $favoriteListPresenter,
selectNumber: $selectNumber,
isSelectAll: $isSelectAll,
usuallyNumber: $usuallyNumber,
favoriteNumber: $favoriteNumber,
isEditDrag: false
})
}
.onDragStart((event: DragEvent, extraParams: string) => {
console.log('ListItem onDragStarts, ' + extraParams)
var jsonString = JSON.parse(extraParams)
if (jsonString.selectedIndex >= this.favoriteNumber) {
console.log('List onDragStarts , return ')
return;
}
this.isEditDrag = true;
this.select = jsonString.selectedIndex;
this.item = item;
return this.pixelMapBuilder();
})
}, (item) => JSON.stringify(item))
}
.editMode(true)
.width('100%')
.height('100%')
.scrollBar(BarState.Off)
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
.onDrop((event: DragEvent, extraParams: string) => {
let jsonString = JSON.parse(extraParams);
if (jsonString.insertIndex >= this.favoriteNumber) {
return;
}
if (this.isEditDrag) {
this.isDragShow = true;
let index = this.presenter.favoriteDataSource.getFavoriteList().indexOf(this.item.favorite);
this.presenter.favoriteDataSource.getFavoriteList().splice(index, 1);
this.presenter.favoriteDataSource.getFavoriteList()
.splice(jsonString.insertIndex, 0, this.item.favorite);
this.presenter.favoriteDataSource.refresh(this.presenter.favoriteDataSource.getFavoriteList());
this.isEditDrag = false;
}
})
.onScroll((scrollOffset, scrollState) => {
this.offsetY = this.positionYDown - this.positionYUp;
if (this.offsetY > 0) {
animateTo({ duration: 1000 }, () => {
});
} else {
animateTo({ duration: 1000 }, () => {
});
}
})
.onTouch((event) => {
switch (event.type) {
case TouchType.Down:
this.positionYDown = Math.abs(event.touches[0].y);
break;
case TouchType.Move:
this.positionYUp = Math.abs(event.touches[0].y);
case TouchType.Up:
this.positionYUp = Math.abs(event.touches[0].y);
break;
}
})
}
}
.height('100%')
.flexShrink(1)
Row() {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
Column() {
Image(this.selectNumber > 0 ? $r('app.media.ic_public_close') : $r('app.media.ic_public_close_gray'))
.objectFit(ImageFit.Contain)
.height($r('app.float.id_card_image_small'))
.width($r('app.float.id_card_image_small'))
.margin({ bottom: 3 })
Text($r('app.string.favorite_remove'))
.fontColor(this.selectNumber > 0 ? $r('sys.color.ohos_id_color_toolbar_text') : Color.Gray)
.fontSize($r('sys.float.ohos_id_text_size_caption'))
.fontWeight(FontWeight.Medium)
.margin({ top: $r('app.float.id_card_margin_large') })
}
.onClick(() => {
if (this.isEditSelectList.length > 0) {
this.presenter.deleteFavoriteInfo(this.isEditSelectList);
this.isEditSelectList = [];
this.selectNumber = this.isEditSelectList.length;
router.back();
}
})
.width('40%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
Column() {
Image(this.presenter.favoriteList.length === this.selectNumber ? $r('app.media.ic_public_select_all_filled') : $r('app.media.ic_public_select_all'))
.objectFit(ImageFit.Contain)
.height($r('app.float.id_card_image_small'))
.width($r('app.float.id_card_image_small'))
.margin({ bottom: 3 })
.fillColor($r('sys.color.ohos_id_color_primary'))
Text(this.presenter.favoriteList.length === this.selectNumber ? $r('app.string.unselect_all') : $r('app.string.select_all'))
.fontColor(this.presenter.favoriteList.length === this.selectNumber ? $r('sys.color.ohos_id_color_toolbar_text') : Color.Gray)
.fontSize($r('sys.float.ohos_id_text_size_caption'))
.fontWeight(FontWeight.Medium)
.margin({ top: $r('app.float.id_card_margin_large') })
}
.onClick(() => {
this.isSelectAll = this.presenter.favoriteList.length === this.selectNumber;
if (this.isSelectAll) {
this.isEditSelectList = this.presenter.cancelAllFavoriteSelectInfo(this.presenter.favoriteList, this.isEditSelectList);
} else {
this.isEditSelectList = this.presenter.addAllFavoriteSelectInfo(this.presenter.favoriteList);
}
this.selectNumber = this.isEditSelectList.length;
this.presenter.favoriteDataSource.refresh(this.presenter.favoriteList);
})
.width('40%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
}
}
.padding({ left: 24, right: 24 })
.backgroundColor(Color.White)
.width('100%')
.height($r('app.float.id_item_height_max'))
}
.padding({ left: 24, right: 24 })
.height('100%')
.width('100%')
}
.height('100%')
.width('100%')
}
}
@Component
export struct FavoriteListItem {
@Link presenter: EditFavoriteListPresenter;
@State item: any = {};
@Link isEditSelectList: string[];
@Link selectNumber: number;
@Link isSelectAll: boolean;
@Link usuallyNumber: number;
@Link favoriteNumber: number;
isEditDrag: boolean = false;
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (1 === this.item.favorite.isCommonUseType) {
Text($r('app.string.common_use_num', this.usuallyNumber))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor('#666666')
.lineHeight(19)
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.id_card_margin_xxl'), bottom: $r('app.float.id_card_margin_xxl') })
.borderRadius($r('app.float.id_card_image_mid'))
.visibility(this.item.favorite.isUsuallyShow ? Visibility.Visible : Visibility.None)
} else if (0 === this.item.favorite.isCommonUseType && this.item.index === 0) {
Text($r('app.string.favorite_num', this.favoriteNumber))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor('#666666')
.lineHeight(19)
.textAlign(TextAlign.Center)
.margin({ top: $r('app.float.id_card_margin_xxl'), bottom: $r('app.float.id_card_margin_xxl') })
.borderRadius($r('app.float.id_card_image_mid'))
.visibility(this.isEditDrag ? Visibility.None : Visibility.Visible)
}
Row() {
Flex({
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Stretch
}) {
Row() {
if (0 === this.item.favorite.isCommonUseType) {
Image($r('app.media.ic_public_drag_handle'))
.width($r('app.float.id_card_image_small'))
.height($r('app.float.id_card_image_small'))
.objectFit(ImageFit.Contain)
.borderRadius($r('app.float.id_card_image_mid'))
.margin({ right: $r('app.float.id_card_image_xs') })
.width('10%')
}
Row() {
if (StringUtil.isEmpty(this.item.favorite.nameSuffix)) {
Image(StringUtil.isEmpty(this.item.favorite.portraitPath) ? $r('app.media.ic_user_portrait') : this.item.favorite.portraitPath)
.width($r("app.float.id_card_image_mid"))
.height($r("app.float.id_card_image_mid"))
.objectFit(ImageFit.Contain)
.borderRadius($r("app.float.id_card_image_mid"))
.backgroundColor(this.item.favorite.portraitColor)
} else {
Text(this.item.favorite.namePrefix.toUpperCase())
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.backgroundColor(this.item.favorite.portraitColor)
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
.textAlign(TextAlign.Center)
.borderRadius($r("app.float.id_card_image_mid"))
}
}
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
if (0 === this.item.favorite.isCommonUseType) {
Text(this.item.favorite.displayName)
.maxLines(1)
.fontSize(40)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontWeight(FontWeight.Bold)
.fontColor(Color.Black)
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.margin({ left: $r('app.float.dialer_common_small_margin') })
.textAlign(TextAlign.Start)
.height('100%')
.width('83%')
} else {
Column() {
Text(this.item.favorite.displayName)
.maxLines(1)
.fontSize(40)
.fontWeight(FontWeight.Bold)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor(Color.Black)
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.margin({ bottom: 5 })
.textAlign(TextAlign.Start)
Text($r('app.string.phone_type_mobile_expansion', this.item.favorite.phoneNum))
.fontColor($r('sys.color.ohos_fa_text_secondary'))
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.textAlign(TextAlign.Start)
}
.width('83%')
.padding({ left: $r('app.float.id_card_margin_xxl'), right: $r('app.float.id_card_margin_large') })
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
}
}
Column() {
Checkbox({ name: this.item.favorite.contactId })
.width($r('app.float.id_card_image_mid'))
.height($r('app.float.id_card_image_mid'))
.selectedColor('#007DFF')
.padding($r("app.float.id_card_margin_mid"))
.select(this.item.favorite.isEditSelect ? true : false)
.onChange((value: boolean) => {
this.isSelectAll = false;
this.item.favorite.isEditSelect = value;
if (value) {
this.isEditSelectList = this.presenter.addSingleFavoriteSelectInfo(this.isEditSelectList, this.item.favorite);
} else {
this.isEditSelectList = this.presenter.cancelSingleFavoriteSelectInfo(this.isEditSelectList, this.item.favorite);
}
this.selectNumber = this.isEditSelectList.length;
this.presenter.favoriteDataSource.refresh(this.presenter.favoriteList);
})
.width('100%')
}
.width('9%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
}
.width('100%')
}
.alignItems(VerticalAlign.Center)
.direction(Direction.Ltr)
.justifyContent(FlexAlign.Start)
.constraintSize({ minHeight: $r('app.float.id_item_height_max') })
.height($r('app.float.id_item_height_large'))
.width('100%')
}.alignItems(HorizontalAlign.Start)
if (this.item.showDivider || this.item.index >= 0 && this.favoriteNumber > 1 && this.favoriteNumber - 1
!= this.item.index && this.presenter.favoriteList.length - 1 != this.item.index) {
Divider()
.color($r('sys.color.ohos_id_color_list_separator'))
.margin({ left: $r('app.float.id_item_height_large') })
}
}
}
}
@Component
export struct FavoriteEmptyPage {
@Link presenter: EditFavoriteListPresenter;
@Link isEdit: boolean ;
build() {
Column() {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 2, lg: 4 } }) {
Text($r('app.string.favorite'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.height($r("app.float.id_item_height_large"))
.textAlign(TextAlign.Start)
.width('100%')
}
}
Column() {
Image($r('app.media.no_contacts_illustration'))
.objectFit(ImageFit.Contain)
.width($r('app.float.id_card_image_large'))
.height($r('app.float.id_card_image_large'))
.margin({ bottom: $r('app.float.id_card_margin_large') })
Text($r('app.string.cancel_favorite'))
.width($r('app.float.id_card_image_large'))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.textAlign(TextAlign.Center)
}
.margin({ bottom: 192 })
}
.padding({ left: 24, right: 24 })
.justifyContent(FlexAlign.SpaceBetween)
.height('100%')
.width('100%')
}
}
@Component
struct TitleGuide {
@Link presenter: EditFavoriteListPresenter;
@Link isEditSelectList: string[];
@Link isDragShow: boolean;
@Link selectNumber: number;
@Link offsetY: number;
build() {
Row() {
Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
Image(this.offsetY > 0 ? $r("app.media.ic_public_back") : $r('app.media.ic_public_cancel'))
.width($r('app.float.id_card_image_large'))
.height($r('app.float.id_item_height_large'))
.padding({
top: $r('app.float.id_card_margin_xxl'),
right: $r('app.float.dialer_keypad_button_height'),
bottom: $r('app.float.id_card_margin_xxl'),
})
.onClick(() => {
this.presenter.cancelEditFavorite();
})
Image($r('app.media.ic_public_ok'))
.width($r('app.float.id_item_height_large'))
.height($r('app.float.id_item_height_large'))
.padding({
top: $r('app.float.id_card_margin_xxl'),
left: $r('app.float.id_card_margin_max'),
bottom: $r('app.float.id_card_margin_xxl')
})
.visibility(this.isDragShow ? Visibility.Visible : Visibility.Hidden)
.onClick(() => {
this.presenter.moveSortFavorite(this.presenter.favoriteDataSource.getFavoriteList());
})
}
.width('100%')
}
.justifyContent(FlexAlign.End)
.alignItems(VerticalAlign.Center)
.height($r('app.float.id_item_height_large'))
.width('100%')
}
onBackPress() {
this.presenter.cancelEditFavorite();
}
}
@@ -0,0 +1,445 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SelectDialogBuilder } from '../../component/mutisim/SelectSimIdDialog';
import { SelectMultiNumDialog } from '../dialog/SelectMultiNumDialog';
import { SelectNumDialogBuilder } from '../dialog/SelectMultiNumDialog';
import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
import { HiLog, sharedPreferencesUtils } from '../../../../../../common';
import FavoriteListPresenter from '../../presenter/favorite/FavoriteListPresenter';
import { PhoneNumber } from '../../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
import ContactAbilityModel from '../../model/ContactAbilityModel';
import emitter from '@ohos.events.emitter';
import { Phone } from '../../../../../../feature/contact/src/main/ets/contract/Phone';
import prompt from '@ohos.prompt';
const TAG = 'FavoriteList';
@Entry
@Component
export default struct FavoriteList {
@State mFavoriteListPresenter: FavoriteListPresenter = FavoriteListPresenter.getInstance();
@State isEdit: boolean = false;
@State favoriteListListLen: number = 0;
emitterId: number = 100;
aboutToAppear() {
HiLog.i(TAG, 'Favorite aboutToAppear!');
this.mFavoriteListPresenter.aboutToAppear();
let innerEvent = {
eventId: this.emitterId,
priority: emitter.EventPriority.HIGH
};
emitter.on(innerEvent, (data) => {
this.favoriteListListLen = data.data['favoriteListListLen'];
})
}
aboutToDisappear() {
HiLog.i(TAG, 'Favorite aboutToDisappear!');
this.mFavoriteListPresenter.aboutToDisappear();
}
onPageShow() {
HiLog.i(TAG, 'Favorite onPageShow');
this.mFavoriteListPresenter.onPageShow();
}
onPageHide() {
HiLog.i(TAG, 'Favorite onPageHide');
this.mFavoriteListPresenter.onPageHide();
}
build() {
Column() {
if (this.favoriteListListLen === 0) {
FavoriteEmptyPage({ presenter: $mFavoriteListPresenter, isEdit: $isEdit });
} else {
FavoriteContent({ presenter: $mFavoriteListPresenter });
}
}
.width('100%')
.height('100%')
}
}
@Component
struct FavoriteContent {
@Link presenter: FavoriteListPresenter;
@State mPresenter: FavoriteListPresenter = this.presenter;
isUsuallyShow: boolean = false;
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
TitleGuide({ mPresenter: $mPresenter });
}
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 2, lg: 4 } }) {
Column() {
Text($r('app.string.favorite'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.margin({ bottom: $r("app.float.id_card_margin_sm") })
.lineHeight(42)
.margin({ top: 8, bottom: 2 })
}
.alignItems(HorizontalAlign.Start)
.width('100%')
.height(82)
}
}
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
List({ space: 0, initialIndex: 0 }) {
LazyForEach(this.presenter.favoriteDataSource, (item, index: number) => {
ListItem() {
FavoriteListItem({ presenter: $mPresenter, item: item, mPresenter: $presenter });
}
}, (item) => JSON.stringify(item))
}
.scrollBar(BarState.Off)
.editMode(true)
.width('100%')
.height('100%')
.listDirection(Axis.Vertical)
.edgeEffect(EdgeEffect.Spring)
}
}
.height('100%')
.flexShrink(1)
}
.padding({ left: 24, right: 24 })
.height('100%')
.width('100%')
}
.backgroundColor(Color.White)
.height('100%')
.width('100%')
}
}
@Component
export struct FavoriteListItem {
@Link presenter: FavoriteListPresenter;
@Link private mPresenter: { [key: string]: any };
@State selectSimBuilder: SelectDialogBuilder = {
title: 'test title',
multiSimCardItems: [],
};
@State item: any = {};
@State builder: SelectNumDialogBuilder = {
title: $r('app.string.contacts_call'),
multiNumCardItems: [],
contactId: ''
};
mSelectSlotIdDialog: CustomDialogController = new CustomDialogController({
builder: SelectMultiNumDialog({
builder: $builder
}),
customStyle: false,
autoCancel: true,
alignment: DialogAlignment.Bottom
})
@State isEmergencyNum: boolean = false;
@StorageLink("haveSimCard") haveSimCard: boolean = false;
@StorageLink('haveMultiSimCard') haveMultiSimCard: boolean = false;
build() {
Stack({ alignContent: Alignment.BottomEnd }) {
Column() {
if (1 === this.item.favorite.isCommonUseType) {
Text($r('app.string.common_use'))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor('#666666')
.margin({ top: $r('app.float.id_card_margin_xxl') })
.textAlign(TextAlign.Center)
.borderRadius($r('app.float.id_card_image_mid'))
.visibility(this.item.favorite.isUsuallyShow ? Visibility.Visible : Visibility.None)
}
Row() {
Flex({
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Stretch
}) {
Row() {
Row() {
if (StringUtil.isEmpty(this.item.favorite.nameSuffix)) {
Image(StringUtil.isEmpty(this.item.favorite.portraitPath) ? $r('app.media.ic_user_portrait') : this.item.favorite.portraitPath)
.width($r("app.float.id_card_image_mid"))
.height($r("app.float.id_card_image_mid"))
.objectFit(ImageFit.Contain)
.borderRadius($r("app.float.id_card_image_mid"))
.backgroundColor(this.item.favorite.portraitColor)
} else {
Text(this.item.favorite.namePrefix.toUpperCase())
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
.backgroundColor(this.item.favorite.portraitColor)
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
.textAlign(TextAlign.Center)
.borderRadius($r("app.float.id_card_image_mid"))
}
}
.height($r("app.float.id_card_image_mid"))
.width($r("app.float.id_card_image_mid"))
if (0 === this.item.favorite.isCommonUseType) {
Text(this.item.favorite.displayName)
.maxLines(1)
.fontSize(40)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontWeight(FontWeight.Bold)
.fontColor(Color.Black)
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.margin({ left: $r('app.float.dialer_common_small_margin') })
.textAlign(TextAlign.Start)
.width('83%')
} else {
Column() {
Text(this.item.favorite.displayName)
.maxLines(1)
.fontSize(40)
.fontWeight(FontWeight.Bold)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.fontColor(Color.Black)
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.margin({ bottom: 5 })
.textAlign(TextAlign.Start)
Text($r('app.string.phone_type_mobile_expansion', this.item.favorite.phoneNum))
.fontColor($r('sys.color.ohos_fa_text_secondary'))
.fontSize($r('sys.float.ohos_id_text_size_sub_title3'))
.textAlign(TextAlign.Start)
}
.width('83%')
.padding({ left: $r('app.float.id_card_margin_xxl'), right: $r('app.float.id_card_margin_large') })
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
}
}
Image($r('app.media.ic_public_detail'))
.height($r('app.float.id_card_margin_xxl'))
.objectFit(ImageFit.Contain)
.borderRadius($r('app.float.id_card_margin_xl'))
.onClick(() => {
this.presenter.goContactDetail(this.item.favorite.contactId);
})
.width('7%')
}
.width('100%')
}
.alignItems(VerticalAlign.Center)
.direction(Direction.Ltr)
.justifyContent(FlexAlign.Start)
.constraintSize({ minHeight: $r('app.float.id_item_height_max') })
.height($r('app.float.id_item_height_large'))
.width('100%')
}
.alignItems(HorizontalAlign.Start)
.justifyContent(FlexAlign.Center)
if (this.item.showDivider) {
Divider()
.color($r('sys.color.ohos_id_color_list_separator'))
.margin({ left: $r('app.float.id_item_height_large') })
}
}
.onClick(() => {
ContactAbilityModel.getContactById(this.item.favorite.contactId, result => {
if (result.data.hasOwnProperty('phones')) {
if (result.data.phones.length > 1) {
new Promise<number>(async () => {
let defaultNumber: String = <String> await sharedPreferencesUtils.getFromPreferences(
this.item.favorite.contactId + '', '-1');
this.builder.multiNumCardItems = []
this.builder.contactId = result.data.id
var hasDefault = false
result.data.phones.forEach((element) => {
let formatNum = PhoneNumber.fromString(element.num).getNumber().replace(/\s+/g, '')
if (defaultNumber != '-1' && defaultNumber == formatNum) {
this.dealCallNumber(formatNum)
hasDefault = true;
return;
}
this.builder.multiNumCardItems.push({ number: element.num, img: $r("app.media.ic_public_phone_dialog"),
numType: Phone.getTypeLabelResource(parseInt(element.numType, 10)) })
});
this.builder.callback = (item) => {
this.dealCallNumber(item.number)
}
if (!hasDefault)
this.mSelectSlotIdDialog.open()
});
} else if (result.data.phones.length > 0) {
this.dealCallNumber(result.data.phones[0].num)
}
} else {
prompt.showToast({ message: '联系人无可用号码!'})
HiLog.e(TAG, ' popupSelectNumber phones null');
}
}, globalThis.getContext())
})
.gesture(
LongPressGesture({ repeat: false })
.onAction((event: GestureEvent) => {
for (let i = 0; i < this.presenter.favoriteList.length; i++) {
if (this.item.favorite.contactId === this.presenter.favoriteList[i].contactId) {
this.presenter.favoriteList[i].isEditSelect = true;
} else {
this.presenter.favoriteList[i].isEditSelect = false;
}
}
this.presenter.isEditSelectList.pop();
this.presenter.isEditSelectList.push(this.item.favorite.contactId + '');
this.presenter.longItemEditFavorite(this.presenter.favoriteList, this.presenter.isEditSelectList, this.item.favorite);
})
)
}
dealCallNumber(phoneNum) {
if (!this.haveSimCard) {
HiLog.i(TAG, "No SIM card!");
PhoneNumber.fromString(phoneNum).isDialEmergencyNum().then((res) => {
this.isEmergencyNum = res;
})
if (!this.isEmergencyNum) {
HiLog.i(TAG, "Is not Emergency Phone Number!");
return;
} else {
HiLog.i(TAG, "No SIM card, but is Emergency Phone Number");
PhoneNumber.fromString(phoneNum).dial();
}
} else if (this.haveMultiSimCard) {
this.selectSimBuilder.title = $r("app.string.contacts_call_number", phoneNum);
this.selectSimBuilder.callback = (value) => {
PhoneNumber.fromString(phoneNum).dial({
accountId: value,
});
}
this.selectSimBuilder.lastSimId = this.mPresenter.lastUsedSlotId;
let spnList = AppStorage.Get<Array<string | Resource>>('spnList');
for (var index = 0; index < spnList.length; index++) {
this.selectSimBuilder.multiSimCardItems[index].name = spnList[index];
}
this.selectSimBuilder.controller?.open();
} else {
PhoneNumber.fromString(phoneNum).dial();
}
}
}
@Component
export struct FavoriteEmptyPage {
@Link presenter: FavoriteListPresenter;
@Link isEdit: boolean ;
build() {
Column() {
GridRow({ columns: { sm: 4, md: 8, lg: 12 }, gutter: { x: 12, y: 0 } }) {
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 1, lg: 2 } }) {
TitleGuide({ mPresenter: $presenter });
}
GridCol({ span: { sm: 4, md: 6, lg: 8 }, offset: { sm: 0, md: 2, lg: 4 } }) {
Text($r('app.string.favorite'))
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.height($r('app.float.id_item_height_large'))
.textAlign(TextAlign.Start)
.width('100%')
}
}
Column() {
Image($r('app.media.ic_no_favorites'))
.objectFit(ImageFit.Contain)
.width($r('app.float.id_card_image_large'))
.height($r('app.float.id_card_image_large'))
.margin({ bottom: $r('app.float.id_card_margin_large') })
Text($r('app.string.no_favorite'))
.width($r('app.float.id_card_image_large'))
.fontSize($r('sys.float.ohos_id_text_size_body2'))
.fontWeight(FontWeight.Regular)
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
.textAlign(TextAlign.Center)
}
.height('100%')
.width('100%')
.margin({ top: $r('app.float.account_listItem_text_common_width') })
}
.padding({ left: 24, right: 24 })
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor(Color.White)
.height('100%')
.width('100%')
}
}
@Component
struct TitleGuide {
@Link mPresenter: FavoriteListPresenter;
@Builder MenuBuilder() {
Column() {
Text($r("app.string.edit"))
.fontSize($r("app.float.id_corner_radius_card_mid"))
.textAlign(TextAlign.Start)
.fontColor($r("sys.color.ohos_id_color_text_primary"))
.lineHeight(19)
.width($r("app.float.account_Divider_width"))
.height(21)
}
.width($r('app.float.account_MenuBuilder_width'))
.justifyContent(FlexAlign.Center)
.height($r("app.float.id_item_height_mid"))
.onClick(() => {
this.mPresenter.editFavorite();
})
}
build() {
Row() {
Image($r('app.media.ic_public_add'))
.width($r('app.float.id_card_image_mid'))
.height($r('app.float.id_card_image_mid'))
.padding($r('app.float.id_card_margin_large'))
.onClick(() => {
this.mPresenter.addFavorite();
});
Image(this.mPresenter.favoriteList.length > 0 ? $r('app.media.ic_public_more') : $r('app.media.ic_public_more_gray'))
.width($r('app.float.id_card_image_mid'))
.height($r('app.float.id_card_image_mid'))
.objectFit(ImageFit.Contain)
.padding($r('app.float.id_card_margin_large'))
.enabled(this.mPresenter.favoriteList.length > 0 ? true : false)
.bindMenu(this.MenuBuilder)
}
.justifyContent(FlexAlign.End)
.alignItems(VerticalAlign.Center)
.height($r('app.float.id_item_height_large'))
.width('100%')
}
}
+46 -19
View File
@@ -14,16 +14,18 @@
*/
import callTabletPage from './dialer/DialerTablet';
import contactPage from './contacts/ContactList';
import favoritePage from './favorites/favoriteList';
import callPage from './phone/dialer/Dialer';
import IndexPresenter from '../presenter/IndexPresenter';
import { HiLog } from '../../../../../common/src/main/ets/util/HiLog';
import { HiLog, StringUtil } from '../../../../../common';
import { PermissionManager } from '../../../../../common/src/main/ets/permission/PermissionManager';
import DialerPresenter from '../presenter/dialer/DialerPresenter';
import call from '@ohos.telephony.call';
import ContactListPresenter from '../presenter/contact/ContactListPresenter';
import CallRecordPresenter from '../presenter/dialer/callRecord/CallRecordPresenter';
import FavoriteListPresenter from '../presenter/favorite/FavoriteListPresenter';
import device from '@system.device';
import router from '@ohos.router';
import emitter from '@ohos.events.emitter';
const TAG = 'Index ';
@@ -41,12 +43,14 @@ struct Index {
@State bottomTabIndex: number = call.hasVoiceCapability() ? 0 : 1;
@StorageLink("targetPage") @Watch("targetPageChange") targetPage: any = {};
@LocalStorageProp('breakpoint') curBp: string = 'sm';
@State isContactSearch: boolean = false;
emitterId: number = 105;
teleNumberChange() {
if (AppStorage.Has('teleNumber')) {
HiLog.i(TAG, "teleNumberChange:" + this.teleNumber);
this.mDialerPresenter.editPhoneNumber(AppStorage.Get('teleNumber'));
AppStorage.Delete('teleNumber');
if (!StringUtil.isEmpty(this.teleNumber)) {
this.mDialerPresenter.editPhoneNumber(this.teleNumber);
AppStorage.SetOrCreate("showDialBtn", true);
this.teleNumber = "";
}
}
@@ -54,6 +58,7 @@ struct Index {
if (this.targetPage && this.targetPage.url) {
HiLog.i(TAG, "targetPageChange in" + this.targetPage);
this.mIndexPresenter.goToPage(this.targetPage.url, this.targetPage.pageIndex, this.targetPage.params)
this.targetPage = {}
}
}
@@ -66,12 +71,12 @@ struct Index {
}
this.bottomTabIndex = this.mainTabsIndex;
this.controller.changeIndex(this.mainTabsIndex);
if (this.mainTabsIndex == 0) {
ContactListPresenter.getInstance().setPageShow(false);
CallRecordPresenter.getInstance().setPageShow(true);
CallRecordPresenter.getInstance().setPageShow(this.bottomTabIndex == 0);
ContactListPresenter.getInstance().setPageShow(this.bottomTabIndex == 1);
if (this.mainTabsIndex != 2) {
FavoriteListPresenter.getInstance().onPageHide()
} else {
CallRecordPresenter.getInstance().setPageShow(false);
ContactListPresenter.getInstance().setPageShow(true);
FavoriteListPresenter.getInstance().onPageShow()
}
}
}
@@ -83,13 +88,8 @@ struct Index {
onPageShow() {
this.mIndexPresenter.onPageShow();
if (this.bottomTabIndex == 0) {
ContactListPresenter.getInstance().setPageShow(false);
CallRecordPresenter.getInstance().setPageShow(true);
} else {
CallRecordPresenter.getInstance().setPageShow(false);
ContactListPresenter.getInstance().setPageShow(true);
}
CallRecordPresenter.getInstance().setPageShow(this.bottomTabIndex == 0);
ContactListPresenter.getInstance().setPageShow(this.bottomTabIndex == 1);
}
onPageHide() {
@@ -103,10 +103,25 @@ struct Index {
this.getInfo();
this.onIndexChanged();
this.teleNumberChange()
let innerEvent = {
eventId: this.emitterId,
priority: emitter.EventPriority.HIGH
};
emitter.on(innerEvent, (data) => {
this.isContactSearch = data.data['isSearchPage'];
})
}
aboutToDisappear() {
this.mIndexPresenter.aboutToDisappear();
emitter.off(this.emitterId);
}
onBackPress() {
if (this.isContactSearch) {
ContactListPresenter.getInstance().sendEmitter(false);
return true;
}
}
getInfo() {
@@ -134,6 +149,7 @@ struct Index {
}
.height('100%')
.zIndex(3)
.visibility(this.isContactSearch ? Visibility.None : Visibility.Visible)
}
Column() {
Tabs({
@@ -153,6 +169,10 @@ struct Index {
TabContent() {
contactPage()
}
TabContent() {
favoritePage()
}
}
.width('100%')
.vertical(false)
@@ -175,6 +195,7 @@ struct Index {
.width('100%')
.height($r("app.float.id_item_height_large"))
.flexShrink(0)
.visibility(this.isContactSearch ? Visibility.None : Visibility.Visible)
}
}
.backgroundColor($r("sys.color.ohos_fa_sub_background"))
@@ -189,7 +210,7 @@ struct Index {
@Component
struct TabBars {
private tabSrc: number[] = call.hasVoiceCapability() ? [0, 1] : [1];
private tabSrc: number[] = call.hasVoiceCapability() ? [0, 1, 2] : [1];
private controller: TabsController;
@Link bottomTabIndex: number;
@State mIndexPresenter: IndexPresenter = IndexPresenter.getInstance()
@@ -224,9 +245,15 @@ struct TabBars {
if (item == 0) {
ContactListPresenter.getInstance().setPageShow(false);
CallRecordPresenter.getInstance().setPageShow(true);
FavoriteListPresenter.getInstance().onPageHide();
} else if (item == 1) {
CallRecordPresenter.getInstance().setPageShow(false);
ContactListPresenter.getInstance().setPageShow(true);
FavoriteListPresenter.getInstance().onPageHide();
} else if (item == 2) {
CallRecordPresenter.getInstance().setPageShow(false);
ContactListPresenter.getInstance().setPageShow(false);
FavoriteListPresenter.getInstance().onPageShow();
}
}
})
+177 -64
View File
@@ -16,9 +16,8 @@
import CallRecord from '../../dialer/callRecord/CallRecord';
import { HiLog } from '../../../../../../../common/src/main/ets/util/HiLog';
import DialerPresenter from './../../../presenter/dialer/DialerPresenter';
import EnvironmentProp from '../../../feature/EnvironmentProp';
import IndexPresenter from '../../../presenter/IndexPresenter';
import { DialerButtonView } from "../../../component/dialer/DialerButtonView";
import { PhoneNumber } from '../../../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
const TAG = 'Dialer';
@@ -30,47 +29,59 @@ struct DialButton {
build() {
Column() {
Button() {
Column() {
if (`${this.button_number}` == '*') {
Image($r("app.media.symbol_phone"))
.width(24)
.height(24)
} else if (`${this.button_number}` == '#') {
Image($r("app.media.symbols_phone"))
.width(24)
.height(24)
} else {
Text(`${this.button_number}`)
.fontSize(25)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontWeight(FontWeight.Medium)
}
if ((this.button_char == 'ic')) {
Image($r("app.media.ic_contacts_voicemail_mini"))
.width(14)
.height(14)
} else if ((this.button_char == '+')) {
Text(`${this.button_char}`)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontSize(17.5)
} else {
Text(`${this.button_char}`)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontSize($r("sys.float.ohos_id_text_size_chart1"))
Column() {
Button() {
Column() {
if (`${this.button_number}` == '*') {
Image($r("app.media.symbol_phone"))
.width(24)
.height(24)
} else if (`${this.button_number}` == '#') {
Image($r("app.media.symbols_phone"))
.width(24)
.height(24)
} else {
Text(`${this.button_number}`)
.fontSize(25)
.fontColor($r('sys.color.ohos_id_color_text_primary'))
.fontWeight(FontWeight.Medium)
}
if ((this.button_char == 'ic')) {
Image($r("app.media.ic_contacts_voicemail_mini"))
.width(14)
.height(14)
} else if ((this.button_char == '+')) {
Text(`${this.button_char}`)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontSize(17.5)
} else {
Text(`${this.button_char}`)
.fontColor($r('sys.color.ohos_id_color_text_secondary'))
.fontSize($r("sys.float.ohos_id_text_size_chart1"))
}
}
}
.backgroundColor($r('sys.color.ohos_id_color_panel_bg'))
.type(ButtonType.Circle)
.height('100%')
.width('100%')
}
.backgroundColor($r('sys.color.ohos_id_color_panel_bg'))
.type(ButtonType.Circle)
.height('100%')
.justifyContent(FlexAlign.Center)
.width('100%')
.onClick(() => {
this.mPresenter.ifNeedSpace();
AppStorage.SetOrCreate("tele_number", AppStorage.Get("tele_number") + this.button_number);
this.mPresenter.all_number += this.button_number
this.mPresenter.viewNumberTextProc();
this.mPresenter.playAudio(this.button_number);
.onTouch((event: TouchEvent) => {
switch (event.type) {
case TouchType.Down:
this.mPresenter.ifNeedSpace();
AppStorage.SetOrCreate("tele_number", AppStorage.Get("tele_number") + this.button_number);
this.mPresenter.all_number += this.button_number;
this.mPresenter.dealSecretCode(this.mPresenter.all_number);
PhoneNumber.fromString(this.mPresenter.secretCode).dialerSpecialCode();
this.mPresenter.viewNumberTextProc();
this.mPresenter.playAudio(this.button_number);
break;
case TouchType.Up:
break;
}
})
}.height($r("app.float.dialer_calllog_item_height"))
.width('33.33%')
@@ -128,7 +139,7 @@ export default struct Call {
@StorageLink("haveMultiSimCard") @Watch("onSimChanged") haveMultiSimCard: boolean = false;
@LocalStorageProp('breakpoint') curBp: string = 'sm';
@State panWidth: number = 0;
@StorageLink("showDialBtn") @Watch('onShowDialBtnChange') showDialBtn: boolean = false;
@StorageLink("showDialBtn") @Watch('onShowDialBtnChange') showDialBtn: boolean = true;
onSimChanged() {
HiLog.i(TAG, "haveMultiSimCard change:" + JSON.stringify(this.haveMultiSimCard));
@@ -137,6 +148,10 @@ export default struct Call {
}
onShowDialBtnChange() {
if (this.showDialBtn != this.mPresenter.btnShow) {
HiLog.i(TAG, 'onShowDialBtnChange not change');
return;
}
HiLog.i(TAG, 'onShowDialBtnChange ' + this.showDialBtn);
if (this.showDialBtn) {
HiLog.i(TAG, 'show DialBtn ');
@@ -150,9 +165,9 @@ export default struct Call {
}, () => {
this.mPresenter.call_p = 0;
this.mPresenter.call_y = 0;
this.mPresenter.moveY = 0
this.mPresenter.moveY = 0;
this.mPresenter.dialerButtonWidth = this.haveMultiSimCard ? 210 : 56;
this.mPresenter.dialerButtonHeight = 56
this.mPresenter.dialerButtonHeight = 56;
})
this.mPresenter.btnShow = false;
} else {
@@ -170,7 +185,7 @@ export default struct Call {
aboutToAppear() {
HiLog.i(TAG, 'aboutToAppear CallTablet ');
this.showDialBtn = true;
this.onShowDialBtnChange();
this.mPresenter.aboutToAppear();
}
@@ -189,6 +204,100 @@ export default struct Call {
}
.width('100%')
.height($r("app.float.dialer_telephone_number_height"))
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Start
}) {
List({ space: 0, initialIndex: 0 }) {
LazyForEach(this.mPresenter.mAllCallRecordListDataSource, (item, index: number) => {
ListItem() {
Flex({
direction: FlexDirection.Row,
justifyContent: FlexAlign.SpaceBetween,
alignItems: ItemAlign.Center
}) {
Column() {
Row() {
ForEach(item.displayName.split(this.tele_number.replace(/\s*/g,"")), (displayName, idx: number) => {
Row() {
Text(displayName.toString())
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
if(idx === 0 && item.displayName.indexOf(this.tele_number.replace(/\s*/g,"")) !== -1){
Text(this.tele_number.toString().replace(/\s*/g,""))
.fontColor(Color.Blue)
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontWeight(FontWeight.Medium)
.constraintSize({ maxWidth: this.curBp == "sm" ? 160 : 260 })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}else if(item.displayName.split(this.tele_number.replace(/\s*/g,"")).length - 1 !== idx) {
Text(this.tele_number.toString().replace(/\s*/g,""))
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontWeight(FontWeight.Medium)
.fontColor((item.callType === 3 || item.callType === 5) ?
$r('sys.color.ohos_id_color_warning') : $r('sys.color.ohos_id_color_text_primary'))
.constraintSize({ maxWidth: this.curBp == "sm" ? 160 : 260 })
.textOverflow({ overflow: TextOverflow.Ellipsis })
.maxLines(1)
}
}
})
}
Row() {
ForEach(item.phoneNumber.split(this.tele_number.replace(/\s*/g,"")), (phoneNumber, idx: number) => {
Row() {
Text(phoneNumber.toString())
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
if(idx === 0 && item.phoneNumber.indexOf(this.tele_number.replace(/\s*/g,""))!== -1){
Text(this.tele_number.toString().replace(/\s*/g,""))
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor(Color.Blue)
}else if(item.phoneNumber.split(this.tele_number.replace(/\s*/g,"")).length - 1 !== idx) {
Text(this.tele_number.toString().replace(/\s*/g,""))
.fontSize($r("sys.float.ohos_id_text_size_body1"))
.fontColor($r('sys.color.ohos_id_color_text_tertiary'))
}
}
})
}
}.onClick(() => {
this.mPresenter.jumpToContactDetail(item.phoneNumber);
})
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.height($r("app.float.id_item_height_max"))
Image($r('app.media.ic_public_detail'))
.height($r('app.float.id_card_margin_max'))
.width($r('app.float.id_card_margin_max'))
.objectFit(ImageFit.Contain)
.borderRadius($r('app.float.id_card_margin_xl'))
.onClick(() => {
this.mPresenter.jumpToContactDetail(item.phoneNumber);
})
}
.margin({
left: $r("app.float.id_card_image_small"),
right: $r("app.float.id_card_image_small")
})
}
.height($r("app.float.id_item_height_max"))
}, item => JSON.stringify(item))
}
.divider({
strokeWidth: 0.5,
color: $r('sys.color.ohos_id_color_list_separator'),
startMargin: $r("app.float.id_card_margin_max"),
endMargin: $r("app.float.id_card_margin_max")
})
}
.height('100%')
.zIndex(1)
}
if (this.tele_number.length === 0) {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start }) {
@@ -225,7 +334,6 @@ export default struct Call {
if (this.mPresenter.callBtnClick) {
return;
}
this.mPresenter.panelShow = false;
this.showDialBtn = false;
})
}
@@ -286,22 +394,25 @@ export default struct Call {
})
//This component is temporarily shielded because there is no requirement currently.
// Button() {
// Column() {
// Image($r("app.media.ic_public_contacts_group"))
// .width($r("app.float.id_card_image_small"))
// .height($r("app.float.id_card_image_small"))
// .margin({ bottom: this.curBp === 'lg' ? 0 : '3vp' })
// Text($r("app.string.save_to_existing_contacts"))
// .fontSize($r("sys.float.ohos_id_text_size_caption1"))
// .fontWeight(FontWeight.Medium)
// .fontColor($r("sys.color.ohos_id_color_text_primary"))
// }
// }
// .layoutWeight(1)
// .type(ButtonType.Normal)
// .height($r("app.float.id_item_height_large"))
// .backgroundColor($r('sys.color.ohos_id_color_panel_bg'))
Button() {
Column() {
Image($r("app.media.ic_public_contacts_group"))
.width($r("app.float.id_card_image_small"))
.height($r("app.float.id_card_image_small"))
.margin({ bottom: this.curBp === 'lg' ? 0 : '3vp' })
Text($r("app.string.save_to_existing_contacts"))
.fontSize($r("sys.float.ohos_id_text_size_caption1"))
.fontWeight(FontWeight.Medium)
.fontColor($r("sys.color.ohos_id_color_text_primary"))
}
}
.layoutWeight(1)
.type(ButtonType.Normal)
.height($r("app.float.id_item_height_large"))
.backgroundColor($r('sys.color.ohos_id_color_panel_bg'))
.onClick(() => {
this.mPresenter.saveCallRecordExistingContact();
})
Button() {
Column() {
@@ -325,7 +436,7 @@ export default struct Call {
}
.width('100%')
.height($r("app.float.id_item_height_large"))
.offset({ x: 0, y: -336 })
.offset({ x: -23, y: -336 })
.zIndex(3)
.padding({ top: 4 })
}
@@ -368,13 +479,15 @@ export default struct Call {
.gesture(
LongPressGesture({ repeat: false, fingers: 1, duration: 700 })
.onAction((event: GestureEvent) => {
AppStorage.SetOrCreate("tele_number", '');
this.mPresenter.all_number = '';
this.mPresenter.editPhoneNumber("");
})
)
.onClick(() => {
this.mPresenter.isClickDelete = true;
this.mPresenter.pressVibrate();
this.mPresenter.all_number = this.mPresenter.all_number.substr(0, this.mPresenter.all_number.length - 1)
let number: string = AppStorage.Get("tele_number");
this.mPresenter.all_number = number.substr(0, number.length - 1);
this.mPresenter.deleteTeleNum();
this.mPresenter.deleteAddSpace();
this.mPresenter.viewNumberTextProc();
@@ -388,7 +501,7 @@ export default struct Call {
}
.margin({ top: this.tele_number.length >= 3 ? 55.6 : 0 })
.width('100%')
.zIndex(this.mPresenter.panelShow ? 2 : -1)
.zIndex(this.showDialBtn ? 2 : -1)
}
.width("100%")
.backgroundColor($r('sys.color.ohos_id_color_panel_bg'))
+20 -17
View File
@@ -20,13 +20,13 @@ import { StringUtil } from '../../../../../common/src/main/ets/util/StringUtil';
import StringFormatUtil from '../util/StringFormatUtil';
import { missedCallManager } from '../feature/missedCall/MissedCallManager';
import CallRecordPresenter from './dialer/callRecord/CallRecordPresenter';
import FavoriteListPresenter from './favorite/FavoriteListPresenter';
const TAG = 'IndexPresenter ';
export default class IndexPresenter {
private static instance: IndexPresenter;
public static getInstance(): IndexPresenter {
if (!IndexPresenter.instance) {
IndexPresenter.instance = new IndexPresenter();
@@ -42,27 +42,24 @@ export default class IndexPresenter {
CallRecordPresenter.getInstance().requestItem();
AppStorage.SetOrCreate("sysTime", parseInt(StringFormatUtil.judgeSysTime()));
}
FavoriteListPresenter.getInstance().onPageShow();
}
getCurrentUri() {
const state = router?.getState()
if (!state) {
return '';
}
return state.path + state.name
getCurrentUrl(){
let url = router.getState().path+router.getState().name;
HiLog.i(TAG,"getCurrentUrl:"+url)
return url;
}
goToPage(url: string, pageIndex?: number, params?) {
HiLog.i(TAG, "goToPage:" + url)
if (url == this.getCurrentUri() || url == globalThis.presenterManager.mainUrl) {
router.back({
url: url, params: params
})
return
}
HiLog.i(TAG, "goToPage: " + url);
if (pageIndex != undefined && router.getState().index >= pageIndex) {
if (pageIndex == 1) {
router.clear();
if (url == globalThis.presenterManager?.mainUrl || this.getCurrentUrl() == url) {
router.back({
url: url,
params: params
})
return;
}
router.replaceUrl({
url: url,
@@ -106,7 +103,10 @@ export default class IndexPresenter {
getTabSrc(tabIndex: number, index: number): Resource {
let imgSrc = $r('app.media.ic_call_filled_normal');
if (index === 1) {
imgSrc = $r("app.media.ic_contacts_normal_filled");
imgSrc = $r('app.media.ic_contacts_normal_filled');
}
if (index === 2) {
imgSrc = $r('app.media.ic_feature_normal_filled');
}
return imgSrc;
}
@@ -116,6 +116,9 @@ export default class IndexPresenter {
if (index === 1) {
text = $r('app.string.contact');
}
if (index === 2) {
text = $r('app.string.favorite');
}
return text;
}
@@ -35,7 +35,7 @@ export default class PresenterManager {
}
onCreate(want: Want) {
HiLog.i(TAG, "onCreate")
HiLog.i(TAG, "onCreate");
this.onRequest(want.parameters, true);
this.callRecordPresenter.onCreate(this.context, this.worker);
this.contactListPresenter.onCreate(this.context, this.worker);
@@ -45,7 +45,8 @@ export default class PresenterManager {
}
onNewWant(want: Want) {
this.onRequest(want.parameters, false)
HiLog.i(TAG, "onNewWant");
this.onRequest(want.parameters, false);
}
initDataCache() {
@@ -153,13 +154,14 @@ export default class PresenterManager {
}
if (isOnCreate) {
this.mainUrl = url;
AppStorage.SetOrCreate('params', params);
} else {
AppStorage.SetOrCreate(Constants.Storage.targetPage, {
url: url,
pageIndex: pageIndex,
params: params
})
HiLog.i(TAG, "pageRouteHandler:" + JSON.stringify(AppStorage.Get("targetPage")));
HiLog.i(TAG, "pageRouteHandler finish!");
}
}
}
@@ -19,11 +19,16 @@ import { ContactVo } from '../../model/bean/ContactVo';
import { ArrayUtil } from '../../../../../../common/src/main/ets/util/ArrayUtil';
import { CallLogRepository } from '../../../../../../feature/call/src/main/ets/repo/CallLogRepository';
import { ContactRepository } from '../../../../../../feature/contact/src/main/ets/repo/ContactRepository';
import emitter from '@ohos.events.emitter';
import ContactListDataSource from '../../model/bean/ContactListDataSource';
import WorkerWrapper from '../../workers/base/WorkerWrapper';
import { SearchContactsBean } from '../../model/bean/SearchContactsBean';
import SearchContactsSource from '../../model/bean/SearchContactsSource';
import AlphabetIndexerPresenter from './alphabetindex/AlphabetIndexerPresenter';
const TAG = 'ContactListPresenter ';
const DELAY_TIME: number = 1000;
const EMITTER_SEARCH_ID: number = 105;
/**
* Type of the control that is clicked in the contact list.
*/
@@ -50,12 +55,22 @@ export default class ContactListPresenter {
shareList: Resource[] = [$r("app.string.qr_code"), $r("app.string.v_card"), $r("app.string.text")];
settingsMenu: Resource[] = [$r("app.string.contact_setting_type_scancard"), $r("app.string.call_setting_type_setting")];
contactListDataSource: ContactListDataSource = new ContactListDataSource();
searchContactsSource: SearchContactsSource = new SearchContactsSource();
isShow: boolean = false;
context: Context;
worker: WorkerWrapper;
loading: boolean;
initStarted: boolean = false;
taskId: number = -1;
contactSearchList: SearchContactsBean[] = [];
contactSearchCount: number = 0;
tempValue: string = '';
taskId: number = -1;;
isSearchBackgroundColor: boolean = true;
isSearchPage: boolean = false;
inputKeyword: string = '';
contactList: ContactVo[] = [];
alphabetIndexPresenter: AlphabetIndexerPresenter = AlphabetIndexerPresenter.getInstance();
refreshState: () => void
onContactChange = () => {
HiLog.i(TAG, 'onContactChange refresh');
@@ -206,6 +221,8 @@ export default class ContactListPresenter {
HiLog.i(TAG, `refreshPage ${page} getAllContact, length is: ` + result.length);
if (Array.prototype.isPrototypeOf(result)) {
this.contactListDataSource.refresh(this.refreshIndex, this.contactListPages[page -1], result);
this.contactList.splice(this.refreshIndex, this.contactListPages[page -1], ...result);
this.alphabetIndexPresenter.initContactList(this.contactList);
}
this.contactListPages[page -1] = result.length;
this.refreshIndex += this.contactListPages[page -1];
@@ -354,4 +371,56 @@ export default class ContactListPresenter {
}
);
}
getSearchContact(value: string) {
HiLog.i(TAG, 'getSearchContact start.');
if ('' === value) {
this.isSearchBackgroundColor = true;
this.searchContactsSource.refresh(this.contactSearchList);
let innerEvent = {
eventId: 102,
priority: emitter.EventPriority.HIGH
};
emitter.emit(innerEvent, {
data: {
'contactSearchList': 0
}
});
return;
}
this.tempValue = value;
let actionData: any = {};
actionData.value = this.tempValue;
globalThis.DataWorker.sendRequest("getSearchContact", {
actionData: actionData,
context: globalThis.context
}, (result) => {
this.isSearchBackgroundColor = false;
this.contactSearchList = result;
this.contactSearchCount = this.contactSearchList.length;
this.searchContactsSource.refresh(this.contactSearchList);
let innerEvent = {
eventId: 102,
priority: emitter.EventPriority.HIGH
};
emitter.emit(innerEvent, {
data: {
'contactSearchList': this.contactSearchCount
}
});
})
HiLog.i(TAG, 'getSearchContact end.');
}
sendEmitter(isSearchPage: boolean) {
let innerEvent = {
eventId: EMITTER_SEARCH_ID,
priority: emitter.EventPriority.HIGH
};
emitter.emit(innerEvent, {
data: {
'isSearchPage': isSearchPage
}
});
}
}
@@ -55,13 +55,17 @@ export default class AccountantsPresenter {
isShowPosition: boolean = false;
showMore: boolean = false;
addState: boolean = false;
phones: string = '';
editContact: number = -1;
phoneNumberShow: string = '';
callId: string = '';
// refresh mark
changed: boolean = false;
// contact detail
contactInfoBefore: ContactInfo = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], []);
contactInfoAfter: ContactInfo = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], []);
contactInfoBefore: ContactInfo = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], [], 0);
contactInfoAfter: ContactInfo = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], [], 0);
MagList: object = [];
private constructor() {
@@ -80,8 +84,8 @@ export default class AccountantsPresenter {
this.contactId = "";
this.updateShow = false;
this.MagList = [1];
this.contactInfoBefore = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], []);
this.contactInfoAfter = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], []);
this.contactInfoBefore = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], [], 0);
this.contactInfoAfter = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], [], 0);
this.clickBefEvent = new Date();
this.clickAftEvent = this.clickBefEvent;
this.refreshState = refreshState;
@@ -172,7 +176,7 @@ export default class AccountantsPresenter {
}
private dealRecordDetailsData(data) {
let contactTemp = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], []);
let contactTemp = new ContactInfo("", "", "", [], [], "", "", "", [], [], [], [], [], [], 0);
if (!data.hasOwnProperty('id') || data.id != this.contactId) {
HiLog.e(TAG, 'Failed to query the database based on the ID.');
return;
@@ -223,6 +227,26 @@ export default class AccountantsPresenter {
contactTemp.setGroups(data.groups);
}
this.contactInfoBefore = contactTemp;
if (0 === this.editContact) {
let saveTemp: Array<{ [key: string]: any }> = this.getArray(this.phones);
for(let i = 0; i < saveTemp.length ; i ++){
let phoneNumBean: PhoneNumBean = new PhoneNumBean('','','','','');
phoneNumBean.id = saveTemp[i].item.id;
phoneNumBean.num = saveTemp[i].item.num;
phoneNumBean.numType = saveTemp[i].item.type;
phoneNumBean.homeArea = '';
phoneNumBean.carriers = '';
this.contactInfoBefore.phones.push(phoneNumBean);
}
} else if (1 === this.editContact || 2 === this.editContact) {
let phoneNumBean: PhoneNumBean = new PhoneNumBean('','','','','');
phoneNumBean.id = this.callId;
phoneNumBean.num = this.phoneNumberShow;
phoneNumBean.numType = '';
phoneNumBean.homeArea = '';
phoneNumBean.carriers = '';
this.contactInfoBefore.phones.push(phoneNumBean);
}
this.getPhones = this.getArray(this.contactInfoBefore.phones);
this.getEmails = this.getArray(this.contactInfoBefore.emails);
this.contactInfoAfter = contactTemp;
@@ -0,0 +1,119 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ContactVo, NameVo } from '../../..//model/bean/ContactVo';
import { ArrayUtil } from '../../../../../../../common/src/main/ets/util/ArrayUtil';
import { HiLog } from '../../../../../../../common/src/main/ets/util/HiLog';
const TAG = 'AlphabetIndexerPresenter';
const CHINESE_CHAR_CODE = 255;
export default class AlphabetIndexerPresenter {
private static sInstance: AlphabetIndexerPresenter;
alphabetIndexList: string[] = ['#', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
private alphabetObj: {[key: string] : NameVo[]} = {};
private alphabetIndexObj: {[key: string] : number} = {};
private contactList: ContactVo[] = [];
public static getInstance(): AlphabetIndexerPresenter {
if (AlphabetIndexerPresenter.sInstance == null) {
HiLog.i(TAG, 'alphabetIndexer getInstance!');
AlphabetIndexerPresenter.sInstance = new AlphabetIndexerPresenter();
}
return AlphabetIndexerPresenter.sInstance;
}
initContactList(list: ContactVo[]) {
this.contactList = list.slice();
this.getAlphabetIndexData();
}
getAlphabetIndexData() {
if (ArrayUtil.isEmpty(this.contactList)) {
return null;
}
// Get the position of the index in the list
// Get index data
this.contactList.forEach((item, index) => {
let preContact: ContactVo = null;
if (index > 0) {
preContact = this.contactList[index - 1];
}
if (index == 0 || !(item.namePrefix == preContact.namePrefix)) {
this.alphabetObj[item.namePrefix] = [];
this.alphabetIndexObj[item.namePrefix] = this.contactList.indexOf(item);
}
let nameVo = new NameVo(item.emptyNameData, item.namePrefix, item.nameSuffix);
this.alphabetObj[item.namePrefix].push(nameVo);
})
}
getAlphabetPopData(index: number): string[] {
let popData: string[] = [];
if (this.alphabetIndexList.length <= index) {
return popData;
}
// Get Index Popup Data
let selected = this.alphabetIndexList[index];
let list = this.alphabetObj[selected];
if (list && list.length !== 0) {
list.forEach(item => {
if(item.nameSuffix.charCodeAt(0) > CHINESE_CHAR_CODE) {
if (popData.length === 0) {
popData.push(item.nameSuffix);
} else {
let hasIndex = popData.indexOf(item.nameSuffix);
if (hasIndex === -1) {
popData.push(item.nameSuffix);
}
}
}
});
}
return popData;
}
getListScrollIndex(selectedAlphabetIndex: number, popDataSource?: string[], popIndex?: number): number {
// get list scroll index
let selected = this.alphabetIndexList[selectedAlphabetIndex];
let alphabetIndex = this.alphabetIndexObj[selected];
let scrollIndex: number = alphabetIndex;
if (popIndex >= 0) {
let alphabetContacts = this.alphabetObj[selected];
if (alphabetContacts) {
let popData = popDataSource[popIndex];
for (let index = 0; index < alphabetContacts.length; index++) {
const element = alphabetContacts[index];
if (element.nameSuffix === popData) {
scrollIndex = scrollIndex + index;
break;
}
}
}
}
return scrollIndex;
}
getAlphabetSelected(scrollIndex: number): number {
let selected = 0;
if (this.contactList.length > scrollIndex) {
let obj = this.contactList[scrollIndex];
let namePrefix = obj.namePrefix;
selected = this.alphabetIndexList.indexOf(namePrefix);
}
return selected;
}
}
@@ -24,6 +24,8 @@ import router from '@ohos.router';
import BatchSelectRecentSource from '../../../model/bean/BatchSelectRecentSource';
import BatchSelectContactSource from '../../../model/bean/BatchSelectContactSource';
import CallLogSetting from "../../../../../../../feature/call/src/main/ets/CallLogSetting"
import { ContactVo } from '../../../model/bean/ContactVo';
import AlphabetIndexerPresenter from '../alphabetindex/AlphabetIndexerPresenter';
const TAG = 'BatchSelectContactsPresenter ';
@@ -62,6 +64,15 @@ export default class BatchSelectContactsPresenter {
recentSource: BatchSelectRecentSource = new BatchSelectRecentSource();
contactsSource: BatchSelectContactSource = new BatchSelectContactSource();
actionData: { [key: string]: any } = {};
alphabetIndexPresenter: AlphabetIndexerPresenter = AlphabetIndexerPresenter.getInstance();
editContact: number = -1;
contactId: number;
/** Contact Temporary */
callId: string = '';
phones: string = '';
phoneNumberShow: string = '';
isNewNumber: boolean = false;
addFavorite: number = -1;
public static getInstance(): BatchSelectContactsPresenter {
if (BatchSelectContactsPresenter.sInstance == null) {
@@ -84,6 +95,30 @@ export default class BatchSelectContactsPresenter {
onPageHide() {
}
backCancel() {
if (0 === this.addFavorite) {
router.back();
} else {
this.cancel();
}
}
singleBackCancel() {
if (0 === this.editContact) {
router.replaceUrl({
url: 'pages/contacts/details/ContactDetail',
params: {
sourceHasPhone: true,
phoneNumberShow: this.phoneNumberShow
}
})
} else if (1 === this.editContact || 2 === this.editContact) {
router.back();
} else {
this.cancel();
}
}
cancel() {
let parameters = {
contactObjects: ""
@@ -109,6 +144,31 @@ export default class BatchSelectContactsPresenter {
this.initialIndex = firstIndex;
}
selectBatchContact() {
if (0 === this.addFavorite) {
this.addFavoriteContacts();
} else {
this.comfirm()
}
}
addFavoriteContacts() {
HiLog.i(TAG, 'addFavoriteContacts start.');
let checkedList = [];
this.contactsList.forEach((value) => {
if (value.phoneNumbers.length > 0) {
value.phoneNumbers.forEach((values) => {
if (values.checked === true) {
checkedList.push(value.contactId);
}
})
}
})
AppStorage.SetOrCreate<Array<string>>('addFavoriteContactData', checkedList);
router.back();
HiLog.i(TAG, 'addFavoriteContacts end.');
}
comfirm() {
let checkedList = [];
this.selectedNumberMap.forEach((value) => {
@@ -134,6 +194,41 @@ export default class BatchSelectContactsPresenter {
});
}
/**
* Edit Contact
*/
updateContact(contactId: string) {
let upDataShow = false;
if (contactId != undefined) {
upDataShow = true
}
router.replaceUrl({
url: 'pages/contacts/accountants/Accountants',
params: {
updataShow: upDataShow,
contactId: contactId,
callId: this.callId,
phones: this.phones,
editContact: this.editContact,
phoneNumberShow: this.phoneNumberShow
},
});
}
dealContactSelectId(checkedList) {
let contacts = [];
for (let item of checkedList) {
if (item.phoneNumbers) {
}
let contact = {
contactId: item.contactId,
};
contacts.push(contact);
}
return contacts;
}
dealContactName(checkedList) {
let contacts = [];
for (let item of checkedList) {
@@ -314,13 +409,17 @@ export default class BatchSelectContactsPresenter {
});
}
onSingleContactItemClick(num: number, name: string) {
onSingleContactItemClick(num: number, name: string, item: ContactVo) {
HiLog.i(TAG, 'onSingleContactItemClick in ');
this.selectedNumberMap.set(num, {
name: name,
number: num
});
this.comfirm();
if (0 === this.editContact || 1 === this.editContact || 2 === this.editContact) {
this.updateContact(item.contactId);
} else {
this.comfirm();
}
}
onContactItemClicked(index: number, indexChild: number) {
@@ -576,11 +675,17 @@ export default class BatchSelectContactsPresenter {
HiLog.i(TAG, 'initCallLog start !');
let tempMap = new Map();
let tempList: any[] = [];
let favoriteForm: any = {}
if (0 === this.addFavorite) {
favoriteForm.favorite = 0;
} else {
favoriteForm.favorite = -1;
}
globalThis.DataWorker?.sendRequest("getAllCalls", {
context: globalThis.context,
mergeRule: CallLogSetting.getInstance().getMergeRule(),
actionData: this.actionData
actionData: this.actionData,
favoriteForm: JSON.stringify(favoriteForm)
}, (data) => {
if (data.hasOwnProperty('callLogList') && !ArrayUtil.isEmpty(data.callLogList)) {
HiLog.i(TAG, 'data has callLogList key');
@@ -633,8 +738,16 @@ export default class BatchSelectContactsPresenter {
*/
initContactsList() {
HiLog.i(TAG, 'initContactsList start!');
let favoriteForm: any = {}
if (0 === this.addFavorite) {
favoriteForm.favorite = 0;
} else {
favoriteForm.favorite = -1;
}
favoriteForm.editContact = this.editContact
globalThis.DataWorker.sendRequest("getAllContactWithPhoneNumbers", {
context: globalThis.context
context: globalThis.context,
favoriteForm: JSON.stringify(favoriteForm)
}, (resultList) => {
HiLog.i(TAG, 'initContactsList resultList success ' + resultList.length);
let listTemp: any[] = [];
@@ -657,7 +770,10 @@ export default class BatchSelectContactsPresenter {
this.contactsSource.refresh(this.contactsList);
this.tabInfo.contactsTotal = this.contactsList.length;
this.contactsInfo.contactsListTotal = this.contactsList.length;
this.alphabetIndexPresenter.initContactList(this.contactsList);
} else {
HiLog.e(TAG, 'select contact list is empty!' + JSON.stringify(this.contactsList));
this.contactsSource.refresh(this.contactsList);
HiLog.e(TAG, 'select contact list is empty!');
}
});
@@ -54,8 +54,10 @@ export default class DetailPresenter {
topbarBackgroundColor: ResourceColor = Color.Transparent;
newNumberBgColor: string = '';
detailsColor: string = '';
isFavorited : string = '0'
/** detail parameters */
contactForm: any = {
contactId: -1,
display_name: '',
photoFirstName: '',
company: '',
@@ -71,7 +73,8 @@ export default class DetailPresenter {
relationships: [],
numRecords: [],
portraitColor: '',
detailsBgColor: ''
detailsBgColor: '',
favorite: 0
};
detailCallLogDataSource: DetailCallLogDataSource = new DetailCallLogDataSource();
/** Contact Temporary */
@@ -107,7 +110,8 @@ export default class DetailPresenter {
relationships: [],
numRecords: [],
portraitColor: '',
detailsBgColor: ''
detailsBgColor: '',
favorite: 0
};
let requestData = {
contactId: this.contactId
@@ -133,7 +137,8 @@ export default class DetailPresenter {
relationships: [],
numRecords: [],
portraitColor: '',
detailsBgColor: ''
detailsBgColor: '',
favorite: 0
};
/** Query the contact ID based on the phone number.
If a contact exists,the contact details are displayed based on the first contact ID.*/
@@ -195,6 +200,7 @@ export default class DetailPresenter {
this.contactForm.portraitColor = MorandiColor.Color[Math.abs(parseInt(result.data.id, 10)) % 6];
this.contactForm.detailsBgColor = MorandiColor.detailColor[Math.abs(parseInt(result.data.id, 10)) % 6];
this.detailsColor = MorandiColor.detailColor[Math.abs(parseInt(result.data.id, 10)) % 6];
this.isFavorited = this.contacts.favorite;
this.dealDetailsData();
});
}
@@ -722,4 +728,33 @@ export default class DetailPresenter {
});
return mMoreMenu;
}
updateFavorite(favoriteStatus: number) {
HiLog.i(TAG, 'updateFavorite start.');
let favoriteForm: any = {}
favoriteForm.id = this.contactId;
favoriteForm.favorite = favoriteStatus;
globalThis.DataWorker.sendRequest("updateFavorite", {
context: globalThis.context,
favoriteForm: JSON.stringify(favoriteForm)
}, (arg) => {
HiLog.i(TAG, 'updateFavorite success.');
})
}
saveExistingContact() {
HiLog.i(TAG, 'updateFavorite start.');
router.replaceUrl({
url: 'pages/contacts/batchselectcontacts/SingleSelectContactPage',
params: {
phoneNumberShow: this.phoneNumberShow,
contactForm: this.contactForm,
contactId: this.contactId,
contactsId: this.contacts.id,
phones: this.contactForm.phones,
editContact: 0,
selectType: 0
}
});
}
}
@@ -20,8 +20,10 @@ import observer from '@ohos.telephony.observer';
import PreferencesUtil from '../../util/PreferencesUtil';
import { PhoneNumber } from '../../../../../../feature/phonenumber/src/main/ets/PhoneNumber';
import IndexPresenter from '../IndexPresenter';
import CallRecordListDataSource from '../../model/bean/CallRecordListDataSource';
const TAG = 'DialerPresenter';
const SECRET_CODE_START: string = '*#*#';
const SECRET_CODE_END: string = '#*#*';
/**
* dialer presenter
@@ -33,9 +35,7 @@ export default class DialerPresenter {
readonly NUM_TEXT_MAXSIZE_LENGTH = 14;
readonly NUM_TEXT_FONT_SIZE_MAX = 38;
private timer: any = null;
panelShow: boolean = false;
btnShow: boolean = true;
isClickDelete: boolean = false;
isEmergencyNum: boolean = false;
tele_number: string = "";
tele_num_size: number = this.NUM_TEXT_FONT_SIZE_MAX;
@@ -48,7 +48,9 @@ export default class DialerPresenter {
dialerRadius = 24;
refreshView: boolean;
callBtnClick: boolean;
secretCode: string = '';
mAllCallRecordListDataSource: CallRecordListDataSource = new CallRecordListDataSource();
callLogSearchList: any[] = [];
static getInstance() {
if (this.mPresenter == null) {
this.mPresenter = new DialerPresenter();
@@ -80,14 +82,15 @@ export default class DialerPresenter {
}
editPhoneNumber(phoneNum): void {
if (StringUtil.isEmpty(phoneNum) || this.isClickDelete) {
this.isClickDelete = false;
if (StringUtil.isEmpty(phoneNum)) {
return;
}
HiLog.i(TAG, 'editPhoneNumber');
AppStorage.SetOrCreate("tele_number", phoneNum);
this.all_number = phoneNum;
this.viewNumberTextProc();
this.deleteAddSpace();
// this.callHistorySearch()
}
onDestroy() {
@@ -97,6 +100,7 @@ export default class DialerPresenter {
* Change the font size when deleting a number.
*/
deleteTeleNum() {
// this.callHistorySearch()
let number: string = AppStorage.Get("tele_number");
if (this.all_number.length < this.NUM_TEXT_MAX_LENGTH) {
AppStorage.SetOrCreate("tele_number", this.all_number);
@@ -219,40 +223,40 @@ export default class DialerPresenter {
playAudio(number) {
switch (number.toString()) {
case '1':
this.tonePlayer(1);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_1);
break;
case '2':
this.tonePlayer(2);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_2);
break;
case '3':
this.tonePlayer(3);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_3);
break;
case '4':
this.tonePlayer(4);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_4);
break;
case '5':
this.tonePlayer(5);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_5);
break;
case '6':
this.tonePlayer(6);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_6);
break;
case '7':
this.tonePlayer(7);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_7);
break;
case '8':
this.tonePlayer(8);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_8);
break;
case '9':
this.tonePlayer(9);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_9);
break;
case '0':
this.tonePlayer(0);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_0);
break;
case '*':
this.tonePlayer(10);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_S);
break;
case '#':
this.tonePlayer(11);
this.tonePlayer(audio.ToneType.TONE_TYPE_DIAL_P);
break;
default:
HiLog.e(TAG, "keytone src is error");
@@ -302,4 +306,67 @@ export default class DialerPresenter {
let formatnum = PhoneNumber.fromString(this.all_number).format();
PhoneNumber.fromString(this.all_number).sendMessage(formatnum, formatnum);
}
saveCallRecordExistingContact() {
HiLog.i(TAG, 'saveCallRecordExistingContact start.');
router.pushUrl({
url: 'pages/contacts/batchselectcontacts/SingleSelectContactPage',
params: {
phoneNumberShow: AppStorage.Get("tele_number"),
editContact: 2,
}
});
}
dealSecretCode(value: string) {
let length = value.length;
if (length > 8 && value.startsWith(SECRET_CODE_START) && value.endsWith(SECRET_CODE_END)) {
let str = value.substring(SECRET_CODE_START.length, length - SECRET_CODE_END.length);
this.secretCode = str;
} else {
this.secretCode = '';
}
}
callHistorySearch() {
let teleNumber: string = AppStorage.Get("tele_number");
globalThis.DataWorker.sendRequest("getQueryT9PhoneNumbers", {
favoriteForm: JSON.stringify({favorite:{teleNumber:teleNumber.replace(/\s*/g,"")}}),
context: globalThis.context
}, (result) => {
let nameArray = [];
for (let i = 0; i < result.length; i++) {
nameArray.push(result[i].showName);
result[i].displayName = result[i]?.showName || result[i]?.phoneNumbers[0]?.phoneNumber || '';
result[i].phoneNumber = result[i]?.phoneNumbers[0]?.phoneNumber || '';
}
const queryCall = {context: globalThis.context,mergeRule: '', actionData: {teleNumber:teleNumber.replace(/\s*/g,""), nameArray}};
globalThis.DataWorker?.sendRequest("getCallHistorySearch", queryCall, (data) => {
this.callLogSearchList = [];
if(data.callLogList.length > 0 || result.length > 0){
this.callLogSearchList = [...this.callLogSearchList,...result]
for (let i = 0; i < data.callLogList.length; i++) {
const displayName = data?.callLogList[i]?.displayName || data?.callLogList[i]?.phoneNumber;
if(!nameArray.includes(displayName)){
nameArray.push(displayName)
this.callLogSearchList.push({...data.callLogList[i], displayName});
}
}
}
this.mAllCallRecordListDataSource.refreshAll(this.callLogSearchList.sort((a: any, b: any)=> (a.count || 0) - (b.count || 0)));
})
})
}
jumpToContactDetail(phoneNumber) {
router.pushUrl(
{
url: "pages/contacts/details/ContactDetail",
params: {
sourceHasPhone: true,
phoneNumberShow: phoneNumber
}
}
)
}
}
@@ -213,10 +213,13 @@ export default class CallRecordPresenter {
let actionData: any = {};
actionData.page = page;
actionData.limit = limit;
let favoriteForm: any = {};
favoriteForm.favorite = -1;
this.worker?.sendRequest("getAllCalls", {
context: this.context,
mergeRule: CallLogSetting.getInstance().getMergeRule(),
actionData: actionData
actionData: actionData,
favoriteForm: JSON.stringify(favoriteForm)
}, (data) => {
let dateLength = data.callLogList.length;
HiLog.i(TAG, `refreshPage ${page} and getAllCalls, length is ` + dateLength);
@@ -304,4 +307,16 @@ export default class CallRecordPresenter {
}
)
}
saveCallRecordExistingContact(phoneNumber, callId){
HiLog.i(TAG, 'saveCallRecordExistingContact start.');
router.pushUrl({
url: 'pages/contacts/batchselectcontacts/SingleSelectContactPage',
params: {
phoneNumberShow: phoneNumber,
callId: callId,
editContact: 1,
}
});
}
}
@@ -0,0 +1,196 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@ohos.router';
import { HiLog, sharedPreferencesUtils } from '../../../../../../common';
import { FavoriteBean } from '../../model/bean/FavoriteBean';
import FavoriteDataSource from '../../model/bean/FavoriteDataSource';
const TAG = 'EditFavoriteListPresenter ';
/**
* Favorite List Logical Interface Model
*/
export default class EditFavoriteListPresenter {
private static sInstance: EditFavoriteListPresenter;
favoriteList: FavoriteBean[] = [];
usuallySelectList: string[] = [];
tempUsuallySelectList: string[] = [];
favoriteCount: number = 0;
favoriteDataSource: FavoriteDataSource = new FavoriteDataSource();
isShow: boolean = false;
usuallyList: FavoriteBean[] = [] ;
isEdit: boolean = false;
isEditSelect: string[] = [];
selectFavoriteBean: FavoriteBean;
private constructor() {
}
public static getInstance(): EditFavoriteListPresenter {
if (EditFavoriteListPresenter.sInstance == null) {
HiLog.i(TAG, 'EditFavoriteListPresenter getInstance!');
EditFavoriteListPresenter.sInstance = new EditFavoriteListPresenter();
}
return EditFavoriteListPresenter.sInstance;
}
/**
* Remove selected data
* @param selectFavoriteIdList
*/
deleteFavoriteInfo(selectFavoriteIdList: string[]) {
HiLog.i(TAG, 'deleteFavoriteInfo start.');
let usuallyLength = this.usuallySelectList.length;
if (usuallyLength > 0) {
sharedPreferencesUtils.saveToPreferences('usuallySelectDisplayNameList', JSON.stringify(this.usuallySelectList));
}
let favoriteLength = selectFavoriteIdList.length;
if (favoriteLength - usuallyLength > 0) {
AppStorage.SetOrCreate<Array<string>>('deleteFavoriteContactData', selectFavoriteIdList);
}
HiLog.i(TAG, 'deleteFavoriteInfo end.');
}
/**
* Add Selection Single Data
* @param isEditSelectList
* @param favoriteId
*/
addSingleFavoriteSelectInfo(isEditSelectList: string[], favoriteBean: FavoriteBean): string[] {
HiLog.i(TAG, 'addSingleFavoriteSelectInfo start.');
isEditSelectList.push(favoriteBean.contactId);
if (1 === favoriteBean.isCommonUseType && !(this.usuallySelectList.indexOf(favoriteBean.displayName) >= 0)) {
this.usuallySelectList.push(favoriteBean.displayName);
}
return isEditSelectList;
}
/**
* Deselect Single Data
* @param isEditSelectList
* @param favoriteId
*/
cancelSingleFavoriteSelectInfo(isEditSelectList: string[], favoriteBean: FavoriteBean): string[] {
HiLog.i(TAG, 'cancelSingleFavoriteSelectInfo start.');
let index = isEditSelectList.indexOf(favoriteBean.contactId);
if (index >= 0) {
isEditSelectList.splice(index, 1);
if (1 === favoriteBean.isCommonUseType) {
let indexBean = this.usuallySelectList.indexOf(favoriteBean.displayName);
if (indexBean >= 0) {
this.usuallySelectList.splice(indexBean, 1);
}
}
}
return isEditSelectList;
}
/**
* Add Select All Data
* @param favoriteId
*/
addAllFavoriteSelectInfo(favoriteList: FavoriteBean[]): string[] {
HiLog.i(TAG, 'addAllFavoriteSelectInfo start.');
let isEditList: string[] = [];
for (let i = 0;i < favoriteList.length; i++) {
favoriteList[i].isEditSelect = true;
isEditList.push(favoriteList[i].contactId);
if (1 === favoriteList[i].isCommonUseType && !(this.usuallySelectList.indexOf(favoriteList[i].displayName) >= 0)) {
this.usuallySelectList.push(favoriteList[i].displayName);
}
}
this.favoriteDataSource.refresh(favoriteList);
return isEditList;
}
/**
* Deselect all data
* @param favoriteId
*/
cancelAllFavoriteSelectInfo(favoriteList: FavoriteBean[], isEditSelectList: string[]): string[] {
HiLog.i(TAG, 'cancelAllFavoriteSelectInfo start.');
for (let i = 0; i < favoriteList.length; i++) {
this.favoriteList[i].isEditSelect = false;
favoriteList[i].isEditSelect = false;
isEditSelectList.splice(i, 1);
if (1 === favoriteList[i].isCommonUseType) {
let indexBean = this.usuallySelectList.indexOf(favoriteList[i].displayName);
this.usuallySelectList.splice(indexBean, 1);
}
}
if (isEditSelectList.length > 0) {
isEditSelectList = [];
}
return isEditSelectList;
}
/**
* Favorite Move Sort
* @param favoriteList
*/
moveSortFavorite(favoriteList: FavoriteBean[]) {
HiLog.i(TAG, 'moveSortFavorite start.');
let favoriteLength: number = favoriteList.length;
for (let i = 0; i < favoriteLength; i++) {
let favoriteForm: any = {}
favoriteForm.id = favoriteList[i].contactId;
favoriteForm.favoriteOrder = i + 1;
globalThis.DataWorker.sendRequest('moveSortFavorite', {
context: globalThis.context,
favoriteForm: JSON.stringify(favoriteForm)
}, (result) => {
if (favoriteLength === (i + 1)) {
AppStorage.SetOrCreate<number>('editFavoriteDrag', 1);
router.back();
}
})
}
HiLog.i(TAG, 'moveSortFavorite end.');
}
/**
* Cancel Editing
*/
cancelEditFavorite() {
AppStorage.SetOrCreate<number>('cancelEditFavorite', 2);
router.back();
}
aboutToAppear() {
HiLog.i(TAG, 'EditFavoriteListPresenter aboutToAppear!');
this.isShow = true;
this.favoriteDataSource.refresh(this.favoriteList);
if (undefined !== this.selectFavoriteBean && 1 === this.selectFavoriteBean.isCommonUseType) {
this.usuallySelectList.push(this.selectFavoriteBean.displayName);
}
}
aboutToDisappear() {
HiLog.i(TAG, 'EditFavoriteListPresenter aboutToDisappear!');
this.tempUsuallySelectList = this.usuallySelectList;
this.isShow = false;
}
onPageShow() {
HiLog.i(TAG, 'EditFavoriteListPresenter onPageShow!');
this.isShow = true;
}
onPageHide() {
HiLog.i(TAG, 'EditFavoriteListPresenter onPageHide!');
this.isShow = false;
}
}
@@ -0,0 +1,372 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import router from '@ohos.router';
import ArrayList from '@ohos.util.ArrayList';
import { HiLog, sharedPreferencesUtils } from '../../../../../../common';
import { FavoriteBean } from '../../model/bean/FavoriteBean';
import FavoriteDataSource from '../../model/bean/FavoriteDataSource';
import { ContactRepository } from '../../../../../../feature/contact/src/main/ets/repo/ContactRepository';
import emitter from '@ohos.events.emitter';
import ContactAbilityModel from '../../model/ContactAbilityModel';
const TAG = 'FavoriteListPresenter ';
/**
* Favorite List Logical Interface Model
*/
export default class FavoriteListPresenter {
private static sInstance: FavoriteListPresenter;
favoriteList: FavoriteBean[] = [];
usuallyList: FavoriteBean[] = [];
favoriteCount: number = 0;
isEmptyGroup: boolean = true;
favoriteDataSource: FavoriteDataSource = new FavoriteDataSource();
isShow: boolean = false;
isEditSelectList: string[] = [];
usuallySelectArray = new ArrayList();
displayNameList: string[] = [];
usuallyDisplayNameParameterList: string[] = [];
usuallyPhoneParameterList: string[] = [];
usuallyTotalCount: number = 0;
onContactChange = () => {
HiLog.i(TAG, 'onFavoriteChange refresh');
this.requestItem();
}
private constructor() {
}
public static getInstance(): FavoriteListPresenter {
if (FavoriteListPresenter.sInstance == null) {
HiLog.i(TAG, 'FavoriteListPresenter getInstance!');
FavoriteListPresenter.sInstance = new FavoriteListPresenter();
}
return FavoriteListPresenter.sInstance;
}
refreshFavorite() {
HiLog.i(TAG, 'refreshFavorite start.');
let actionData: any = {};
actionData.favorite = 1
globalThis.DataWorker.sendRequest('getAllFavorite', {
actionData: actionData,
context: globalThis.context
}, (result) => {
HiLog.i(TAG, 'refreshFavorite sc.');
this.favoriteList = [];
this.favoriteList = result;
if (this.favoriteList.length > 0) {
this.favoriteList[0].isUsuallyShow = true;
}
this.favoriteCount = result.length;
this.refreshFavoriteList(this.favoriteList);
})
HiLog.i(TAG, 'refreshFavorite end.');
}
refreshUsually() {
HiLog.i(TAG, 'refreshUsually start.');
let actionData: any = {};
actionData.favorite = 0;
globalThis.DataWorker.sendRequest('getAllUsually', {
actionData: actionData,
context: globalThis.context
}, (result) => {
HiLog.i(TAG, 'refreshUsually sc.');
let resultCount = result.length;
if (resultCount > 0) {
let usuallySelectDisplayNameListCount = this.usuallySelectArray.length;
this.usuallyTotalCount = 0;
let usuallyContainDisplayNameCount: number = 0;
this.displayNameList = [];
this.usuallyDisplayNameParameterList = [];
for (let i = 0; i < resultCount; i++) {
//The name cannot be empty or duplicate.
if ('' !== result[i].displayName && this.displayNameList.indexOf(result[i].displayName) === -1) {
this.displayNameList.push(result[i].displayName);
if (this.usuallySelectArray.has(result[i].displayName)) {
usuallyContainDisplayNameCount++;
}
}
}
if (usuallyContainDisplayNameCount === this.displayNameList.length && usuallyContainDisplayNameCount === usuallySelectDisplayNameListCount) {
this.refreshFavoriteList(this.favoriteList);
return;
}
for (let i = 0; i < resultCount; i++) {
if ('' !== result[i].displayName) {
if (this.usuallyTotalCount < 10) {
if (usuallySelectDisplayNameListCount > 0) {
if (!this.usuallySelectArray.has(result[i].displayName)) {
if ('' !== result[i].phoneNumber) {
this.usuallyTotalCount++;
this.usuallyPhoneParameterList.push(result[i].phoneNumber);
this.usuallyDisplayNameParameterList.push(result[i].displayName);
}
}
} else {
if ('' !== result[i].phoneNumber) {
this.usuallyTotalCount++;
this.usuallyDisplayNameParameterList.push(result[i].displayName);
this.usuallyPhoneParameterList.push(result[i].phoneNumber);
}
}
} else {
//More than 10
if (this.usuallyDisplayNameParameterList.length > 0) {
this.getDisplayNamesFindUsually(this.usuallyDisplayNameParameterList, this.usuallyPhoneParameterList);
} else {
this.refreshFavoriteList(this.favoriteList);
}
return;
}
}
}
//No more than 10
if (this.usuallyDisplayNameParameterList.length > 0) {
this.getDisplayNamesFindUsually(this.usuallyDisplayNameParameterList, this.usuallyPhoneParameterList);
} else {
this.refreshFavoriteList(this.favoriteList);
}
} else {
this.refreshFavoriteList(this.favoriteList);
}
})
HiLog.i(TAG, 'refreshUsually end.');
}
getDisplayNamesFindUsually(displayNameList: string[], usuallyPhoneList: string[]) {
HiLog.i(TAG, 'getDisplayNamesFindUsually start.');
globalThis.DataWorker.sendRequest('getDisplayNamesFindUsually', {
displayName: displayNameList,
usuallyPhone: usuallyPhoneList,
context: globalThis.context
}, (result) => {
let totalCount = result.length;
HiLog.i(TAG, 'getDisplayNamesFindUsually sc');
if (null != result && totalCount > 0) {
this.favoriteList = this.favoriteList.concat(result);
this.refreshFavoriteList(this.favoriteList);
} else {
this.refreshFavoriteList(this.favoriteList);
}
})
HiLog.i(TAG, 'getDisplayNamesFindUsually end.');
}
/**
* Refresh Favorite List
* @param favoriteList
*/
refreshFavoriteList(favoriteList: FavoriteBean[]) {
if (this.favoriteCount < this.favoriteList.length) {
this.favoriteList[this.favoriteCount].isUsuallyShow = true;
}
this.favoriteDataSource.refresh(favoriteList);
let innerEvent = {
eventId: 100,
priority: emitter.EventPriority.HIGH
};
emitter.emit(innerEvent, {
data: {
'favoriteListListLen': this.favoriteList.length
}
});
}
goContactDetail(contactId: string) {
HiLog.i(TAG, 'goContactDetail start.');
router.pushUrl(
{
url: 'pages/contacts/details/ContactDetail',
params: {
sourceHasId: true,
contactId: contactId
}
}
);
}
aboutToAppear() {
HiLog.i(TAG, 'FavoriteListPresenter aboutToAppear!');
this.isShow = true;
ContactRepository.getInstance().registerDataChangeObserver(this.onContactChange);
}
aboutToDisappear() {
HiLog.i(TAG, 'FavoriteListPresenter aboutToDisappear!');
this.isShow = false;
ContactRepository.getInstance().unRegisterDataChangeObserver(this.onContactChange);
}
async onPageShow() {
HiLog.i(TAG, 'onPageShow!');
this.isShow = true;
let editFavoriteDrag: number = AppStorage.Get<number>('editFavoriteDrag');
let addFavoriteContactData: string[] = AppStorage.Get<Array<string>>('addFavoriteContactData');
let deleteFavoriteContactData: string[] = AppStorage.Get<Array<string>>('deleteFavoriteContactData');
let cancelEditFavorite: number = AppStorage.Get<number>('cancelEditFavorite');
let that = this;
let usuallySelectData: Promise<string> = new Promise(async (resolve) => {
let usuallySelectDisplayNameList: string = <string> await sharedPreferencesUtils.getFromPreferences('usuallySelectDisplayNameList', '');
if ('' !== usuallySelectDisplayNameList) {
let usuallySelectDisplayList: string[] = JSON.parse(usuallySelectDisplayNameList);
let count = usuallySelectDisplayList.length;
that.usuallySelectArray.clear();
for (let i = 0; i < count; i++) {
that.usuallySelectArray.add(usuallySelectDisplayList[i]);
}
}
if(0 !== that.usuallySelectArray.length){
this.requestItem();
}
resolve(usuallySelectDisplayNameList)
});
if (editFavoriteDrag !== undefined && editFavoriteDrag === 1) {
HiLog.i(TAG, 'onPageShow editFavoriteDrag!');
this.requestItem();
AppStorage.SetOrCreate<number>('editFavoriteDrag', 0);
} else if (addFavoriteContactData !== undefined && addFavoriteContactData.length > 0) {
HiLog.i(TAG, 'onPageShow addFavoriteContactData!');
this.addFavoriteInfo(addFavoriteContactData);
AppStorage.SetOrCreate<Array<string>>('addFavoriteContactData', []);
} else if (cancelEditFavorite !== undefined && 2 === cancelEditFavorite) {
HiLog.i(TAG, 'onPageShow cancelEditFavorite!');
AppStorage.SetOrCreate<number>('cancelEditFavorite', 0);
} else if (deleteFavoriteContactData !== undefined && deleteFavoriteContactData.length > 0) {
HiLog.i(TAG, 'onPageShow deleteFavoriteContactData!');
this.deleteFavorite(deleteFavoriteContactData);
AppStorage.SetOrCreate<Array<string>>('deleteFavoriteContactData', []);
} else {
HiLog.i(TAG, 'onPageShow else!');
await usuallySelectData.then(result => {
if ('' === result) {
this.requestItem();
}
})
}
}
onPageHide() {
HiLog.i(TAG, 'onPageHide!');
this.isShow = false;
}
requestItem() {
HiLog.i(TAG, 'requestItem start.');
this.refreshFavorite();
this.refreshUsually();
}
async usuallySelectData(): Promise<string> {
let that = this;
//let usuallySelectData: Promise<string>
return await new Promise(async (resolve) => {
let usuallySelectDisplayNameList: string = <string> await sharedPreferencesUtils.getFromPreferences('usuallySelectDisplayNameList', '');
if ('' !== usuallySelectDisplayNameList) {
let usuallySelectDisplayList: string[] = JSON.parse(usuallySelectDisplayNameList);
let count = usuallySelectDisplayList.length;
that.usuallySelectArray.clear();
for (let i = 0; i < count; i++) {
that.usuallySelectArray.add(usuallySelectDisplayList[i]);
}
}
if(0 !== that.usuallySelectArray.length){
this.requestItem();
}
resolve(usuallySelectDisplayNameList)
});
}
addFavorite() {
router.pushUrl({
url: 'pages/contacts/batchselectcontacts/BatchSelectContactsPage',
params: {
addFavorite: 0,
selectType: 1
}
});
}
editFavorite() {
router.pushUrl({
url: 'pages/favorites/editFavoriteList',
params: {
isEdit: true,
favoriteList: this.favoriteList,
favoriteNumber: this.favoriteCount,
usuallyNumber: this.favoriteList.length - this.favoriteCount,
}
})
}
addFavoriteInfo(selectFavoriteIdList: string[]) {
HiLog.i(TAG, 'addFavoriteInfo start.');
let selectLength: number = selectFavoriteIdList.length;
for (let i = 0; i < selectLength; i++) {
let favoriteForm: any = {}
favoriteForm.id = selectFavoriteIdList[i];
favoriteForm.favorite = 1;
globalThis.DataWorker.sendRequest('updateFavorite', {
context: globalThis.context,
favoriteForm: JSON.stringify(favoriteForm)
}, (arg) => {
if (i === (selectLength - 1)) {
AppStorage.SetOrCreate<Array<string>>('addFavoriteContactData', [])
HiLog.i(TAG, 'addFavoriteInfo success refresh.');
this.requestItem();
}
})
}
HiLog.i(TAG, 'addFavoriteInfo end.');
}
deleteFavorite(deleteFavoriteIdList: string[]) {
HiLog.i(TAG, 'deleteFavorite start.');
let favoriteLength: number = deleteFavoriteIdList.length;
for (let i = 0; i < favoriteLength; i++) {
let favoriteForm: any = {};
favoriteForm.id = deleteFavoriteIdList[i];
favoriteForm.favorite = 0;
globalThis.DataWorker.sendRequest("updateFavorite", {
context: globalThis.context,
favoriteForm: JSON.stringify(favoriteForm)
}, (arg) => {
if(i === (favoriteLength - 1)){
HiLog.i(TAG, 'deleteFavoriteInfo success.');
AppStorage.SetOrCreate<Array<string>>('deleteFavoriteContactData', [])
this.requestItem();
}
})
}
HiLog.i(TAG, 'deleteFavorite end.');
}
longItemEditFavorite(favoriteList: FavoriteBean[], isEditSelectList: string[], favoriteBean: FavoriteBean) {
router.pushUrl({
url: 'pages/favorites/editFavoriteList',
params: {
isEdit: true,
favoriteList: favoriteList,
selectNumber: 1,
favoriteNumber: this.favoriteCount,
usuallyNumber: favoriteList.length - this.favoriteCount,
isEditSelectList: isEditSelectList,
selectFavoriteBean: favoriteBean
}
})
}
}
+1 -1
View File
@@ -48,7 +48,7 @@ export default {
return $r("app.string.time_morning", hour, minutes);
}
if (hour >= 11 && hour < 13) {
return $r("app.string.time_noon", hour >= 12 ? (parseInt(hour) - 12).toString() : hour, minutes);
return $r("app.string.time_noon", hour, minutes);
}
if (hour >= 13 && hour < 17) {
return $r("app.string.time_afternoon", (parseInt(hour) - 12).toString(), minutes);
+50 -2
View File
@@ -37,6 +37,14 @@ export enum DataWorkerConstant {
"getContactById",
"updateContact",
"getIdByTelephone",
"updateFavorite",
"getAllFavorite",
"getAllUsually",
"getDisplayNamesFindUsually",
"moveSortFavorite",
"getSearchContact",
"getCallHistorySearch",
"getQueryT9PhoneNumbers"
}
export class DataWorkerTask extends WorkerTask {
@@ -58,7 +66,7 @@ export class DataWorkerTask extends WorkerTask {
HiLog.i(TAG, `runInWorker ${request}`)
switch (request) {
case DataWorkerConstant[DataWorkerConstant.getAllCalls]:
CallLog.getAllCalls(param.actionData, param.mergeRule, (data) => {
CallLog.getAllCalls(JSON.parse(param.favoriteForm), param.actionData, param.mergeRule, (data) => {
HiLog.i(TAG, `getAllCalls result: ${JSON.stringify(data).length}`)
callBack(data);
}, param.context);
@@ -96,7 +104,7 @@ export class DataWorkerTask extends WorkerTask {
case DataWorkerConstant[DataWorkerConstant.getAllContactWithPhoneNumbers]:
ContactAbilityModel.getAllContactWithPhoneNumbers((resultList) => {
callBack(resultList);
}, param.context)
}, JSON.parse(param.favoriteForm), param.context)
break
case DataWorkerConstant[DataWorkerConstant.getContactById]:
ContactAbilityModel.getContactById(param.contactId, result => {
@@ -113,6 +121,46 @@ export class DataWorkerTask extends WorkerTask {
callBack(arg);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.updateFavorite]:
ContactAbilityModel.updateFavorite(null, JSON.parse(param.favoriteForm), (arg) => {
callBack(arg);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getAllFavorite]:
ContactAbilityModel.getAllFavorite(param.actionData, (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getAllUsually]:
ContactAbilityModel.getAllUsually(param.actionData, (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getDisplayNamesFindUsually]:
ContactAbilityModel.getDisplayNamesFindUsually(param.displayName, param.usuallyPhone, (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.moveSortFavorite]:
ContactAbilityModel.moveSortFavorite(null, JSON.parse(param.favoriteForm), (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getSearchContact]:
ContactAbilityModel.getSearchContact(param.actionData, (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getCallHistorySearch]:
CallLog.getCallHistorySearch(param.actionData, param.mergeRule, (data) => {
callBack(data);
}, param.context);
break
case DataWorkerConstant[DataWorkerConstant.getQueryT9PhoneNumbers]:
ContactAbilityModel.getQueryT9PhoneNumbers((resultList) => {
callBack(resultList);
}, JSON.parse(param.favoriteForm), param.context)
break
default:
HiLog.w(TAG, `${request} not allow!!!`)
break;
@@ -1,141 +0,0 @@
/**
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { HiLog } from "../../../../../common"
import { WorkerType } from "./WorkFactory"
import WorkerWrapper from "./base/WorkerWrapper"
import WorkerTask from "./base/WorkerTask"
import { ThreadWorkerGlobalScope } from '@ohos.worker';
import CallLog from '../model/calllog/CalllogModel';
import { CallLogRepository } from '../../../../../feature/call';
import { ContactRepository } from '../../../../../feature/contact';
import ContactAbilityModel from '../model/ContactAbilityModel';
const TAG = "DataWorkerWrapper"
export default class DataWorkerWrapper extends WorkerWrapper {
private static sInstance: DataWorkerWrapper = undefined;
private constructor() {
super()
}
static getInstance() {
HiLog.i(TAG, "getInstance in.")
if (DataWorkerWrapper.sInstance == undefined || DataWorkerWrapper.sInstance.mWorker == undefined) {
HiLog.i(TAG, "make DataWorkerWrapper.")
DataWorkerWrapper.sInstance = new DataWorkerWrapper();
}
return DataWorkerWrapper.sInstance;
}
getWorkerType(): WorkerType {
return WorkerType.DataWorker;
}
}
export enum DataWorkerConstant {
"deleteCallLogsById",
"getAllCalls",
"findByNumberIn",
"deleteContactById",
"addContact",
"getAllContact",
"getAllContactWithPhoneNumbers",
"getContactById",
"updateContact",
"getIdByTelephone",
}
export class DataWorkerTask extends WorkerTask {
private static sInstance: DataWorkerTask = undefined;
private constructor(workerPort: ThreadWorkerGlobalScope) {
super(workerPort)
}
static getInstance(workerPort: ThreadWorkerGlobalScope) {
HiLog.i(TAG, "getInstance in.")
if (DataWorkerTask.sInstance == undefined || DataWorkerTask.sInstance.workerPort == undefined) {
DataWorkerTask.sInstance = new DataWorkerTask(workerPort);
}
return DataWorkerTask.sInstance;
}
runInWorker(request: string, callBack: (v?: any) => void, param?: any) {
HiLog.i(TAG, `runInWorker ${request}`)
switch (request) {
case DataWorkerConstant[DataWorkerConstant.getAllCalls]:
CallLog.getAllCalls(param.actionData, param.mergeRule, (data) => {
HiLog.i(TAG, `getAllCalls result: ${JSON.stringify(data).length}`)
callBack(data);
}, param.context);
break;
case DataWorkerConstant[DataWorkerConstant.findByNumberIn]:
CallLogRepository.getInstance().init(param.context);
CallLogRepository.getInstance().findByNumberIn(param.numbers, (resultList) => {
callBack(resultList);
});
break
case DataWorkerConstant[DataWorkerConstant.deleteContactById]:
ContactRepository.getInstance().init(param.context);
ContactRepository.getInstance().deleteById(param.contactId, (result) => {
HiLog.i(TAG, `deleteContactById result ${result}`)
callBack(result);
});
break;
case DataWorkerConstant[DataWorkerConstant.deleteCallLogsById]:
CallLogRepository.getInstance().init(param.context);
CallLogRepository.getInstance().deleteByIdIn(param.ids, (result) => {
callBack(result);
})
break;
case DataWorkerConstant[DataWorkerConstant.addContact]:
const contactInfoAfter = JSON.parse(param.contactInfoAfter)
ContactAbilityModel.addContact(contactInfoAfter, (arg) => {
callBack(arg);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getAllContact]:
ContactAbilityModel.getAllContact(param.actionData, (result) => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getAllContactWithPhoneNumbers]:
ContactAbilityModel.getAllContactWithPhoneNumbers((resultList) => {
callBack(resultList);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getContactById]:
ContactAbilityModel.getContactById(param.contactId, result => {
callBack(result);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.getIdByTelephone]:
ContactAbilityModel.getIdByTelephone(param.phoneNumber, (contactId) => {
callBack(contactId);
}, param.context)
break
case DataWorkerConstant[DataWorkerConstant.updateContact]:
ContactAbilityModel.updateContact(null, JSON.parse(param.contactInfoAfter), (arg) => {
callBack(arg);
}, param.context)
break
default:
HiLog.w(TAG, `${request} not allow!!!`)
break;
}
}
}
+3
View File
@@ -103,6 +103,9 @@
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
},
{
"name": "ohos.permission.SET_TELEPHONY_STATE"
}
]
}
@@ -270,7 +270,7 @@
},
{
"name": "contact_list_search",
"value": "搜索联系人"
"value": "搜索..."
},
{
"name": "contact_list_search_empty",
@@ -454,7 +454,7 @@
},
{
"name": "no_select",
"value": "未选"
"value": "未选"
},
{
"name": "select_contact",
@@ -811,6 +811,39 @@
{
"name": "china_unicom",
"value": "中国联通"
},
{
"name": "common_use",
"value": "常用"
},
{
"name": "no_favorite",
"value": "没有收藏"
},
{
"name": "favorite_num",
"value": "收藏 %d"
},
{
"name": "common_use_num",
"value": "常用 %d"
},
{
"name": "favorite_remove",
"value": "取消"
},
{
"name": "contacts_call",
"value": "呼叫"
},
{
"name": "set_default_values",
"value": "设置默认值"
},
{
"name": "found_contacts",
"value": "找到 %d 个联系人"
}
]
}
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="120px" height="120px" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>NoFavorites</title>
<g id="NoFavorites" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="0" y="0" width="120" height="120"></rect>
<g id="EmptyPage/15-NoCallRecords" transform="translate(17.000000, 17.151346)" fill="#A1A7B3">
<path d="M4.24873433,76.5752664 L4.25,78.3686343 C4.25,79.4986499 5.12635957,80.4240111 6.23645429,80.5023411 L6.38921926,80.507712 L80.7221684,80.507712 C81.852184,80.507712 82.7775452,79.6314819 82.8558752,78.5213985 L82.8612461,78.3686343 L82.8614577,77.1946504 C84.5679382,77.9506741 85.5,78.7681567 85.5,79.6212852 C85.5,80.6264434 84.2061477,81.5821194 81.8762739,82.4460951 L81.3203371,82.6438271 L81.3203371,82.6438271 L80.7283227,82.8381882 C80.4234134,82.9345068 80.105239,83.029518 79.7741957,83.1231571 L79.0950676,83.3085864 C78.8630502,83.3697735 78.6254307,83.4303315 78.3823263,83.4902413 L77.6366759,83.6680064 L77.6366759,83.6680064 L76.8588206,83.8417664 L76.8588206,83.8417664 L76.0494644,84.0114061 L76.0494644,84.0114061 L75.2093116,84.1768101 L75.2093116,84.1768101 L74.3390662,84.3378632 C74.1915567,84.3643364 74.0428227,84.3906235 73.8928788,84.4167221 L72.9788149,84.5710326 L72.9788149,84.5710326 L72.0364187,84.7207039 C71.8770308,84.7452561 71.7164917,84.7696102 71.5548161,84.7937638 L70.5712419,84.9362602 L70.5712419,84.9362602 L69.5610958,85.073829 L69.5610958,85.073829 L68.525082,85.2063552 L68.525082,85.2063552 L67.4639046,85.3337233 L67.4639046,85.3337233 L66.3782677,85.4558181 L66.3782677,85.4558181 L64.7054912,85.6288206 L64.7054912,85.6288206 L63.5617863,85.7372277 L63.5617863,85.7372277 L62.3960863,85.8399579 L62.3960863,85.8399579 L61.2090955,85.9368959 L61.2090955,85.9368959 L60.001518,86.0279265 L60.001518,86.0279265 L58.7740579,86.1129343 L58.7740579,86.1129343 L57.5274193,86.1918041 L57.5274193,86.1918041 L56.2623065,86.2644205 L56.2623065,86.2644205 L54.9794234,86.3306683 L54.9794234,86.3306683 L53.02332,86.4178465 L53.02332,86.4178465 L51.6990921,86.4676683 L51.6990921,86.4676683 L50.3595585,86.5107178 L50.3595585,86.5107178 L49.0054233,86.5468799 L49.0054233,86.5468799 L47.6373906,86.5760391 L47.6373906,86.5760391 L46.2561647,86.5980804 L46.2561647,86.5980804 L44.8624496,86.6128882 L44.8624496,86.6128882 L43.4569494,86.6203474 L43.4569494,86.6203474 L42.0430506,86.6203474 L42.0430506,86.6203474 L40.6375504,86.6128882 L40.6375504,86.6128882 L39.2438353,86.5980804 L39.2438353,86.5980804 L37.8626094,86.5760391 L37.8626094,86.5760391 L36.4945767,86.5468799 L36.4945767,86.5468799 L35.1404415,86.5107178 L35.1404415,86.5107178 L33.8009079,86.4676683 L33.8009079,86.4676683 L32.47668,86.4178465 L32.47668,86.4178465 L30.5205766,86.3306683 L30.5205766,86.3306683 L28.6028718,86.2289012 L28.6028718,86.2289012 L27.3469081,86.1531437 L27.3469081,86.1531437 L26.1097707,86.0711905 L26.1097707,86.0711905 L24.8921639,85.9831568 L24.8921639,85.9831568 L23.6947917,85.8891581 L23.6947917,85.8891581 L22.5183583,85.7893096 L22.5183583,85.7893096 L21.3635679,85.6837266 L21.3635679,85.6837266 L19.673503,85.514852 L19.673503,85.514852 L18.0360954,85.3337233 L18.0360954,85.3337233 L16.974918,85.2063552 L16.974918,85.2063552 L15.9389042,85.073829 L15.9389042,85.073829 L14.9287581,84.9362602 L14.9287581,84.9362602 L13.9451839,84.7937638 C13.7835083,84.7696102 13.6229692,84.7452561 13.4635813,84.7207039 L12.5211851,84.5710326 L12.5211851,84.5710326 L11.6071212,84.4167221 L11.6071212,84.4167221 L10.7220936,84.2578878 C10.5770478,84.2310448 10.4332412,84.2040181 10.2906884,84.1768101 L9.45053559,84.0114061 L9.45053559,84.0114061 L8.64117944,83.8417664 L8.64117944,83.8417664 L7.8633241,83.6680064 L7.8633241,83.6680064 L7.11767371,83.4902413 C6.99612151,83.4602864 6.87594053,83.4301695 6.75714542,83.3998929 L6.06112271,83.2163363 C5.6083511,83.0927136 5.17822301,82.966613 4.77167729,82.8381882 L4.17966285,82.6438271 L4.17966285,82.6438271 L3.62372611,82.4460951 C1.2938523,81.5821194 0,80.6264434 0,79.6212852 C0,78.5295393 1.52636699,77.496168 4.24873433,76.5752664 Z" id="路径" opacity="0.15"></path>
<path d="M69.0156348,37.2503434 L82.6025248,53.0454136 C82.748568,53.2152004 82.8370976,53.4258877 82.8569481,53.6473727 L82.8612461,53.7692411 L82.8612461,78.3686343 C82.8612461,79.5500143 81.9035484,80.507712 80.7221684,80.507712 L6.38921926,80.507712 C5.20783928,80.507712 4.24974806,79.5500143 4.24974806,78.3686343 L4.24974806,53.7692411 C4.24659732,53.5479365 4.30955514,53.3242898 4.44336552,53.1323306 L4.50506342,53.0521016 L17.5065338,37.6843465 C19.3445143,50.243709 30.1617148,59.8868608 43.231194,59.8868608 C56.4508199,59.8868608 67.3661198,50.0208687 69.0156348,37.2503434 Z M68.2133407,41.4058247 C65.0607677,52.215398 55.0776909,60.1131295 43.25,60.1131295 C31.7171994,60.1131295 21.938179,52.6043042 18.5351215,42.2088364 L18.4176686,41.8407464 L10.2883876,52.2837462 L10.2373038,52.3551437 C9.95814637,52.7808189 10.0199255,53.345011 10.379366,53.7004004 L10.4754024,53.7846966 L10.5477884,53.836359 C10.6864387,53.926858 10.8441094,53.9838507 11.0082489,54.0030278 L11.1323702,54.0102529 L20.7592404,54.0102529 L20.7596974,61.4291341 C20.7596974,62.2659449 21.4003794,62.9531164 22.2179809,63.026886 L22.3640057,63.0334423 L66.7498674,63.0334423 C67.5866782,63.0334423 68.2738497,62.3927603 68.3476193,61.5751588 L68.3541756,61.4291341 L68.3537186,54.0102529 L75.9789247,54.0102529 L76.0587456,54.0073193 C76.6121571,53.9664901 77.0484635,53.5045545 77.0484635,52.940714 C77.0484635,52.7479552 76.9963934,52.5597141 76.899003,52.395395 L76.8175682,52.2769441 L68.2133407,41.4058247 Z" id="形状" opacity="0.400000006"></path>
<path d="M68.2133407,41.4058247 L76.8175682,52.2769441 C76.967104,52.465876 77.0484635,52.6997655 77.0484635,52.940714 C77.0484635,53.5045545 76.6121571,53.9664901 76.0587456,54.0073193 L75.9789247,54.0102529 L68.3537186,54.0102529 L68.3541756,61.4291341 C68.3541756,62.3151691 67.6359024,63.0334423 66.7498674,63.0334423 L22.3640057,63.0334423 C21.4779707,63.0334423 20.7596974,62.3151691 20.7596974,61.4291341 L20.7592404,54.0102529 L11.1323702,54.0102529 C10.9241335,54.0102529 10.7211013,53.9494827 10.5477884,53.836359 L10.4754024,53.7846966 C10.0325896,53.440005 9.93488324,52.8162919 10.2373038,52.3551437 L10.2883876,52.2837462 L18.4176686,41.8407464 C21.7083271,52.4265866 31.5815194,60.1131295 43.25,60.1131295 C55.0776909,60.1131295 65.0607677,52.215398 68.2133407,41.4058247 Z" id="路径" opacity="0.600000024"></path>
<path d="M53.1929308,39.5353971 L53.2074151,39.6339208 L54.609652,47.9025315 C54.8953508,49.6127938 53.1545474,50.9237183 51.6269537,50.1815433 L51.5532136,50.1440223 L46.1376392,47.2658523 C46.8600709,46.6478759 47.6079997,45.8910638 48.3814258,44.9954161 C49.6146738,43.5672825 51.2787773,41.3622869 53.3732458,38.3785862 C53.3782395,38.3677384 53.3833251,38.3569301 53.388502,38.3461625 C53.2125816,38.7124384 53.1423288,39.1248969 53.1929308,39.5353971 Z M45.0689332,18.2842932 L45.1116876,18.3674305 L48.7816046,25.8861103 C49.0744013,26.4883694 49.6292176,26.9090864 50.2745499,27.035141 L50.3673375,27.0511321 L58.5835696,28.2604302 C60.2802216,28.508055 60.9758489,30.5859262 59.8111063,31.8260048 L59.7502746,31.8883247 L53.8154162,37.7494081 C50.1341971,40.9497905 45.9306388,43.9638428 41.2047412,46.791565 L41.2106873,46.787346 L34.898911,50.1384878 C33.3787776,50.9445987 31.6040052,49.6762968 31.829968,47.9794309 L31.8424726,47.8969969 L33.2447096,39.6283863 C33.351651,38.9668763 33.1555296,38.3003464 32.7060278,37.8152534 L32.6367084,37.7438736 L26.6881563,31.8883247 C25.4601035,30.6801334 26.1069857,28.5862527 27.7694577,28.2773529 L27.8548613,28.2631975 L36.0710934,27.0594339 C36.7231754,26.9619205 37.2932813,26.5606973 37.6134372,25.9824595 L37.659565,25.8944121 L41.3349595,18.3674305 C42.0934938,16.8155341 44.2601102,16.7878217 45.0689332,18.2842932 Z" id="形状结合" fill-opacity="0.8" fill-rule="nonzero"></path>
<path d="M53.8154162,37.7494081 C53.6286734,37.9329124 53.4799871,38.1467129 53.3732458,38.3785862 C51.2787773,41.3622869 49.6146738,43.5672825 48.3814258,44.9954161 C47.6072908,45.8918847 46.8586998,46.6492631 46.1356528,47.2675513 L44.2051633,46.2394006 C43.6197568,45.9291893 42.9280664,45.9136788 42.3367278,46.1928689 L42.2442226,46.2394006 L41.2047412,46.791565 C45.9306388,43.9638428 50.1341971,40.9497905 53.8154162,37.7494081 L53.8154162,37.7494081 Z" id="形状结合" fill-opacity="0.6" fill-rule="nonzero"></path>
<path d="M43.25,8.11312951 C57.6094035,8.11312951 69.25,19.753726 69.25,34.1131295 C69.25,48.472533 57.6094035,60.1131295 43.25,60.1131295 C28.8905965,60.1131295 17.25,48.472533 17.25,34.1131295 C17.25,19.753726 28.8905965,8.11312951 43.25,8.11312951 Z M45.0689332,18.2842932 C44.2601102,16.7878217 42.0934938,16.8155341 41.3349595,18.3674305 L41.3349595,18.3674305 L37.659565,25.8944121 L37.6134372,25.9824595 C37.2932813,26.5606973 36.7231754,26.9619205 36.0710934,27.0594339 L36.0710934,27.0594339 L27.8548613,28.2631975 L27.7694577,28.2773529 C26.1069857,28.5862527 25.4601035,30.6801334 26.6881563,31.8883247 L26.6881563,31.8883247 L32.6367084,37.7438736 L32.7060278,37.8152534 C33.1555296,38.3003464 33.351651,38.9668763 33.2447096,39.6283863 L33.2447096,39.6283863 L31.8424726,47.8969969 L31.829968,47.9794309 C31.6040052,49.6762968 33.3787776,50.9445987 34.898911,50.1384878 L34.898911,50.1384878 L42.2442226,46.2394006 L42.3367278,46.1928689 C42.9280664,45.9136788 43.6197568,45.9291893 44.2051633,46.2394006 L44.2051633,46.2394006 L51.5532136,50.1440223 L51.6269537,50.1815433 C53.1545474,50.9237183 54.8953508,49.6127938 54.609652,47.9025315 L54.609652,47.9025315 L53.2074151,39.6339208 L53.1929308,39.5353971 C53.111913,38.8781542 53.3407006,38.2158912 53.8154162,37.7494081 L53.8154162,37.7494081 L59.7502746,31.8883247 L59.8111063,31.8260048 C60.9758489,30.5859262 60.2802216,28.508055 58.5835696,28.2604302 L58.5835696,28.2604302 L50.3673375,27.0511321 L50.2745499,27.035141 C49.6292176,26.9090864 49.0744013,26.4883694 48.7816046,25.8861103 L48.7816046,25.8861103 L45.1116876,18.3674305 Z" id="形状结合" fill-opacity="0.3"></path>
<path d="M75.8064204,14.4793094 L69.4560706,17.7149743 C68.7844788,18.0571673 68.5174485,18.8790023 68.8596416,19.5505941 C69.2018346,20.2221858 70.0236696,20.4892162 70.6952614,20.1470231 L77.0456112,16.9113583 C77.7172029,16.5691652 77.9842333,15.7473302 77.6420402,15.0757385 C77.2998471,14.4041467 76.4780121,14.1371163 75.8064204,14.4793094 Z M64.2661783,0.220338867 C63.6340345,-0.190180103 62.7887894,-0.0105176972 62.3782704,0.621626082 L58.4965386,6.59896891 C58.0860196,7.23111269 58.265682,8.07635785 58.8978258,8.48687682 C59.5299696,8.89739579 60.3752147,8.71773339 60.7857337,8.08558961 L64.6674655,2.10824678 C65.0779845,1.476103 64.8983221,0.630857837 64.2661783,0.220338867 Z M71.388694,6.74660139 C70.8843401,6.18645966 70.021396,6.14123468 69.4612542,6.64558855 L64.1647391,11.4145922 C63.6045973,11.9189461 63.5593723,12.7818903 64.0637262,13.342032 C64.5680801,13.9021737 65.4310243,13.9473987 65.991166,13.4430449 L71.2876812,8.67404117 C71.8478229,8.1696873 71.8930479,7.30674311 71.388694,6.74660139 Z" id="形状" opacity="0.2"></path>
<path d="M10.6798671,14.4793094 L17.0302169,17.7149743 C17.7018086,18.0571673 17.968839,18.8790023 17.6266459,19.5505941 C17.2844528,20.2221858 16.4626178,20.4892162 15.7910261,20.1470231 L9.44067631,16.9113583 C8.76908456,16.5691652 8.50205418,15.7473302 8.84424727,15.0757385 C9.18644036,14.4041467 10.0082753,14.1371163 10.6798671,14.4793094 Z M22.2201091,0.220338867 C22.8522529,-0.190180103 23.6974981,-0.0105176972 24.1080171,0.621626082 L27.9897489,6.59896891 C28.4002678,7.23111269 28.2206054,8.07635785 27.5884617,8.48687682 C26.9563179,8.89739579 26.1110727,8.71773339 25.7005537,8.08558961 L21.8188219,2.10824678 C21.408303,1.476103 21.5879654,0.630857837 22.2201091,0.220338867 Z M15.0975934,6.74660139 C15.6019473,6.18645966 16.4648915,6.14123468 17.0250332,6.64558855 L22.3215484,11.4145922 C22.8816901,11.9189461 22.9269151,12.7818903 22.4225612,13.342032 C21.9182074,13.9021737 21.0552632,13.9473987 20.4951215,13.4430449 L15.1986063,8.67404117 C14.6384646,8.1696873 14.5932396,7.30674311 15.0975934,6.74660139 Z" id="形状" opacity="0.2"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_public_close</title>
<g id="ic_public_close" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M12,1 C18.0751322,1 23,5.92486775 23,12 C23,18.0751322 18.0751322,23 12,23 C5.92486775,23 1,18.0751322 1,12 C1,5.92486775 5.92486775,1 12,1 Z M12,2.5 C6.75329488,2.5 2.5,6.75329488 2.5,12 C2.5,17.2467051 6.75329488,21.5 12,21.5 C17.2467051,21.5 21.5,17.2467051 21.5,12 C21.5,6.75329488 17.2467051,2.5 12,2.5 Z M8.81801948,7.75735931 L12.0007071,10.9386327 L15.1819805,7.75735931 C15.4748737,7.46446609 15.9497475,7.46446609 16.2426407,7.75735931 C16.5355339,8.05025253 16.5355339,8.52512627 16.2426407,8.81801948 L8.81801948,16.2426407 C8.52512627,16.5355339 8.05025253,16.5355339 7.75735931,16.2426407 C7.46446609,15.9497475 7.46446609,15.4748737 7.75735931,15.1819805 L10.9400469,11.9992929 L7.75735931,8.81801948 C7.46446609,8.52512627 7.46446609,8.05025253 7.75735931,7.75735931 C8.05025253,7.46446609 8.52512627,7.46446609 8.81801948,7.75735931 Z M13.767767,12.7071068 L16.2426407,15.1819805 C16.5355339,15.4748737 16.5355339,15.9497475 16.2426407,16.2426407 C15.9497475,16.5355339 15.4748737,16.5355339 15.1819805,16.2426407 L12.7071068,13.767767 L13.767767,12.7071068 Z" id="形状结合" fill="#000000" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_public_close</title>
<g
id="ic_public_close"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd">
<rect
id="矩形"
x="0"
y="0"
width="24"
height="24"></rect>
<path
d="M12,1 C18.0751322,1 23,5.92486775 23,12 C23,18.0751322 18.0751322,23 12,23 C5.92486775,23 1,18.0751322 1,12 C1,5.92486775 5.92486775,1 12,1 Z M12,2.5 C6.75329488,2.5 2.5,6.75329488 2.5,12 C2.5,17.2467051 6.75329488,21.5 12,21.5 C17.2467051,21.5 21.5,17.2467051 21.5,12 C21.5,6.75329488 17.2467051,2.5 12,2.5 Z M8.81801948,7.75735931 L12.0007071,10.9386327 L15.1819805,7.75735931 C15.4748737,7.46446609 15.9497475,7.46446609 16.2426407,7.75735931 C16.5355339,8.05025253 16.5355339,8.52512627 16.2426407,8.81801948 L8.81801948,16.2426407 C8.52512627,16.5355339 8.05025253,16.5355339 7.75735931,16.2426407 C7.46446609,15.9497475 7.46446609,15.4748737 7.75735931,15.1819805 L10.9400469,11.9992929 L7.75735931,8.81801948 C7.46446609,8.52512627 7.46446609,8.05025253 7.75735931,7.75735931 C8.05025253,7.46446609 8.52512627,7.46446609 8.81801948,7.75735931 Z M13.767767,12.7071068 L16.2426407,15.1819805 C16.5355339,15.4748737 16.5355339,15.9497475 16.2426407,16.2426407 C15.9497475,16.5355339 15.4748737,16.5355339 15.1819805,16.2426407 L12.7071068,13.767767 L13.767767,12.7071068 Z"
id="形状结合"
fill="#aaaaaa"
fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.8 KiB

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_public_collected</title>
<g id="ic_public_collected" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M18.9644843,13.4953627 L18.5583362,13.891644 C18.3226501,14.1213812 18.2151017,14.4523814 18.2707396,14.7767754 L19.0417936,19.2723649 C19.2051753,20.2249537 18.5653966,21.1296265 17.6128078,21.2930083 C17.233482,21.3580678 16.8432878,21.2962671 16.502632,21.1171737 L13.370917,19.4707361 C14.8799294,18.2083685 16.3396237,16.5514564 17.75,14.5 C17.8946364,14.3590143 18.3500792,14.0014458 18.9644843,13.4953627 Z M12.77449,1.63492692 C13.1196121,1.80525484 13.3989602,2.084603 13.5692881,2.42972506 L15.5879336,6.51994748 C15.7335956,6.81509095 16.0151612,7.01966033 16.3408713,7.06698879 L20.8546998,7.72288645 C21.8111533,7.86186728 22.4738458,8.74989227 22.334865,9.70634578 C22.2795221,10.0872106 22.1001695,10.4392098 21.8245732,10.7078499 L19.6760114,12.8014342 L19.5568049,12.9183776 L18.901793,13.4819135 C17.5965541,14.5925465 16.3200252,15.6045457 15.0722065,16.5179114 C13.6164179,17.5835046 12.107038,18.5826772 10.5440669,19.5154293 L10.5479464,19.5118248 L7.49736799,21.1171737 C6.64188996,21.5669251 5.58379244,21.2380187 5.13404103,20.3825407 C4.95494765,20.0418849 4.89314697,19.6516907 4.95820645,19.2723649 L5.7292604,14.7767754 C5.78489833,14.4523814 5.67734985,14.1213812 5.44166376,13.891644 L2.17542683,10.7078499 C1.48333057,10.0332227 1.46916903,8.92527453 2.14379615,8.23317827 C2.41243621,7.95758191 2.76443543,7.77822934 3.14530023,7.72288645 L7.65912866,7.06698879 C7.98483882,7.01966033 8.26640441,6.81509095 8.41206642,6.51994748 L10.4307119,2.42972506 C10.8584509,1.56303116 11.9077961,1.20718791 12.77449,1.63492692 Z" id="形状结合" fill="#000000" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_public_drag_handle</title>
<g id="ic_public_drag_handle" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="矩形" x="0" y="0" width="24" height="24"></rect>
<path d="M2.75,9.75 C2.33578644,9.75 2,9.41421356 2,9 C2,8.58578644 2.33578644,8.25 2.75,8.25 L21.25,8.25 C21.6642136,8.25 22,8.58578644 22,9 C22,9.41421356 21.6642136,9.75 21.25,9.75 L2.75,9.75 Z M21.25,14.25 C21.6642136,14.25 22,14.5857864 22,15 C22,15.4142136 21.6642136,15.75 21.25,15.75 L2.75,15.75 C2.33578644,15.75 2,15.4142136 2,15 C2,14.5857864 2.33578644,14.25 2.75,14.25 L21.25,14.25 Z" id="move" fill="#000000" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 866 B

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_more</title>
<defs>
<path
d="M6.25,15.5 C7.21649831,15.5 8,16.2835017 8,17.25 C8,18.2164983 7.21649831,19 6.25,19 C5.28350169,19 4.5,18.2164983 4.5,17.25 C4.5,16.2835017 5.28350169,15.5 6.25,15.5 Z M17.75,15.5 C18.7164983,15.5 19.5,16.2835017 19.5,17.25 C19.5,18.2164983 18.7164983,19 17.75,19 C16.7835017,19 16,18.2164983 16,17.25 C16,16.2835017 16.7835017,15.5 17.75,15.5 Z M6.25,4.5 C7.21649831,4.5 8,5.28350169 8,6.25 C8,7.21649831 7.21649831,8 6.25,8 C5.28350169,8 4.5,7.21649831 4.5,6.25 C4.5,5.28350169 5.28350169,4.5 6.25,4.5 Z M17.75,4.5 C18.7164983,4.5 19.5,5.28350169 19.5,6.25 C19.5,7.21649831 18.7164983,8 17.75,8 C16.7835017,8 16,7.21649831 16,6.25 C16,5.28350169 16.7835017,4.5 17.75,4.5 Z"
id="path-1"></path>
</defs>
<g
id="Public/ic_public_more"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd">
<mask
id="mask-2"
fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use
id="形状结合"
fill="#999999"
xlink:href="#path-1"></use>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Public/ic_public_phone</title>
<defs>
<path
d="M5.16720725,2.15694972 C4.57981912,2.29147814 4.01663811,2.67469617 3.45795888,3.28222699 L3.40000863,3.34652585 L3.41706088,3.3290245 C2.31983567,4.41733995 1.86268744,5.99225358 2.20824887,7.49585665 C2.84070426,10.2182299 4.91223973,13.4662736 7.70579392,16.2883966 C10.5332577,19.0872915 13.7813017,21.1588206 16.5019346,21.7908739 L16.5941801,21.8110531 C18.0405745,22.1115169 19.5405408,21.676154 20.6032636,20.6488379 L20.6530605,20.5992242 L20.6367826,20.6144113 C21.3182937,20.0075363 21.7360372,19.3963547 21.858708,18.7555609 C22.0403569,17.8066839 21.6727677,16.8312994 20.9172668,16.2234479 L18.8910284,14.5810212 L18.8910284,14.5810212 C17.9729968,13.7661146 16.5931939,13.7836376 15.699312,14.6157694 L15.6477052,14.665379 L15.6228063,14.690554 L14.686639,15.6828975 C14.5546026,15.8149102 14.3280746,15.8409839 14.1527582,15.7314508 C13.3172557,15.2120891 12.1303644,14.1987708 10.9802683,13.0284399 L10.7611357,12.8108428 C9.67601351,11.7221684 8.75502696,10.6301338 8.26897505,9.84821364 C8.15853902,9.67144831 8.18461264,9.44492031 8.33152313,9.29843477 L9.30896885,8.37671655 L9.33414385,8.35181763 L9.37464007,8.30982875 C10.2003067,7.42306041 10.2324768,6.07746659 9.46508279,5.162393 L9.3537796,5.03091264 L8.22723777,3.64204688 C8.07133397,3.44889272 7.91700627,3.25742016 7.77607494,3.08225607 C7.16822347,2.32675513 6.19283903,1.95916594 5.243962,2.14081487 L5.16720725,2.15694972 Z M20.3854606,18.4735287 C20.3347566,18.7383909 20.0964509,19.087045 19.6392388,19.4941853 L19.6055231,19.5261346 C18.8823263,20.255252 17.8371496,20.5586342 16.839641,20.3293845 C14.4293391,19.7694247 11.4077574,17.8423281 8.7664403,15.2277501 C6.15720291,12.5917737 4.23009995,9.57019147 3.66973827,7.15815029 C3.44742729,6.19082408 3.72736923,5.17688065 4.41193762,4.45676796 L4.50533759,4.36028407 C4.91247789,3.90307193 5.26113202,3.66476633 5.52599414,3.61406226 C5.92515246,3.53764911 6.34435194,3.69563113 6.60738014,4.02254988 L8.02359877,5.77349596 L8.33190757,6.14585543 C8.59711542,6.47956509 8.58061124,6.96151558 8.28584937,7.27815087 L8.26649427,7.29801532 L7.28729807,8.22179031 C6.630534,8.87624912 6.51580142,9.8730476 6.99594523,10.641556 C7.58651914,11.5916262 8.67168241,12.862672 9.91964876,14.08906 L10.1558071,14.3268132 C11.2995201,15.4658 12.4692794,16.45116 13.3594158,17.0044806 L13.4145885,17.0377028 C14.1737396,17.4779592 15.1385121,17.3537064 15.7632834,16.7271225 L16.7010407,15.7332689 L16.7309899,15.7045601 C17.0383508,15.4185862 17.5199701,15.4023958 17.8559701,15.669668 L18.0404137,15.8240228 C18.3872561,16.1094041 19.2522673,16.8090681 19.976973,17.3921427 C20.3038918,17.6551709 20.4618738,18.0743704 20.3854606,18.4735287 Z"
id="path-1"></path>
</defs>
<g
id="Public/ic_public_phone"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd">
<mask
id="mask-2"
fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use
id="形状"
fill="#999999"
fill-rule="nonzero"
xlink:href="#path-1"></use>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px"
height="24px"
viewBox="0 0 24 24"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_public_search</title>
<g
id="ic_public_search"
stroke="none"
stroke-width="1"
fill="none"
fill-rule="evenodd">
<rect
id="矩形"
x="0"
y="0"
width="24"
height="24"></rect>
<path
d="M17.4552585,16.5201811 L20.8132621,19.8776019 C21.1061553,20.1704951 21.1061553,20.6453689 20.8132621,20.9382621 C20.5203689,21.2311553 20.0454951,21.2311553 19.7526019,20.9382621 L16.3849514,17.5705115 C16.7690371,17.2493647 17.1270214,16.8980393 17.4552585,16.5201811 Z M10.375,2 C15.0003848,2 18.75,5.74961522 18.75,10.375 C18.75,12.4492584 17.9959213,14.3473923 16.746948,15.8102175 L16.746948,15.8102175 L16.7248309,15.8360159 C16.6580095,15.9136422 16.5897889,15.9900296 16.5202083,16.0651391 L16.746948,15.8102175 C16.6540763,15.9189909 16.5584681,16.0253575 16.4602302,16.1292106 C16.4016383,16.1911476 16.342303,16.2519995 16.2820606,16.3119405 C16.2610861,16.3328082 16.240292,16.3532825 16.2193918,16.3736485 C16.1491692,16.4420866 16.0772901,16.5097189 16.0042335,16.576078 C15.9759275,16.6017907 15.9472456,16.6274881 15.9183866,16.6529896 C15.8514229,16.712158 15.7837649,16.7700565 15.7151861,16.8268826 C15.7013815,16.8383205 15.6877981,16.8495035 15.674179,16.8606444 C14.2305262,18.0415704 12.3854944,18.75 10.375,18.75 C5.74961522,18.75 2,15.0003848 2,10.375 C2,5.74961522 5.74961522,2 10.375,2 Z M10.375,3.5 C6.57804235,3.5 3.5,6.57804235 3.5,10.375 C3.5,14.1719577 6.57804235,17.25 10.375,17.25 C14.1719577,17.25 17.25,14.1719577 17.25,10.375 C17.25,6.57804235 14.1719577,3.5 10.375,3.5 Z"
id="形状结合"
fill="#aaaaaa"
fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

@@ -6,6 +6,7 @@
"pages/contacts/details/ContactDetail",
"pages/dialer/DialerTablet",
"pages/contacts/batchselectcontacts/BatchSelectContactsPage",
"pages/contacts/batchselectcontacts/SingleSelectContactPage"
"pages/contacts/batchselectcontacts/SingleSelectContactPage",
"pages/favorites/editFavoriteList"
]
}
@@ -270,7 +270,7 @@
},
{
"name": "contact_list_search",
"value": "searching for contacts"
"value": "Search..."
},
{
"name": "contact_list_search_empty",
@@ -811,6 +811,38 @@
{
"name": "china_unicom",
"value": "China Unicom"
},
{
"name": "common_use",
"value": "Common Use"
},
{
"name": "no_favorite",
"value": "No favorite"
},
{
"name": "favorite_num",
"value": "Favorites %d"
},
{
"name": "common_use_num",
"value": "Common Use %d"
},
{
"name": "favorite_remove",
"value": "Cancel"
},
{
"name": "contacts_call",
"value": "call"
},
{
"name": "set_default_values",
"value": "Set default values"
},
{
"name": "found_contacts",
"value": "found %d contacts"
}
]
}
@@ -270,7 +270,7 @@
},
{
"name": "contact_list_search",
"value": "搜索联系人"
"value": "搜索..."
},
{
"name": "contact_list_search_empty",
@@ -454,7 +454,7 @@
},
{
"name": "no_select",
"value": "未选"
"value": "未选"
},
{
"name": "select_contact",
@@ -811,6 +811,38 @@
{
"name": "china_unicom",
"value": "中国联通"
},
{
"name": "common_use",
"value": "常用"
},
{
"name": "no_favorite",
"value": "没有收藏"
},
{
"name": "favorite_num",
"value": "收藏 %d"
},
{
"name": "common_use_num",
"value": "常用 %d"
},
{
"name": "favorite_remove",
"value": "取消"
},
{
"name": "contacts_call",
"value": "呼叫"
},
{
"name": "set_default_values",
"value": "设置默认值"
},
{
"name": "found_contacts",
"value": "找到 %d 个联系人"
}
]
}
@@ -15,6 +15,9 @@
import Notification from "@ohos.notificationManager"
import WantAgent from '@ohos.app.ability.wantAgent';
import { HiLog, sharedPreferencesUtils } from '../../../../../../common';
import notificationSubscribe from '@ohos.notificationSubscribe';
import call from '@ohos.telephony.call';
import { NotificationSubscriber } from 'notification/notificationSubscriber';
const TAG = "MissedCallNotifier";
@@ -22,6 +25,11 @@ const BUNDLE_NAME: string = 'com.ohos.contacts';
const ABILITY_NAME: string = 'com.ohos.contacts.MainAbility';
const GROUP_NAME: string = "MissedCall"
const KEY_MISSED_BADGE_NUM = 'missed_badge_number'
const KEY_ID = 'unread_call_notification_id'
const KEY_DISPLAY_NAME = 'unread_call_notification_displayName'
const KEY_COUNT = 'unread_call_notification_count'
const KEY_CREATE_TIME = 'unread_call_notification_create_time'
const KEY_RING_DURATION = 'unread_call_notification_ring_duration'
const actionBtnMaps =
{
'notification.event.dialBack': $r('app.string.dial_back'),
@@ -42,6 +50,7 @@ export class MissedCallNotifier {
private context: Context;
private static sInstance: MissedCallNotifier = undefined;
private missedBadgeNumber: number = -1;
private UnReadMissedCallData: MissedCallNotifyData;
/**
* getInstance for MissedCallNotifier
@@ -164,16 +173,24 @@ export class MissedCallNotifier {
private async sendNotification(missedCallData: MissedCallNotifyData) {
const {id, displayName, count, createTime, ringDuration} = missedCallData;
sharedPreferencesUtils.saveToPreferences(KEY_ID, id);
sharedPreferencesUtils.saveToPreferences(KEY_DISPLAY_NAME, displayName);
sharedPreferencesUtils.saveToPreferences(KEY_COUNT, count);
sharedPreferencesUtils.saveToPreferences(KEY_CREATE_TIME, createTime);
sharedPreferencesUtils.saveToPreferences(KEY_RING_DURATION, ringDuration)
HiLog.i(TAG, `sendNotification in id:${id}, count:${count}, createTime:${createTime}`)
let str_text = this.getContext()?.resourceManager.getStringSync($r("app.string.contacts_ring_times")) +
ringDuration + this.getContext()?.resourceManager.getStringSync($r("app.string.contacts_time_sec"));
if (ringDuration === 0) {
str_text = $r("app.string.missed_call")
}
const notificationRequest: Notification.NotificationRequest = {
content: {
contentType: Notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
normal: {
title: count > 1 ? `${displayName} (${count})` : displayName,
text: str_text,
additionalText: ""
additionalText: missedCallData.phoneNumber
},
},
id: id,
@@ -204,6 +221,43 @@ export class MissedCallNotifier {
HiLog.i(TAG, 'sendNotification end')
}
/**
* send Unread Call Notification
*/
public async sendUnreadCallNotification(map: Map<string, string>) {
let id: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_ID, -1);
let displayName: string = <string> await sharedPreferencesUtils.getFromPreferences(KEY_DISPLAY_NAME, "");
let count: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_COUNT, -1);
let createTime: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_CREATE_TIME, -1);
let ringDuration: number = <number> await sharedPreferencesUtils.getFromPreferences(KEY_RING_DURATION, -1);
let missCallData = map.get("missedPhoneJson")
const parameters = JSON.parse(JSON.stringify(missCallData));
for (let i = 0; i < parameters.phoneNumberList.length; i++) {
const missedPhoneNumber = parameters.phoneNumberList[i]
const missedNum = parameters.countList[i]
if (i === (parameters.phoneNumberList.length -1)) {
this.UnReadMissedCallData = {
phoneNumber: missedPhoneNumber,
displayName: missedPhoneNumber,
id: i,
createTime: createTime,
count: count,
ringDuration: ringDuration
}
} else {
this.UnReadMissedCallData = {
phoneNumber: missedPhoneNumber,
displayName: missedPhoneNumber,
id: i,
createTime: createTime,
count: count,
ringDuration: 0
}
}
this.sendNotification(this.UnReadMissedCallData);
}
}
private setMissedBadgeNumber(newBadgeNum: number) {
HiLog.i(TAG, 'setMissedBadgeNumber :' + newBadgeNum);
this.missedBadgeNumber = newBadgeNum;
@@ -224,7 +278,7 @@ export class MissedCallNotifier {
missedCallData: missedCallData
}, }],
operationType: WantAgent.OperationType.SEND_COMMON_EVENT,
requestCode: 0 // requestCode是WantAgentInfo的请求码,是使用者定义的一个私有值
requestCode: 0
})
}
@@ -80,6 +80,13 @@ export class MissedCallService {
this.sendMissedCallNotify(this.lastMissedId);
}
/**
*
* Unread missed call notification
*/
public async unreadCallNotification(map:Map<string,string>) {
MissedCallNotifier.getInstance().sendUnreadCallNotification(map);
}
/**
* cancelMissedNotificationAction
@@ -19,6 +19,7 @@ import ICallLogRepository from './ICallLogRepository';
import { CallLog } from '../entity/CallLog';
import CallLogBuilder from '../entity/CallLogBuilder';
import Calls from '../contract/Calls';
import { RawContacts } from '../../../../../contact/src/main/ets/contract/RawContacts';
import CallLogDelta from './CallLogDelta';
import { StringUtil } from '../../../../../../common/src/main/ets/util/StringUtil';
import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
@@ -55,7 +56,7 @@ export class CallLogRepository implements ICallLogRepository {
private async getDataAbilityHelper() {
if (this.dataShareHelper == undefined) {
this.dataShareHelper = await dataShare.createDataShareHelper(this.context ? this.context : globalThis.context,
Calls.CONTENT_URI);
Calls.CONTENT_URI);
}
return this.dataShareHelper;
}
@@ -134,10 +135,13 @@ export class CallLogRepository implements ICallLogRepository {
return false;
}
findAll(actionData, callback) {
findAll(favorite: number, actionData, callback) {
this.getDataAbilityHelper().then((dataAbilityHelper) => {
let condition = new dataSharePredicates.DataSharePredicates();
let offset = actionData.page < 3 ? (actionData.page - 1) * 50 : (actionData.page - 2) * 500 + 50;
if (0 === favorite) {
condition.equalTo(RawContacts.FAVORITE, favorite)
}
condition.limit(actionData.limit, offset);
condition.orderByDesc(Calls.CREATE_TIME);
dataAbilityHelper.query(Calls.CALL_LOG_URI, condition, null).then(resultSet => {
@@ -337,4 +341,36 @@ export class CallLogRepository implements ICallLogRepository {
this.unregisterCallLogDataChange();
}
}
findSearch(actionData, callback) {
this.getDataAbilityHelper().then((dataAbilityHelper) => {
let condition = new dataSharePredicates.DataSharePredicates();
condition.in(Calls.DISPLAY_NAME, actionData.nameArray)
.or()
.like(Calls.PHONE_NUMBER, `%${actionData.teleNumber}%`);
dataAbilityHelper.query(Calls.CALL_LOG_URI, condition, null).then(resultSet => {
let rst: CallLog[] = [];
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
let builder = CallLogBuilder.fromResultSet(resultSet);
if (builder.id > 0) {
rst.push(new CallLog(builder));
}
} while (resultSet.goToNextRow());
resultSet.close();
callback(rst);
}
}).catch(error => {
HiLog.w(TAG, 'findAll error:' + JSON.stringify(error.message));
callback([]);
});
}).catch(error => {
HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message));
callback([]);
});
}
}
@@ -27,7 +27,7 @@ export default interface ICallLogRepository {
deleteByLookupUri: (lookupUri: string) => boolean;
readByNumber: (number: string) => boolean;
readById: (id: number) => boolean;
findAll: (actionData: any, callback) => void;
findAll: (favorite: number, actionData: any, callback) => void;
findByFeature: (feature: number) => CallLog[];
findByNumberIn: (numbers: number[], callback) => void;
notifyChange: () => void;
@@ -55,4 +55,6 @@ export default class DataColumns extends BaseColumns {
static readonly SYN_1: string = "syn_1";
static readonly SYN_2: string = "syn_2";
static readonly SYN_3: string = "syn_3";
static readonly FAVORITE: string = "favorite";
static readonly CONTENT_TYPE: string = "content_type";
}
@@ -44,4 +44,5 @@ export default class DataType {
static readonly DATA: string = DataColumns.DETAIL_INFO;
static readonly LABEL_ID: string = DataColumns.EXTEND7;
static readonly LABEL_NAME: string = DataColumns.CUSTOM_DATA;
static readonly FAVORITE: string = DataColumns.FAVORITE;
}
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import SearchContactColumns from './SearchContactsColumns';
/**
* searchContact data type
*/
export class SearchContacts extends SearchContactColumns {
static readonly CONTENT_URI: string = "datashare:///com.ohos.contactsdataability/contacts/search_contact";
constructor() {
super()
}
}
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import BaseColumns from './BaseColumns';
/**
* Field constants in the contact searchcontact table
*/
export default class SearchContactsColumns extends BaseColumns {
static readonly ACCOUNT_ID: string = "account_id";
static readonly CONTACT_ID: string = "contact_id";
static readonly ROW_CONTACT_ID: string = "raw_contact_id";
static readonly SEARCH_NAME: string = "search_name";
static readonly DISPLAY_NAME: string = "display_name";
static readonly PHONETIC_NAME: string = "phonetic_name";
static readonly PHOTO_ID: string = "photo_id";
static readonly PHOTO_FILE_ID: string = "photo_file_id";
static readonly IS_DELETED: string = "is_deleted";
static readonly TYPE_ID: string = "type_id";
static readonly POSITION: string = "position";
static readonly DETAIL_INFO: string = "detail_info";
static readonly PHOTO_FIRST_NAME: string = "photo_first_name";
static readonly SORT_FIRST_LETTER: string = "sort_first_letter";
static readonly CUSTOM_DATA: string = "custom_data";
static readonly CONTENT_TYPE: string = "content_type";
static readonly HAS_PHONE_NUMBER: string = "has_phone_number";
}
@@ -63,6 +63,7 @@ export class DataItem {
contentValues.set(Data.SYN_1, resultSet.getString(resultSet.getColumnIndex(Data.SYN_1)));
contentValues.set(Data.SYN_2, resultSet.getString(resultSet.getColumnIndex(Data.SYN_2)));
contentValues.set(Data.SYN_3, resultSet.getString(resultSet.getColumnIndex(Data.SYN_3)));
contentValues.set(Data.FAVORITE, resultSet.getString(resultSet.getColumnIndex(Data.FAVORITE)));
return new DataItem(contentValues);
}
@@ -85,4 +86,8 @@ export class DataItem {
getLabelName() {
return this.values.get(DataType.LABEL_NAME);
}
getFavorite() {
return this.values.get(DataType.FAVORITE);
}
}
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SearchContacts } from '../contract/SearchContacts';
import { Data } from '../contract/Data';
import { DataItem } from '../entity/DataItem';
export default class SearchContact {
readonly id: number;
readonly values: Map<string, any>;
readonly dataItems: DataItem[];
constructor(id: number, values: Map<string, any>) {
this.id = id;
this.values = values;
this.dataItems = [];
}
static fromResultSet(resultSet: any): SearchContact{
let contentValues: Map<string, any> = new Map();
contentValues.set(SearchContacts.ACCOUNT_ID, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.ACCOUNT_ID)));
contentValues.set(SearchContacts.CONTACT_ID, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.CONTACT_ID)));
contentValues.set(SearchContacts.RAW_CONTACT_ID, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.RAW_CONTACT_ID)));
contentValues.set(SearchContacts.SEARCH_NAME, resultSet.getString(resultSet.getColumnIndex(SearchContacts.SEARCH_NAME)));
contentValues.set(SearchContacts.DISPLAY_NAME, resultSet.getString(resultSet.getColumnIndex(SearchContacts.DISPLAY_NAME)));
contentValues.set(SearchContacts.PHONETIC_NAME, resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHONETIC_NAME)));
contentValues.set(SearchContacts.PHOTO_ID, resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHOTO_ID)));
contentValues.set(SearchContacts.PHOTO_FILE_ID, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.PHOTO_FILE_ID)));
contentValues.set(SearchContacts.IS_DELETED, resultSet.getString(resultSet.getColumnIndex(SearchContacts.IS_DELETED)));
contentValues.set(SearchContacts.POSITION, resultSet.getString(resultSet.getColumnIndex(SearchContacts.POSITION)));
contentValues.set(SearchContacts.PHOTO_FIRST_NAME, resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHOTO_FIRST_NAME)));
contentValues.set(SearchContacts.SORT_FIRST_LETTER, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.SORT_FIRST_LETTER)));
contentValues.set(SearchContacts.CUSTOM_DATA, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.CUSTOM_DATA)));
contentValues.set(SearchContacts.DETAIL_INFO, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.DETAIL_INFO)));
contentValues.set(SearchContacts.CONTENT_TYPE, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.CONTENT_TYPE)));
contentValues.set(SearchContacts.HAS_PHONE_NUMBER, resultSet.getLong(resultSet.getColumnIndex(SearchContacts.HAS_PHONE_NUMBER)));
return new SearchContact(resultSet.getLong(resultSet.getColumnIndex(SearchContacts.ID)), contentValues);
}
}
@@ -20,7 +20,7 @@ import ContactBuilder from '../entity/ContactBuilder';
export default class ContactListItem {
static readonly COLUMNS: string[] = [Contacts.ID, Contacts.QUICK_SEARCH_KEY, RawContacts.DISPLAY_NAME,
RawContacts.SORT_FIRST_LETTER, RawContacts.PHOTO_FIRST_NAME, Contacts.COMPANY, Contacts.POSITION];
RawContacts.SORT_FIRST_LETTER, RawContacts.PHOTO_FIRST_NAME, Contacts.COMPANY, Contacts.POSITION, RawContacts.FAVORITE_ORDER];
readonly id: number;
readonly displayName: string;
readonly sortFirstLetter: string;
@@ -28,6 +28,7 @@ export default class ContactListItem {
readonly quickSearchKey: string;
readonly company: string;
readonly position: string;
readonly favoriteOrder: string;
phoneNumbers: [] = [];
constructor(resultSet: any) {
@@ -38,6 +39,7 @@ export default class ContactListItem {
this.quickSearchKey = resultSet.getString(resultSet.getColumnIndex(Contacts.QUICK_SEARCH_KEY));
this.company = resultSet.getString(resultSet.getColumnIndex(Contacts.COMPANY));
this.position = resultSet.getString(resultSet.getColumnIndex(Contacts.POSITION));
this.favoriteOrder = resultSet.getString(resultSet.getColumnIndex(RawContacts.FAVORITE_ORDER));
}
createContact() {
@@ -29,6 +29,12 @@ import { Data } from '../contract/Data';
import { HiLog } from '../../../../../../common/src/main/ets/util/HiLog';
import ContactListItem from './ContactListItem';
import { DataItemType } from '../contract/DataType';
import Calls from '../../../../../call/src/main/ets/contract/Calls';
import { CallLog } from '../../../../../call/src/main/ets/entity/CallLog';
import CallLogBuilder from '../../../../../call/src/main/ets/entity/CallLogBuilder';
import { SearchContacts } from '../contract/SearchContacts';
import SearchContactListItem from './SearchContactListItem';
import ContactUsuallyListItem from './ContactUsuallyListItem';
const TAG = "ContactRepository";
@@ -207,14 +213,24 @@ export class ContactRepository implements IContactRepository {
return new ContactList({});
}
findByPhoneIsNotNull(callback) {
this.getAllContactNumbers((contactNumberMap) => {
findByPhoneIsNotNull(favorite: number, editContact: number, callback) {
HiLog.i(TAG, 'initContactsList resultList success favoriteForm favorite :' + favorite + "---" + editContact);
this.getAllContactNumbers(favorite, editContact, (contactNumberMap) => {
this.getDataAbilityHelper().then((dataAbilityHelper) => {
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.equalTo(RawContacts.IS_DELETED, '0')
.and()
.equalTo(Contacts.HAS_PHONE_NUMBER, '1')
.orderByAsc(RawContacts.SORT_FIRST_LETTER);
if (-1 !== editContact || 0 === favorite) {
conditionArgs.equalTo(RawContacts.IS_DELETED, '0');
if (0 === favorite) {
conditionArgs.and();
conditionArgs.equalTo(RawContacts.FAVORITE, 0);
}
conditionArgs.orderByAsc(RawContacts.SORT_FIRST_LETTER);
} else {
conditionArgs.equalTo(RawContacts.IS_DELETED, '0')
.and()
.equalTo(Contacts.HAS_PHONE_NUMBER, '1')
.orderByAsc(RawContacts.SORT_FIRST_LETTER);
}
dataAbilityHelper.query(Contacts.CONTACT_URI, conditionArgs, ContactListItem.COLUMNS)
.then(resultSet => {
let rst: ContactListItem[] = [];
@@ -251,11 +267,15 @@ export class ContactRepository implements IContactRepository {
/**
* 查询所有联系人手机号
*/
private getAllContactNumbers(callback) {
private getAllContactNumbers(favorite: number, editContact: number, callback) {
this.getDataAbilityHelper().then((dataAbilityHelper) => {
let resultColumns = [RawContacts.CONTACT_ID, Data.DETAIL_INFO, Data.EXTEND7, Data.CUSTOM_DATA];
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.equalTo(Data.TYPE_ID, DataItemType.PHONE).orderByAsc(RawContacts.CONTACT_ID);
if (-1 !== editContact || 0 === favorite) {
conditionArgs.orderByAsc(RawContacts.CONTACT_ID);
} else {
conditionArgs.equalTo(Data.TYPE_ID, DataItemType.PHONE).orderByAsc(RawContacts.CONTACT_ID);
}
dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, resultColumns).then(resultSet => {
// 用于存储联系人及其电话号码的对应关系
let contactNumberMap = new Map();
@@ -442,4 +462,236 @@ export class ContactRepository implements IContactRepository {
}
return contacts;
}
findAllFavorite(actionData, callback) {
HiLog.i(TAG, 'refreshUsually findAllFavorite start.');
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.equalTo(RawContacts.IS_DELETED, '0');
conditionArgs.and();
conditionArgs.equalTo(RawContacts.FAVORITE, 1);
conditionArgs.and();
conditionArgs.orderByAsc(RawContacts.FAVORITE_ORDER);
this.getDataAbilityHelper().then((dataAbilityHelper) => {
dataAbilityHelper.query(Contacts.CONTACT_URI, conditionArgs, ContactListItem.COLUMNS)
.then(resultSet => {
let rst: ContactListItem[] = [];
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
rst.push(new ContactListItem(resultSet));
} while (resultSet.goToNextRow());
resultSet.close();
HiLog.i(TAG, 'findAllFavorite query data success.');
callback(rst);
}
})
.catch(error => {
HiLog.e(TAG, 'findAllFavorite error:%s' + JSON.stringify(error.message));
callback([]);
});
}).catch(error => {
HiLog.e(TAG, 'findAllFavorite error:%s' + JSON.stringify(error.message));
callback([]);
});
}
findAllUsually(actionData, callback) {
HiLog.i(TAG, 'refreshUsually findAllUsually start.');
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.groupBy([Calls.DISPLAY_NAME, Calls.PHONE_NUMBER]).distinct();
conditionArgs.and();
conditionArgs.orderByDesc(Calls.TALK_DURATION);
conditionArgs.and();
conditionArgs.orderByDesc(Calls.CREATE_TIME);
this.getDataAbilityHelper().then((dataAbilityHelper) => {
dataAbilityHelper.query(Calls.CALL_LOG_URI, conditionArgs, null)
.then(resultSet => {
let rst: CallLog[] = [];
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
let builder = CallLogBuilder.fromResultSet(resultSet);
if (builder.id > 0) {
rst.push(new CallLog(builder));
}
} while (resultSet.goToNextRow());
resultSet.close();
HiLog.i(TAG, 'findAllUsually query data success.');
callback(rst);
}
})
.catch(error => {
HiLog.e(TAG, 'findAllUsually error:%s' + JSON.stringify(error.message));
callback([]);
});
}).catch(error => {
HiLog.e(TAG, 'findAllUsually error:%s' + JSON.stringify(error.message));
callback([]);
});
}
getDisplayNameByFavorite(displayName, usuallyPhone, callback) {
HiLog.i(TAG, 'getDisplayNameByFavorite start.');
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.equalTo(RawContacts.IS_DELETED, '0');
conditionArgs.and();
conditionArgs.in(RawContacts.DISPLAY_NAME, displayName);
conditionArgs.and();
conditionArgs.in(Data.DETAIL_INFO, usuallyPhone);
conditionArgs.and();
conditionArgs.equalTo(RawContacts.FAVORITE, 0);
conditionArgs.and();
conditionArgs.equalTo(Data.CONTENT_TYPE, 'phone');
this.getDataAbilityHelper().then((dataAbilityHelper) => {
dataAbilityHelper.query(Data.CONTENT_URI, conditionArgs, ContactUsuallyListItem.COLUMNS)
.then(resultSet => {
let rst: ContactUsuallyListItem[] = [];
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
rst.push(new ContactUsuallyListItem(resultSet));
} while (resultSet.goToNextRow());
resultSet.close();
HiLog.i(TAG, 'getDisplayNameByFavorite query data sc.');
callback(rst);
}
})
.catch(error => {
HiLog.e(TAG, 'getDisplayNameByFavorite error:%s' + JSON.stringify(error.message));
callback([]);
});
}).catch(error => {
HiLog.e(TAG, 'getDisplayNameByFavorite error:%s' + JSON.stringify(error.message));
callback([]);
});
}
searchContact(actionData, callback) {
HiLog.i(TAG, "searchContact start.");
let conditionArgs = new dataSharePredicates.DataSharePredicates();
let searchValue: string = actionData.value;
conditionArgs.beginWrap()
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone')
conditionArgs.and()
conditionArgs.beginWrap()
conditionArgs.like(SearchContacts.DETAIL_INFO, '%' + searchValue + '%')
conditionArgs.endWrap()
conditionArgs.or()
conditionArgs.beginWrap()
conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, '#')
conditionArgs.and()
conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + searchValue + '%')
conditionArgs.endWrap()
conditionArgs.endWrap()
conditionArgs.or()
conditionArgs.beginWrap()
conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, searchValue[0].toUpperCase())
conditionArgs.and()
conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + searchValue + '%')
conditionArgs.and()
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone')
conditionArgs.endWrap()
conditionArgs.or()
conditionArgs.beginWrap()
conditionArgs.equalTo(SearchContacts.SORT_FIRST_LETTER, searchValue.toUpperCase())
conditionArgs.and()
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone')
conditionArgs.endWrap()
conditionArgs.or()
conditionArgs.beginWrap()
conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + actionData.value + '%')
conditionArgs.and()
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone')
conditionArgs.endWrap()
conditionArgs.or()
conditionArgs.beginWrap()
conditionArgs.like(SearchContacts.SEARCH_NAME, '%' + actionData.value + '%')
conditionArgs.and()
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'name')
conditionArgs.and()
conditionArgs.equalTo(SearchContacts.HAS_PHONE_NUMBER, '0')
conditionArgs.endWrap()
conditionArgs.and()
conditionArgs.groupBy([SearchContacts.ROW_CONTACT_ID]).distinct();
this.getDataAbilityHelper().then((dataAbilityHelper) => {
dataAbilityHelper.query(SearchContacts.CONTENT_URI, conditionArgs, SearchContactListItem.COLUMNS)
.then(resultSet => {
HiLog.i(TAG, "searchContact resultSet.rowCount : " + JSON.stringify(resultSet.rowCount) );
let rst: SearchContactListItem[] = [];
let goTo: boolean = false;
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
rst.push(new SearchContactListItem(resultSet));
goTo = resultSet.goToNextRow();
} while (goTo);
resultSet.close();
HiLog.i(TAG, 'searchContact query data success.');
callback(rst);
}
})
.catch(error => {
HiLog.i(TAG, 'searchContact error:%s' + JSON.stringify(error.message));
callback([]);
});
}).catch(error => {
HiLog.i(TAG, 'searchContact:%s' + JSON.stringify(error.message));
callback([]);
});
}
queryT9PhoneIsNotNull(favorite: any, callback) {
this.getAllContactNumbers(0, 0, (contactNumberMap) => {
this.getDataAbilityHelper().then((dataAbilityHelper) => {
let conditionArgs = new dataSharePredicates.DataSharePredicates();
conditionArgs.like(SearchContacts.DETAIL_INFO, `%${favorite.teleNumber}%`);
conditionArgs.equalTo(SearchContacts.CONTENT_TYPE, 'phone');
conditionArgs.orderByAsc(SearchContacts.DISPLAY_NAME)
dataAbilityHelper.query(
SearchContacts.CONTENT_URI,
conditionArgs,
SearchContactListItem.COLUMNS
).then(resultSet => {
let rst: ContactListItem[] = [];
if (resultSet.rowCount === 0) {
resultSet.close();
callback(rst);
} else {
resultSet.goToFirstRow();
do {
let id = resultSet.getLong(resultSet.getColumnIndex(Contacts.ID));
if (!contactNumberMap.has(id)) {
HiLog.w(TAG, 'findAll: contact id is invalid or contact has no phone number.');
continue;
}
let contactListItem = new ContactListItem(resultSet);
contactListItem.phoneNumbers = contactNumberMap.get(id);
rst.push(contactListItem);
} while (resultSet.goToNextRow());
resultSet.close();
callback(rst);
}
})
.catch(error => {
HiLog.w(TAG, 'findAll error:%s' + JSON.stringify(error.message));
callback();
});
}).catch(error => {
HiLog.w(TAG, 'error:%s' + JSON.stringify(error.message));
callback();
});
});
}
}
@@ -0,0 +1,53 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Contact from '../entity/Contact';
import { Contacts } from '../contract/Contacts';
import { RawContacts } from '../contract/RawContacts';
import ContactBuilder from '../entity/ContactBuilder';
import { Data } from '../contract/Data';
export default class ContactUsuallyListItem {
static readonly COLUMNS: string[] = [Data.RAW_CONTACT_ID, Contacts.QUICK_SEARCH_KEY, RawContacts.DISPLAY_NAME,
RawContacts.SORT_FIRST_LETTER, RawContacts.PHOTO_FIRST_NAME, Contacts.COMPANY, Contacts.POSITION,
RawContacts.FAVORITE_ORDER, Data.DETAIL_INFO, Data.CONTENT_TYPE];
readonly id: number;
readonly displayName: string;
readonly sortFirstLetter: string;
readonly photoFirstName: string;
readonly quickSearchKey: string;
readonly company: string;
readonly position: string;
readonly favoriteOrder: string;
readonly detailInfo: string;
readonly contentType: string;
constructor(resultSet: any) {
this.id = resultSet.getLong(resultSet.getColumnIndex(Data.RAW_CONTACT_ID));
this.displayName = resultSet.getString(resultSet.getColumnIndex(RawContacts.DISPLAY_NAME));
this.sortFirstLetter = resultSet.getString(resultSet.getColumnIndex(RawContacts.SORT_FIRST_LETTER));
this.photoFirstName = resultSet.getString(resultSet.getColumnIndex(RawContacts.PHOTO_FIRST_NAME));
this.quickSearchKey = resultSet.getString(resultSet.getColumnIndex(Contacts.QUICK_SEARCH_KEY));
this.company = resultSet.getString(resultSet.getColumnIndex(Contacts.COMPANY));
this.position = resultSet.getString(resultSet.getColumnIndex(Contacts.POSITION));
this.favoriteOrder = resultSet.getString(resultSet.getColumnIndex(RawContacts.FAVORITE_ORDER));
this.detailInfo = resultSet.getString(resultSet.getColumnIndex(Data.DETAIL_INFO));
this.contentType = resultSet.getString(resultSet.getColumnIndex(Data.CONTENT_TYPE));
}
// createContact() {
// return new Contact(new ContactBuilder(this.id));
// }
}
@@ -0,0 +1,49 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Contact from '../entity/Contact';
import { Contacts } from '../contract/Contacts';
import { RawContacts } from '../contract/RawContacts';
import ContactBuilder from '../entity/ContactBuilder';
export default class FavoriteListItem {
static readonly COLUMNS: string[] = [Contacts.ID, Contacts.QUICK_SEARCH_KEY, RawContacts.DISPLAY_NAME,
RawContacts.SORT_FIRST_LETTER, RawContacts.PHOTO_FIRST_NAME, Contacts.COMPANY, Contacts.POSITION];
readonly id: number;
readonly displayName: string;
readonly sortFirstLetter: string;
readonly photoFirstName: string;
readonly quickSearchKey: string;
readonly company: string;
readonly position: string;
phoneNumbers: [] = [];
constructor(resultSet: any) {
this.id = resultSet.getLong(resultSet.getColumnIndex(Contacts.ID));
this.displayName = resultSet.getString(resultSet.getColumnIndex(RawContacts.DISPLAY_NAME));
this.sortFirstLetter = resultSet.getString(resultSet.getColumnIndex(RawContacts.SORT_FIRST_LETTER));
this.photoFirstName = resultSet.getString(resultSet.getColumnIndex(RawContacts.PHOTO_FIRST_NAME));
this.quickSearchKey = resultSet.getString(resultSet.getColumnIndex(Contacts.QUICK_SEARCH_KEY));
this.company = resultSet.getString(resultSet.getColumnIndex(Contacts.COMPANY));
this.position = resultSet.getString(resultSet.getColumnIndex(Contacts.POSITION));
}
createContact() {
return new Contact(new ContactBuilder(this.id));
}
}
@@ -26,10 +26,10 @@ export default interface IContactRepository {
save: (contact: ContactDelta, callback) => void;
findById: (id: number, callback) => void;
findByQuickSearchKey: (searchKey: string, callback) => void;
findAll: (actionData: any, callback) => void;
findAll: (favorite: number, actionData: any, callback) => void;
findAllWithBookIndex: () => ContactList;
search: (queryStr: string) => ContactList;
findByPhoneIsNotNull: (callback) => void;
findByPhoneIsNotNull: (favorite: number, editContact: number, callback) => void;
findByMailIsNotNull: () => ContactList;
deleteByIdIn: (ids: number[]) => boolean;
deleteById: (id: number, callback) => void;
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Contact from '../entity/Contact';
import ContactBuilder from '../entity/ContactBuilder';
import { SearchContacts } from '../contract/SearchContacts';
export default class SearchContactListItem {
static readonly COLUMNS: string[] = [SearchContacts.ID, SearchContacts.ACCOUNT_ID, SearchContacts.CONTACT_ID,
SearchContacts.ROW_CONTACT_ID, SearchContacts.SEARCH_NAME, SearchContacts.DISPLAY_NAME, SearchContacts.PHONETIC_NAME,
SearchContacts.PHOTO_ID, SearchContacts.PHOTO_FILE_ID, SearchContacts.IS_DELETED, SearchContacts.POSITION,
SearchContacts.PHOTO_FIRST_NAME, SearchContacts.SORT_FIRST_LETTER, SearchContacts.CUSTOM_DATA,
SearchContacts.DETAIL_INFO, SearchContacts.CONTENT_TYPE, SearchContacts.HAS_PHONE_NUMBER];
readonly id: number;
readonly accountId: string;
readonly contactId: string;
readonly rawContactId: string;
readonly searchName: string;
readonly displayName: string;
readonly phoneticName: string;
readonly photoId: string;
readonly photoFileId: string;
readonly isDeleted: number;
readonly position: string;
readonly photoFirstName: string;
readonly sortFirstLetter: string;
readonly customData: string;
readonly detailInfo: string;
readonly contentType: string;
readonly hasPhoneNumber: string;
constructor(resultSet: any) {
this.id = resultSet.getLong(resultSet.getColumnIndex(SearchContacts.ID));
this.accountId = resultSet.getString(resultSet.getColumnIndex(SearchContacts.ACCOUNT_ID));
this.contactId = resultSet.getString(resultSet.getColumnIndex(SearchContacts.CONTACT_ID));
this.rawContactId = resultSet.getString(resultSet.getColumnIndex(SearchContacts.ROW_CONTACT_ID));
this.searchName = resultSet.getString(resultSet.getColumnIndex(SearchContacts.SEARCH_NAME));
this.displayName = resultSet.getString(resultSet.getColumnIndex(SearchContacts.DISPLAY_NAME));
this.phoneticName = resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHONETIC_NAME));
this.photoId = resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHOTO_ID));
this.photoFileId = resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHOTO_FILE_ID));
this.isDeleted = resultSet.getString(resultSet.getColumnIndex(SearchContacts.IS_DELETED));
this.position = resultSet.getString(resultSet.getColumnIndex(SearchContacts.POSITION));
this.photoFirstName = resultSet.getString(resultSet.getColumnIndex(SearchContacts.PHOTO_FIRST_NAME));
this.sortFirstLetter = resultSet.getString(resultSet.getColumnIndex(SearchContacts.SORT_FIRST_LETTER));
this.customData = resultSet.getString(resultSet.getColumnIndex(SearchContacts.CUSTOM_DATA));
this.detailInfo = resultSet.getString(resultSet.getColumnIndex(SearchContacts.DETAIL_INFO));
this.contentType = resultSet.getString(resultSet.getColumnIndex(SearchContacts.CONTENT_TYPE));
this.hasPhoneNumber = resultSet.getString(resultSet.getColumnIndex(SearchContacts.HAS_PHONE_NUMBER));
}
}
@@ -69,6 +69,20 @@ export class PhoneNumber {
});
}
dialerSpecialCode() {
if (this.number.length === 0) {
return;
}
let phoneNumber = this.number;
call.inputDialerSpecialCode(phoneNumber, (err) => {
if (err) {
HiLog.e(TAG, 'inputDialerSpecialCode error: ' + JSON.stringify(err));
} else {
HiLog.e(TAG, 'inputDialerSpecialCode success');
}
});
}
sendMessage(formatnum?:string, name?: string) {
HiLog.i(TAG, 'send message.');
MmsService.sendMessage(this.number, formatnum, name);
BIN
View File
Binary file not shown.