UNPKG

ngx-tencent-im

Version:
752 lines (733 loc) 283 kB
import * as i0 from '@angular/core'; import { InjectionToken, Injectable, Inject, Component, ChangeDetectionStrategy, Input, ViewChild, EventEmitter, Output, NgModule } from '@angular/core'; import { Subject } from 'rxjs'; import * as i1 from '@ngrx/store'; import { createAction, props, createSelector, createReducer, on, StoreModule } from '@ngrx/store'; import TIM$1 from 'tim-js-sdk'; import TIMUploadPlugin from 'tim-upload-plugin'; import * as i1$1 from '@angular/forms'; import { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms'; import * as i2 from 'ng-zorro-antd/modal'; import { NzModalModule } from 'ng-zorro-antd/modal'; import * as i5 from 'ng-zorro-antd/form'; import { NzFormModule } from 'ng-zorro-antd/form'; import * as i6 from 'ng-zorro-antd/radio'; import { NzRadioModule } from 'ng-zorro-antd/radio'; import * as i7 from 'ng-zorro-antd/button'; import { NzButtonModule } from 'ng-zorro-antd/button'; import * as i8 from 'ng-zorro-antd/grid'; import * as i9 from 'ng-zorro-antd/input'; import { NzInputModule } from 'ng-zorro-antd/input'; import * as i5$1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i10 from 'ng-zorro-antd/core/wave'; import * as i6$1 from 'ng-zorro-antd/core/transition-patch'; import * as i1$2 from 'ng-zorro-antd/avatar'; import { NzAvatarModule } from 'ng-zorro-antd/avatar'; import * as i6$2 from 'ng-zorro-antd/icon'; import { NzIconModule } from 'ng-zorro-antd/icon'; import * as i7$1 from 'ng-zorro-antd/popover'; import { NzPopoverModule } from 'ng-zorro-antd/popover'; import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; import * as i6$3 from 'ng-zorro-antd/select'; import { NzSelectModule } from 'ng-zorro-antd/select'; import * as i1$3 from 'ng-zorro-antd/dropdown'; import { NzDropDownModule } from 'ng-zorro-antd/dropdown'; import * as i6$4 from 'ng-zorro-antd/menu'; import * as i2$1 from 'ng-zorro-antd/image'; import { NzImageModule } from 'ng-zorro-antd/image'; import * as i11 from 'ng-zorro-antd/tooltip'; import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; import * as i3 from 'ng-zorro-antd/input-number'; import { NzInputNumberModule } from 'ng-zorro-antd/input-number'; import * as i6$5 from 'ng-zorro-antd/switch'; import { NzSwitchModule } from 'ng-zorro-antd/switch'; import * as i6$6 from '@angular/cdk/drag-drop'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { NzBadgeModule } from 'ng-zorro-antd/badge'; import { NzCollapseModule } from 'ng-zorro-antd/collapse'; import { NzMessageModule } from 'ng-zorro-antd/message'; import { NzPopconfirmModule } from 'ng-zorro-antd/popconfirm'; var LoginActionTypes; (function (LoginActionTypes) { LoginActionTypes["Login"] = "[toggleIsLogin]"; })(LoginActionTypes || (LoginActionTypes = {})); const loginAction = createAction(LoginActionTypes.Login, props()); var UserActionTypes; (function (UserActionTypes) { UserActionTypes["SDKReady"] = "[user] toggleIsSDKReady"; UserActionTypes["updateCurrentUserProfile"] = "[user] updateCurrentUserProfile"; UserActionTypes["resetUser"] = "[user] resetUser"; })(UserActionTypes || (UserActionTypes = {})); const SDKReadyAction = createAction(UserActionTypes.SDKReady, props()); const updateCurrentUserProfileAction = createAction(UserActionTypes.updateCurrentUserProfile, props()); const resetUserAction = createAction(UserActionTypes.resetUser); const showAction = createAction('[showMessage]', props()); const updateMessageAction = createAction('[updateMessage]', props()); ; const updateCurrentConversationAction = createAction('[conversation] updateCurrentConversation', props()); const updateConversationListAction = createAction('[conversation] updateConversationList', props()); const resetCurrentConversationAction = createAction('[conversation] resetCurrentConversation'); const pushCurrentMessageListAction = createAction('[conversation] pushCurrentMessageList', props()); const removeMessageAction = createAction('[conversation] removeMessage', props()); const resetConversationAction = createAction('[conversation] reset'); const checkoutConversationAction = createAction('[conversation] checkoutConversation', props()); const selectPlayerStates$3 = (state) => state.currentConversationID; const getCurrentConversationID = createSelector(selectPlayerStates$3, (state) => state.conversationID); const selectConversation = (state) => state.conversation; const conversationSelector = createSelector(selectConversation, (state) => state); const selectCurrentConversation = (state) => state.conversation.currentConversation; const currentConversationSelector = createSelector(selectCurrentConversation, (state) => state); const selectConversationList = (state) => state.conversation.conversationList; const conversationListSelector = createSelector(selectConversationList, (state) => state); const selectPlayerStates$2 = (state) => state.login; const getLogin = createSelector(selectPlayerStates$2, (state) => state.isLogin); const selectPlayerStates$1 = (state) => state.message; const getMessage = createSelector(selectPlayerStates$1, (state) => state); const selectPlayerStates = (state) => state.user; const getSDkReady = createSelector(selectPlayerStates, (state) => state.isSDKReady); const currentUserProfileSelector = createSelector(selectPlayerStates, (state) => state.currentUserProfile); const updateGroupListAction = createAction('[group] updateGroupList', props()); const updateCurrentMemberListAction = createAction('[group] updateCurrentMemberList', props()); const resetCurrentMemberListAction = createAction('[group] resetCurrentMemberList'); const selectGroupListStates = (state) => state.group.groupList; const groupListSelector = createSelector(selectGroupListStates, (state) => state); const currentMemberListStates = (state) => state.group.currentMemberList; const currentMemberListSelector = createSelector(currentMemberListStates, (state) => state); const NG_Tim_CONFIG = new InjectionToken('config'); var MESSAGE_STATUS; (function (MESSAGE_STATUS) { MESSAGE_STATUS["success"] = "success"; MESSAGE_STATUS["info"] = "info"; MESSAGE_STATUS["warning"] = "warning"; MESSAGE_STATUS["error"] = "error"; })(MESSAGE_STATUS || (MESSAGE_STATUS = {})); var CONVERSATION_TYPE; (function (CONVERSATION_TYPE) { CONVERSATION_TYPE["client"] = "C2C"; CONVERSATION_TYPE["group"] = "GROUP"; CONVERSATION_TYPE["system"] = "@TIM#SYSTEM"; })(CONVERSATION_TYPE || (CONVERSATION_TYPE = {})); var TIM_TYPES; (function (TIM_TYPES) { TIM_TYPES["GRP_WORK"] = "Private"; TIM_TYPES["GRP_PUBLIC"] = "Public"; TIM_TYPES["GRP_MEETING"] = "ChatRoom"; TIM_TYPES["GRP_AVCHATROOM"] = "AVChatRoom"; })(TIM_TYPES || (TIM_TYPES = {})); const TIM = { TYPES: { "MSG_TEXT": "TIMTextElem", "MSG_IMAGE": "TIMImageElem", "MSG_SOUND": "TIMSoundElem", "MSG_AUDIO": "TIMSoundElem", "MSG_FILE": "TIMFileElem", "MSG_FACE": "TIMFaceElem", "MSG_VIDEO": "TIMVideoFileElem", "MSG_GEO": "TIMLocationElem", "MSG_GRP_TIP": "TIMGroupTipElem", "MSG_GRP_SYS_NOTICE": "TIMGroupSystemNoticeElem", "MSG_CUSTOM": "TIMCustomElem", "MSG_MERGER": "TIMRelayElem", "MSG_PRIORITY_HIGH": "High", "MSG_PRIORITY_NORMAL": "Normal", "MSG_PRIORITY_LOW": "Low", "MSG_PRIORITY_LOWEST": "Lowest", "CONV_C2C": "C2C", "CONV_GROUP": "GROUP", "CONV_SYSTEM": "@TIM%23SYSTEM", "CONV_AT_ME": 1, "CONV_AT_ALL": 2, "CONV_AT_ALL_AT_ME": 3, "GRP_PRIVATE": "Private", "GRP_WORK": "Private", "GRP_PUBLIC": "Public", "GRP_CHATROOM": "ChatRoom", "GRP_MEETING": "ChatRoom", "GRP_AVCHATROOM": "AVChatRoom", "GRP_MBR_ROLE_OWNER": "Owner", "GRP_MBR_ROLE_ADMIN": "Admin", "GRP_MBR_ROLE_MEMBER": "Member", "GRP_TIP_MBR_JOIN": 1, "GRP_TIP_MBR_QUIT": 2, "GRP_TIP_MBR_KICKED_OUT": 3, "GRP_TIP_MBR_SET_ADMIN": 4, "GRP_TIP_MBR_CANCELED_ADMIN": 5, "GRP_TIP_GRP_PROFILE_UPDATED": 6, "GRP_TIP_MBR_PROFILE_UPDATED": 7, "MSG_REMIND_ACPT_AND_NOTE": "AcceptAndNotify", "MSG_REMIND_ACPT_NOT_NOTE": "AcceptNotNotify", "MSG_REMIND_DISCARD": "Discard", "GENDER_UNKNOWN": "Gender_Type_Unknown", "GENDER_FEMALE": "Gender_Type_Female", "GENDER_MALE": "Gender_Type_Male", "KICKED_OUT_MULT_ACCOUNT": "multipleAccount", "KICKED_OUT_MULT_DEVICE": "multipleDevice", "KICKED_OUT_USERSIG_EXPIRED": "userSigExpired", "ALLOW_TYPE_ALLOW_ANY": "AllowType_Type_AllowAny", "ALLOW_TYPE_NEED_CONFIRM": "AllowType_Type_NeedConfirm", "ALLOW_TYPE_DENY_ANY": "AllowType_Type_DenyAny", "FORBID_TYPE_NONE": "AdminForbid_Type_None", "FORBID_TYPE_SEND_OUT": "AdminForbid_Type_SendOut", "JOIN_OPTIONS_FREE_ACCESS": "FreeAccess", "JOIN_OPTIONS_NEED_PERMISSION": "NeedPermission", "JOIN_OPTIONS_DISABLE_APPLY": "DisableApply", "JOIN_STATUS_SUCCESS": "JoinedSuccess", "JOIN_STATUS_ALREADY_IN_GROUP": "AlreadyInGroup", "JOIN_STATUS_WAIT_APPROVAL": "WaitAdminApproval", "GRP_PROFILE_OWNER_ID": "ownerID", "GRP_PROFILE_CREATE_TIME": "createTime", "GRP_PROFILE_LAST_INFO_TIME": "lastInfoTime", "GRP_PROFILE_MEMBER_NUM": "memberNum", "GRP_PROFILE_MAX_MEMBER_NUM": "maxMemberNum", "GRP_PROFILE_JOIN_OPTION": "joinOption", "GRP_PROFILE_INTRODUCTION": "introduction", "GRP_PROFILE_NOTIFICATION": "notification", "GRP_PROFILE_MUTE_ALL_MBRS": "muteAllMembers", "NET_STATE_CONNECTED": "connected", "NET_STATE_CONNECTING": "connecting", "NET_STATE_DISCONNECTED": "disconnected", "MSG_AT_ALL": "__kImSDK_MesssageAtALL__" }, EVENT: { "SDK_READY": "sdkStateReady", "SDK_NOT_READY": "sdkStateNotReady", "SDK_DESTROY": "sdkDestroy", "MESSAGE_RECEIVED": "onMessageReceived", "MESSAGE_REVOKED": "onMessageRevoked", "MESSAGE_READ_BY_PEER": "onMessageReadByPeer", "CONVERSATION_LIST_UPDATED": "onConversationListUpdated", "GROUP_LIST_UPDATED": "onGroupListUpdated", "GROUP_SYSTEM_NOTICE_RECEIVED": "receiveGroupSystemNotice", "PROFILE_UPDATED": "onProfileUpdated", "BLACKLIST_UPDATED": "blacklistUpdated", "KICKED_OUT": "kickedOut", "ERROR": "error", "NET_STATE_CHANGE": "netStateChange", "SDK_RELOAD": "sdkReload" }, VERSION: "2.10.2" }; class TimHelperService { constructor(store, config) { this.store = store; this.config = config; this.eventBus$ = new Subject(); this.totalUnRead = new Subject(); this.initTim(config); // 初始化监听器 this.initListener(); // 获取当前会话 this.store.select(conversationSelector).subscribe(res => { this.conversation = res; }); // 获取当前成员 this.store.select(currentMemberListSelector).subscribe(res => { this.currentMemberList = res; }); } login(userId, userSig) { if (!userSig) { throw new Error('请配置签名!'); } this.tim.login({ userID: userId, userSig }) .then((imResponse) => { this.eventBus$.next('login'); this.store.dispatch(loginAction({ isLogin: true })); // this.store.dispatch(startComputeCurrentAction()); this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.success, message: '登录成功!' })); if (imResponse.data.repeatLogin === true) { // 标识账号已登录,本次登录操作为重复登录。v2.5.1 起支持 console.log(imResponse.data.errorInfo); } }).catch((imError) => { console.warn('login error:', imError); // 登录失败的相关信息 }); } logout() { // 若有当前会话,在退出登录时已读上报 if (this.conversation.currentConversation.conversationID) { this.tim.setMessageRead({ conversationID: this.conversation.currentConversation.conversationID }); } this.tim.logout().then((res) => { this.eventBus$.next('logout'); // this.store.dispatch(stopComputeCurrentAction()); this.store.dispatch(loginAction({ isLogin: false })); this.store.dispatch(resetUserAction()); this.store.dispatch(resetConversationAction()); this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.success, message: '已退出!' })); }); } // 初始化tim监听函数 initListener() { // sdk ready this.tim.on(TIM$1.EVENT.SDK_READY, this.onReadyStateUpdate, this); // SDK NOT READT this.tim.on(TIM$1.EVENT.SDK_NOT_READY, this.onReadyStateUpdate, this); // 被踢出 this.tim.on(TIM$1.EVENT.KICKED_OUT, this.onKickOut, this); // SDK内部出错 this.tim.on(TIM$1.EVENT.ERROR, this.onError, this); // 收到新消息 this.tim.on(TIM$1.EVENT.MESSAGE_RECEIVED, this.onReceiveMessage, this); // 会话列表更新 this.tim.on(TIM$1.EVENT.CONVERSATION_LIST_UPDATED, this.onUpdateConversationList, this); // 群组列表更新 this.tim.on(TIM$1.EVENT.GROUP_LIST_UPDATED, this.onUpdateGroupList, this); // 网络监测 this.tim.on(TIM$1.EVENT.NET_STATE_CHANGE, this.onNetStateChange, this); // 已读回执 this.tim.on(TIM$1.EVENT.MESSAGE_READ_BY_PEER, this.onMessageReadByPeer, this); } onReadyStateUpdate({ name }) { const isSDKReady = name === TIM$1.EVENT.SDK_READY ? true : false; this.store.dispatch(SDKReadyAction({ SDKReadyState: isSDKReady })); if (isSDKReady) { this.tim.getMyProfile() .then(({ data }) => { this.store.dispatch(updateCurrentUserProfileAction({ profile: data })); }) .catch(error => { this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.warning, message: error.message })); }); } } onKickOut(event) { this.eventBus$.next('logout'); // this.store.dispatch(stopComputeCurrentAction()); this.store.dispatch(loginAction({ isLogin: false })); this.store.dispatch(resetUserAction()); this.store.dispatch(resetConversationAction()); this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.warning, message: '由于多实例登录被踢出,请重新登录!' })); } onError({ data }) { if (data.message !== 'Network Error') { console.log('%c error', 'color:red;font-size:20px;', data); } } onMessageReadByPeer(event) { console.log('已回执', event); } onReceiveMessage({ data: messageList }) { // this.handleVideoMessage(messageList); // this.handleAt(messageList); // this.handleQuitGroupTip(messageList); this.store.dispatch(pushCurrentMessageListAction({ message: messageList })); } // 会话列表更新 onUpdateConversationList(event) { this.store.dispatch(updateConversationListAction({ conversationList: event.data })); } // 群列表更新 onUpdateGroupList(event) { this.store.dispatch(updateGroupListAction({ groupList: event.data })); } onNetStateChange(event) { console.log('网络监测::', event); } /** * 切换会话 * 调用时机:切换会话时 */ checkoutConversation(conversationID) { this.store.dispatch(resetCurrentMemberListAction()); // 1.切换会话前,将切换前的会话进行已读上报 if (this.conversation.currentConversation.conversationID) { const prevConversationID = this.conversation.currentConversation.conversationID; this.tim.setMessageRead({ conversationID: prevConversationID }); } // 2.待切换的会话也进行已读上报 this.tim.setMessageRead({ conversationID }); // 3. 获取会话信息 return this.tim.getConversationProfile(conversationID).then((res) => { // 3.1 更新当前会话 this.store.dispatch(updateCurrentConversationAction({ conversation: res.data.conversation })); // 3.2 获取消息列表 this.getMessageList(conversationID); if (res.data.conversation.type === TIM$1.TYPES.CONV_GROUP) { this.getGroupMemberList(res.data.conversation.groupProfile.groupID); } return Promise.resolve(); }); // .catch(err => { // this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.error, message: err })); // }); } /** * @description 获取消息 */ getMessageList(conversationID) { if (this.conversation.isCompleted) { this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.info, message: '已经没有更多的历史消息了哦' })); return; } const { nextReqMessageID, currentMessageList } = this.conversation; this.tim.getMessageList({ conversationID, nextReqMessageID, count: 15 }) .then((imResponse) => { this.store.dispatch(updateMessageAction({ nextReqMessageID: imResponse.data.nextReqMessageID, isCompleted: imResponse.data.isCompleted, currentMessageList: [...imResponse.data.messageList, ...currentMessageList] })); }); } /** * @description 获取群成员 */ getGroupMemberList(groupID) { this.tim.getGroupMemberList({ groupID, offset: this.currentMemberList.length, count: 30 }).then((imResponse) => { this.store.dispatch(updateCurrentMemberListAction({ currentMemberList: imResponse.data.memberList })); }); } initTim(config) { // const cosImport = await import('cos-js-sdk-v5'); // const timImport = await import('tim-js-sdk'); this.tim = TIM$1.create({ SDKAppID: config.sdkAppId, oversea: config.oversea, }); // 无日志级别 this.tim.setLogLevel(config.level || 1); // 注册 cos this.tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin }); } } TimHelperService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: TimHelperService, deps: [{ token: i1.Store }, { token: NG_Tim_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); TimHelperService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: TimHelperService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: TimHelperService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: function () { return [{ type: i1.Store }, { type: undefined, decorators: [{ type: Inject, args: [NG_Tim_CONFIG] }] }]; } }); function titleNotify(count) { const hasNewMessage = count > 0; if (hasNewMessage) { if (document.title.search(/\((.*?)\)/) >= 0) { document.title = document.title.replace(/\((.*?)\)/, `(${count > 99 ? '99+' : count})`); } else { document.title = `(${count})${document.title}`; } } else { document.title = document.title.replace(/\((.*?)\)/, ''); } } class EditProfileComponent { constructor(fb, modalRef, store, timHelperService) { this.fb = fb; this.modalRef = modalRef; this.store = store; this.timHelperService = timHelperService; this.radioOption = [ { label: '男', value: TIM.TYPES.GENDER_MALE }, { label: '女', value: TIM.TYPES.GENDER_FEMALE }, { label: '不显示', value: TIM.TYPES.GENDER_UNKNOWN }, ]; } ngOnInit() { this.form = this.fb.group({ avatar: [this.userProfile.avatar], nick: [this.userProfile.nick], gender: [this.userProfile.gender] }); } submitForm() { const formValue = this.form.value; if (formValue.avatar && formValue.avatar.indexOf('http') === -1) { this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.warning, message: '头像应该是 Url 地址' })); formValue.avatar = ''; return; } const options = {}; // 过滤空串 Object.keys(formValue).forEach(key => { if (formValue[key]) { options[key] = formValue[key]; } }); this.timHelperService.tim .updateMyProfile(options) .then(() => { this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.success, message: '修改成功' })); this.modalRef.destroy(); }) .catch(imError => { this.store.dispatch(showAction({ msgType: MESSAGE_STATUS.error, message: imError.message })); }); } } EditProfileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: EditProfileComponent, deps: [{ token: i1$1.FormBuilder }, { token: i2.NzModalRef }, { token: i1.Store }, { token: TimHelperService }], target: i0.ɵɵFactoryTarget.Component }); EditProfileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: EditProfileComponent, selector: "im-edit-profile", inputs: { userProfile: "userProfile" }, ngImport: i0, template: "<form nz-form [formGroup]=\"form\" (ngSubmit)=\"submitForm()\">\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\">\r\n <span>\u5934\u50CF</span>\r\n </nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <input nz-input formControlName=\"avatar\" placeholder=\"\u5934\u50CF\u5730\u5740\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\" nzFor=\"avatar\">\u6635\u79F0</nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <input nz-input formControlName=\"nick\" placeholder=\"\u6635\u79F0\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\">\u6027\u522B\r\n </nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <nz-radio-group formControlName=\"gender\">\r\n <label *ngFor=\"let item of radioOption\" nz-radio\r\n [nzValue]=\"item.value\">{{item.label}}</label>\r\n </nz-radio-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n\r\n <nz-form-item nz-row nzJustify=\"center\">\r\n <nz-form-control [nzSpan]=\"12\" nzPush=\"8\">\r\n <button nz-button nzType=\"primary\">\u786E\u5B9A</button>\r\n </nz-form-control>\r\n <nz-form-control [nzSpan]=\"12\">\r\n <button nz-button nzType=\"default\" type=\"button\" (click)=\"modalRef.destroy()\">\u53D6\u6D88</button>\r\n </nz-form-control>\r\n </nz-form-item>\r\n</form>\r\n", styles: [""], components: [{ type: i5.NzFormItemComponent, selector: "nz-form-item", exportAs: ["nzFormItem"] }, { type: i5.NzFormLabelComponent, selector: "nz-form-label", inputs: ["nzFor", "nzRequired", "nzNoColon", "nzTooltipTitle", "nzTooltipIcon"], exportAs: ["nzFormLabel"] }, { type: i5.NzFormControlComponent, selector: "nz-form-control", inputs: ["nzSuccessTip", "nzWarningTip", "nzErrorTip", "nzValidatingTip", "nzExtra", "nzAutoTips", "nzDisableAutoTips", "nzHasFeedback", "nzValidateStatus"], exportAs: ["nzFormControl"] }, { type: i6.NzRadioGroupComponent, selector: "nz-radio-group", inputs: ["nzDisabled", "nzButtonStyle", "nzSize", "nzName"], exportAs: ["nzRadioGroup"] }, { type: i6.NzRadioComponent, selector: "[nz-radio],[nz-radio-button]", inputs: ["nzValue", "nzDisabled", "nzAutoFocus"], exportAs: ["nzRadio"] }, { type: i7.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }], directives: [{ type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.NzFormDirective, selector: "[nz-form]", inputs: ["nzLayout", "nzNoColon", "nzAutoTips", "nzDisableAutoTips", "nzTooltipIcon"], exportAs: ["nzForm"] }, { type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i8.NzRowDirective, selector: "[nz-row],nz-row,nz-form-item", inputs: ["nzAlign", "nzJustify", "nzGutter"], exportAs: ["nzRow"] }, { type: i8.NzColDirective, selector: "[nz-col],nz-col,nz-form-control,nz-form-label", inputs: ["nzFlex", "nzSpan", "nzOrder", "nzOffset", "nzPush", "nzPull", "nzXs", "nzSm", "nzMd", "nzLg", "nzXl", "nzXXl"], exportAs: ["nzCol"] }, { type: i9.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzBorderless", "nzSize", "disabled"], exportAs: ["nzInput"] }, { type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { type: i6$1.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: EditProfileComponent, decorators: [{ type: Component, args: [{ selector: 'im-edit-profile', changeDetection: ChangeDetectionStrategy.OnPush, template: "<form nz-form [formGroup]=\"form\" (ngSubmit)=\"submitForm()\">\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\">\r\n <span>\u5934\u50CF</span>\r\n </nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <input nz-input formControlName=\"avatar\" placeholder=\"\u5934\u50CF\u5730\u5740\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\" nzFor=\"avatar\">\u6635\u79F0</nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <input nz-input formControlName=\"nick\" placeholder=\"\u6635\u79F0\" />\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n <nz-form-item>\r\n <nz-form-label [nzSm]=\"6\" [nzXs]=\"24\">\u6027\u522B\r\n </nz-form-label>\r\n <nz-form-control [nzSm]=\"14\" [nzXs]=\"24\">\r\n <nz-radio-group formControlName=\"gender\">\r\n <label *ngFor=\"let item of radioOption\" nz-radio\r\n [nzValue]=\"item.value\">{{item.label}}</label>\r\n </nz-radio-group>\r\n </nz-form-control>\r\n </nz-form-item>\r\n\r\n\r\n <nz-form-item nz-row nzJustify=\"center\">\r\n <nz-form-control [nzSpan]=\"12\" nzPush=\"8\">\r\n <button nz-button nzType=\"primary\">\u786E\u5B9A</button>\r\n </nz-form-control>\r\n <nz-form-control [nzSpan]=\"12\">\r\n <button nz-button nzType=\"default\" type=\"button\" (click)=\"modalRef.destroy()\">\u53D6\u6D88</button>\r\n </nz-form-control>\r\n </nz-form-item>\r\n</form>\r\n", styles: [""] }] }], ctorParameters: function () { return [{ type: i1$1.FormBuilder }, { type: i2.NzModalRef }, { type: i1.Store }, { type: TimHelperService }]; }, propDecorators: { userProfile: [{ type: Input }] } }); class AvatarComponent { constructor() { this.shape = 'circle'; this.size = 'large'; this.type = 'C2C'; } set src(value) { this._src = value; if (/^(https:|http:|\/\/)/.test(value)) { this.avatarSrc = value; } else { this.avatarSrc = this.getDefaultAvatar(); } } ; get src() { return this._src; } ngOnInit() { } getDefaultAvatar() { switch (this.type) { case 'C2C': // 个人头像 return 'https://imgcache.qq.com/open/qcloud/video/act/webim-avatar/avatar-2.png'; case 'GROUP': // 群默认头像 return 'https://imgcache.qq.com/open/qcloud/video/act/webim-avatar/avatar-3.png'; case TIM.TYPES.CONV_SYSTEM: return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAK4AAACpCAMAAAHy0MbyAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJYUExURQrBYAvBYRPDZhzGbCXIcSrJdSHHbxjFaQ7CYwzBYSnJdEzSi3bcpqLnw87z3+X47uj58Ov68uz68+n58ef579/36rzu05Djt2TYmz7OghnFai/KeIHfrcPw2OP47fz+/f////P8+Nb15K7ry1vVlBrFaw7CYlDTjqrqyPP899j15YrhsxDCZFfUksDv1vr+/C7KdyzKdq3qynLbo2HXmf7//rTszhTDZo/jtk7SjCjJc7nt0fX9+THLes3y3/3//oXgsA3CYjTMe5HjuA/CY8/z4IDfrRbEaLft0GbYnO779Pb9+cLv1x3GbNL04ub575zmv5flvEDPgzDLeaXoxIzitPD79TXMfB7GbeL47F7WlhLDZavqyfj9+03SjN326YvitEbQh3jdqO/79CLHcLHrzE/TjSPHcOT47vH79rHrzUvSivf9+vn++8zy3lXUkdf15SDHblnVk+D36ybIclrVlGfZnHjdpznNf1HTjhfEadv26I3itUfRiMfx26Pow0HPhJPkuZjlvMHv1zjNfkTQhWnZnhvFa8ry3TLLepXkurbt0Gvan4LfrknRiV/Wl9X05HHbo7/v1Z3mv8jx24jhskjRiTrNf8nx3Mvy3WLXmUfQh0XQhu3681LTj9n15ljVk2XYm6/ry+H37Or68bXsz2PYmjfMfW3aoLvu0zbMfTPLe77u1S7KeErRirDrzNr253fcpkPPhSvJdafpxr3u1N736n/frPL89o7itW/boWDXl3ndqJvmvvv+/Xveqsbx2tz26fT8+BHDZD3OgYTgr4fhsQAAAKRC35oAAADIdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8A9ppxxwAAAAlwSFlzAAAXEQAAFxEByibzPwAABVpJREFUaEPt2zuP2koUB3BaN1dCLikwols5fVb5Cim3QaxEtNomDdJKaHWbbaBASPcTUKVBShv6NNH6e2Uefxs/5u0H7NX5NXiOzwwjY+yxPR4N422MhYqEw/KFiDbiZ3UY0V7D1ThizDMiAmIcIkIURaycxlGEQCFLRvUvlDJ8/j+MP2OhTGymxoqxCDc2ioz6/mgo5hB1C39BtBZGkEFAQIiLERKiKN2xtc0ffpSkD1MsVhzxSZxgoydLlA2QKfyLmA7S4Buiaitk5RBWQ04BYTXkFBBWQ04BYTXkFA6IqyCl5AvWNGB9DVbWYW3NGWvVZGOZsb8X8i+MAiHe5rOFeYfMbcSuliQzlA3WSGUQ0fqGPAExHWRJvxFUwzk2h6gacnKIqiEnt0VYCTm5FcJKyMlVzrB1yMl9tFzTBn5ASgFxFWRc6I+YSCjDmoZGDzisq8PaKuWQR52qaTi/BKjB2jo28mZjb7k2TkRRLGv9lCcgTUdrkiQbpbZTVk5003VYH2X3lo4SQkiAN3EokhYbBNuqDFWkN6xqoTRWKmt5d2SJZhSQESQfAyohJwRa0ECSvzka0LhHmrcZGtBYI80b6usYR1kG7ARuRO1KH63d0D8GausFdfiAykbI9fAdNS0+Id2RU2cl1HCivHrQ8bgPihpuvqOSi/RxFRd4XSwyU1bEIndKUcVbym8fYplhBeNlswfWVIJuTXh35WIH7lhjvEHhAcEuRO9/ZKOrPSKEEEIIIVey+e+f8Wy8e3V4yuxuWb4AV02QCFO/rH9CvB3FLRPlbB5P6lsmWBnuBQ3VYXUwNNPg8NTPhA+o1Vr9eKb7UUgJUnt8WDFHTgDDXTkGSQHM97ncHt6ooAGN4NtctstZZHnbo74O0rxpHsgVkObtHvV1Qq+4be2G3hCndiVqV6J2pb7afUJ9HbcpYk316Xx15smAeqiuhzxPW9TWq8xQdmW9u+53J7VQ3Dc0CJgCa98KHJLd2c5tOaQ7QzUr46yoJpeNK3ndY85QyYXPcApV3KCOA9cfTZqglp1fu+7/utT9Z9NNoFJLj2s8nuBYZSxx1dKd919OTKxixLOiNC+OnnkJBdtUKzN+ALo8gub/byy2xVq6bMRKoR3WxekjllfsJw1+fl7H+pjEfHd65ztKV90did/q8hynw+lmomEIfi6mdEKr284nx02y7GlPU+4IIYQQQgghhBBisVxuNptOp4j0YpOt60/wF/MfN9nvHzt0UGH2OfTJUT9eTdMipPmt9Hhj2K4Vr6hwTYcFOuOiu3lUYZauWzZ31S3s90hD2F3vQKF4xdBudq3/3G90wFfoc+t2grYtN75Gf1/x5QEWaGJAL7YpBSah0w3C2SZWGI0HPzzoJ0+66GZ2rDuPV+tUWkyvDGKbvGOx7vbxn9UnfG+g1cDnirbdfUE7A6Hu9om62yfqbp+ou336YN1tMTjn4oFPwm5TR/U6m+flJOCKvSr8vZQA5ZlggQa8/jn7TMTU8ZpZ20ary7SLfMpiv9J2V2klsfuE3WBHfFcnMjTal32buwsKcfgbcQ463bRSfxeZ6Rpf0a2A9xtcTLo4fKn0soH3fAp6P/o4xfWw3+amPfzhetpzuR2+olv3fMp89+56HJ1F+4kCdpQTihVnuc/HB5TLDpOB75VJE9GjZKX6cow1Bx0xWkR4A+AB5ZIU58Gejq5hnnGUaxxCMdacnlC+EZP8qHwqvwyB/ZZF0xt7RSJdF4eN6Wl7PP7asoHmFNv2J5JuyVk3Wnu8yt/fKkq32Jwlq/tbflMmet/e/ZEdncZfj0Gvvw4s35ztXpkjhBBCCCGkrdHoLzv9X1u4OdoGAAAAAElFTkSuQmCC'; default: // 默认头像 return 'https://imgcache.qq.com/open/qcloud/video/act/webim-avatar/avatar-1.png'; } } } AvatarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); AvatarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: AvatarComponent, selector: "im-avatar", inputs: { shape: "shape", size: "size", type: "type", title: "title", src: "src" }, ngImport: i0, template: "<nz-avatar [nzSize]=\"size\" [nzShape]=\"shape\" [nzSrc]=\"avatarSrc\" [nzAlt]=\"title\" [title]=\"title\"></nz-avatar>\r\n", styles: [""], components: [{ type: i1$2.NzAvatarComponent, selector: "nz-avatar", inputs: ["nzShape", "nzSize", "nzGap", "nzText", "nzSrc", "nzSrcSet", "nzAlt", "nzIcon"], outputs: ["nzError"], exportAs: ["nzAvatar"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: AvatarComponent, decorators: [{ type: Component, args: [{ selector: 'im-avatar', template: "<nz-avatar [nzSize]=\"size\" [nzShape]=\"shape\" [nzSrc]=\"avatarSrc\" [nzAlt]=\"title\" [title]=\"title\"></nz-avatar>\r\n", styles: [""] }] }], ctorParameters: function () { return []; }, propDecorators: { shape: [{ type: Input }], size: [{ type: Input }], type: [{ type: Input }], title: [{ type: Input }], src: [{ type: Input }] } }); class ProfileCardComponent { constructor() { } set userProfile(value) { this._userProfile = value; switch (value.gender) { case TIM.TYPES.GENDER_MALE: this.className = 'icon-male'; break; case TIM.TYPES.GENDER_FEMALE: this.className = 'icon-female'; break; default: this.className = null; } } ; get userProfile() { return this._userProfile; } ; ngOnInit() { } } ProfileCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: ProfileCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); ProfileCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: ProfileCardComponent, selector: "im-profile-card", inputs: { userProfile: "userProfile" }, ngImport: i0, template: "<div class=\"profile-card-wrapper\">\r\n <div class=\"content\">\r\n <im-avatar [src]=\"userProfile?.avatar\"></im-avatar>\r\n <div class=\"basic\">\r\n <span class=\"nick text-ellipsis\">{{ userProfile?.nick || userProfile?.userID }}</span>\r\n <span class=\"iconfont\" [class]=\"className\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".profile-header{display:flex;margin-bottom:12px}.profile-card-wrapper .content{display:flex;justify-content:center;flex-direction:column;align-items:center}.basic{display:flex;align-items:center;margin-top:12px}.icon-male{color:#6391f3}.icon-female{color:#ff8096}.nick{font-size:18px;margin-right:8px;max-width:100px;display:inline-block}im-avatar::ng-deep .avatar{width:70px;height:70px}\n"], components: [{ type: AvatarComponent, selector: "im-avatar", inputs: ["shape", "size", "type", "title", "src"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: ProfileCardComponent, decorators: [{ type: Component, args: [{ selector: 'im-profile-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"profile-card-wrapper\">\r\n <div class=\"content\">\r\n <im-avatar [src]=\"userProfile?.avatar\"></im-avatar>\r\n <div class=\"basic\">\r\n <span class=\"nick text-ellipsis\">{{ userProfile?.nick || userProfile?.userID }}</span>\r\n <span class=\"iconfont\" [class]=\"className\"></span>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".profile-header{display:flex;margin-bottom:12px}.profile-card-wrapper .content{display:flex;justify-content:center;flex-direction:column;align-items:center}.basic{display:flex;align-items:center;margin-top:12px}.icon-male{color:#6391f3}.icon-female{color:#ff8096}.nick{font-size:18px;margin-right:8px;max-width:100px;display:inline-block}im-avatar::ng-deep .avatar{width:70px;height:70px}\n"] }] }], ctorParameters: function () { return []; }, propDecorators: { userProfile: [{ type: Input }] } }); class MyProfileComponent { constructor(store, modal) { this.store = store; this.modal = modal; } ngOnInit() { this.subscription = this.store.select(currentUserProfileSelector) .subscribe(res => { if (res) { this.currentUserProfile = res; } }); } editProfile() { this.modal.create({ nzTitle: `编辑资料`, nzContent: EditProfileComponent, nzMaskClosable: false, nzFooter: null, nzWidth: '40%', nzStyle: { top: '20px' }, nzComponentParams: { userProfile: this.currentUserProfile } }); } ngOnDestroy() { if (this.subscription) { this.subscription.unsubscribe(); } } } MyProfileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MyProfileComponent, deps: [{ token: i1.Store }, { token: i2.NzModalService }], target: i0.ɵɵFactoryTarget.Component }); MyProfileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: MyProfileComponent, selector: "app-my-profile", ngImport: i0, template: "<ng-template #titleTemplate>\r\n <div class=\"title-container\">\r\n <span>\u5F53\u524D\u7528\u6237</span>\r\n <i nz-icon nzType=\"setting\" nzTheme=\"outline\" (click)=\"editProfile()\"></i>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #contentTemplate>\r\n <im-profile-card [userProfile]=\"currentUserProfile\"></im-profile-card>\r\n</ng-template>\r\n\r\n<div class=\"my-profile-wrapper\">\r\n <div nz-button nz-popover nzType=\"primary\" nzPopoverTrigger=\"click\"\r\n [nzPopoverTitle]=\"titleTemplate\" nzPopoverPlacement=\"right\"\r\n [nzPopoverContent]=\"contentTemplate\">\r\n <im-avatar [src]=\"currentUserProfile.avatar\"></im-avatar>\r\n </div>\r\n</div>\r\n", styles: [".title-container{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;align-items:center}.title-container i{cursor:pointer}.my-profile-wrapper{margin:15px}.my-profile-wrapper im-avatar{cursor:pointer}.edit-my-profile{position:absolute;top:10px;right:10px;cursor:pointer}\n"], components: [{ type: ProfileCardComponent, selector: "im-profile-card", inputs: ["userProfile"] }, { type: AvatarComponent, selector: "im-avatar", inputs: ["shape", "size", "type", "title", "src"] }], directives: [{ type: i6$1.ɵNzTransitionPatchDirective, selector: "[nz-button], nz-button-group, [nz-icon], [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { type: i6$2.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { type: i7$1.NzPopoverDirective, selector: "[nz-popover]", inputs: ["nzPopoverArrowPointAtCenter", "nzPopoverTitle", "nzPopoverContent", "nz-popover", "nzPopoverTrigger", "nzPopoverPlacement", "nzPopoverOrigin", "nzPopoverVisible", "nzPopoverMouseEnterDelay", "nzPopoverMouseLeaveDelay", "nzPopoverOverlayClassName", "nzPopoverOverlayStyle", "nzPopoverBackdrop"], outputs: ["nzPopoverVisibleChange"], exportAs: ["nzPopover"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: MyProfileComponent, decorators: [{ type: Component, args: [{ selector: 'app-my-profile', template: "<ng-template #titleTemplate>\r\n <div class=\"title-container\">\r\n <span>\u5F53\u524D\u7528\u6237</span>\r\n <i nz-icon nzType=\"setting\" nzTheme=\"outline\" (click)=\"editProfile()\"></i>\r\n </div>\r\n</ng-template>\r\n\r\n<ng-template #contentTemplate>\r\n <im-profile-card [userProfile]=\"currentUserProfile\"></im-profile-card>\r\n</ng-template>\r\n\r\n<div class=\"my-profile-wrapper\">\r\n <div nz-button nz-popover nzType=\"primary\" nzPopoverTrigger=\"click\"\r\n [nzPopoverTitle]=\"titleTemplate\" nzPopoverPlacement=\"right\"\r\n [nzPopoverContent]=\"contentTemplate\">\r\n <im-avatar [src]=\"currentUserProfile.avatar\"></im-avatar>\r\n </div>\r\n</div>\r\n", styles: [".title-container{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;align-items:center}.title-container i{cursor:pointer}.my-profile-wrapper{margin:15px}.my-profile-wrapper im-avatar{cursor:pointer}.edit-my-profile{position:absolute;top:10px;right:10px;cursor:pointer}\n"] }] }], ctorParameters: function () { return [{ type: i1.Store }, { type: i2.NzModalService }]; } }); /** * 返回年月日 * @export * @param {Date} date * @param {string} [splitor='-'] * @returns */ function getDate(date, splitor = '-') { const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); return `${year}${splitor}${addZeroPrefix(month)}${splitor}${addZeroPrefix(day)}`; } /** * 返回时分秒/时分 * @export * @param {*} date * @param {boolean} [withSecond=false] * @returns */ function getTime(date, withSecond = false) { const hour = date.getHours(); const minute = date.getMinutes(); const second = date.getSeconds(); return withSecond ? `${addZeroPrefix(hour)}:${addZeroPrefix(minute)}:${addZeroPrefix(second)}` : `${hour}:${addZeroPrefix(minute)}`; } function getFullDate(date) { return `${getDate(date)} ${getTime(date)}`; } function isToday(date) { return date.toDateString() === new Date().toDateString(); } /** * 个位数,加0前缀 * @param {*} number * @returns */ function addZeroPrefix(number) { return number < 10 ? `0${number}` : number; } class ConversationItemComponent { constructor(store, timHelperService) { this.store = store; this.timHelperService = timHelperService; this.TIM = TIM$1; } ngOnInit() { this.profileSubscription = this.store.select(currentUserProfileSelector) .subscribe(res => { this.currentUserProfile = res; }); } selectConversation() { if (this.conversation.conversationID !== this.currentConversation.conversationID) { this.timHelperService.checkoutConversation(this.conversation.conversationID); // this.timHelperService.eventBus$.next('select-item'); } } get avatarSrc() { switch (this.conversation.type) { case 'GROUP': return this.conversation.groupProfile?.avatar; case 'C2C': return this.conversation.userProfile?.avatar; default: return null; } } ; get date() { if (!this.conversation.lastMessage || !this.conversation.lastMessage.lastTime) { return ''; } const date = new Date(this.conversation.lastMessage.lastTime * 1000); if (isToday(date)) { return getTime(date); } return getDate(date); } get messageForShow() { if (this.conversation.lastMessage.isRevoked) { if (this.conversation.lastMessage.fromAccount === this.currentUserProfile?.userID) { return '你撤回了一条消息'; } if (this.conversation.type === TIM$1.TYPES.CONV_C2C) { return '对方撤回了一条消息'; } return `${this.conversation.lastMessage.fromAccount}撤回了一条消息`; } return this.conversation.lastMessage.messageForShow; } get conversationName() { if (this.conversation.type === TIM$1.TYPES.CONV_C2C) { return this.conversation.userProfile.nick || this.conversation.userProfile.userID; } if (this.conversation.type === TIM$1.TYPES.CONV_GROUP) { return this.conversation.groupProfile.name || this.conversation.groupProfile.groupID; } if (this.conversation.type === TIM$1.TYPES.CONV_SYSTEM) { return '系统通知'; } return ''; } deleteConversation(event) { // 停止冒泡,避免和点击会话的事件冲突 event.stopPropagation(); this.timHelperService.tim .deleteConversation(this.conversation.conversationID) .then(() => { this.store.dispatch(showAction({ message: `会话【${this.conversationName}】删除成功!`, msgType: MESSAGE_STATUS.success })); this.store.dispatch(resetCurrentConversationAction()); }) .catch(error => { this.store.dispatch(showAction({ message: `会话【${this.conversationName}】删除失败!, error=${error.message}`, msgType: MESSAGE_STATUS.error })); }); } ngOnDestroy() { if (this.profileSubscription) { this.profileSubscription.unsubscribe(); } } } ConversationItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: ConversationItemComponent, deps: [{ token: i1.Store }, { token: TimHelperService }], target: i0.ɵɵFactoryTarget.Component }); ConversationItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: ConversationItemComponent, selector: "app-conversation-item", inputs: { currentConversation: "currentConversation", conversation: "conversation" }, ngImport: i0, template: "<div class=\"conversation-item-container\"\r\n [ngClass]=\"{'choose': conversation.conversationID === currentConversation.conversationID }\"\r\n (click)=\"selectConversation()\">\r\n <div class=\"close-btn\">\r\n <span class=\"tim-icon-close\" title=\"\u5220\u9664\u4F1A\u8BDD\" (click)=\"deleteConversation($event)\"></span>\r\n </div>\r\n <div class=\"warp\">\r\n <im-avatar [src]=\"avatarSrc\" [type]=\"conversation.type\"></im-avatar>\r\n <div class=\"content\">\r\n <div class=\"row-1\">\r\n <div class=\"name\">\r\n <div class=\"text-ellipsis\">\r\n <span [title]=\"conversation.userProfile.nick || conversation.userProfile.userID\"\r\n *ngIf=\"conversation.type === TIM.TYPES.CONV_C2C\">\r\n {{conversation.userProfile.nick || conversation.userProfile.userID}}\r\n </span>\r\n <span [title]=\"conversation.groupProfile.name || conversation.groupProfile.groupID\"\r\n *ngIf=\"conversation.type===TIM.TYPES.CONV_GROUP\">\r\n {{conversation.groupProfile.name || conversation.groupProfile.groupID}}\r\n </span>\r\n <span *ngIf=\"conversation.type === TIM.TYPES.CONV_SYSTEM\">\u7CFB\u7EDF\u901A\u77E5\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"unread-count\">\r\n <span class=\"badge\" *ngIf=\"this.conversation.unreadCount > 0\">\r\n {{conversation.unreadCount > 99 ? '99+' : conversation.unreadCount}}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"row-2\">\r\n <div class=\"summary\">\r\n <div v-if=\"conversation.lastMessage\" class=\"text-ellipsis\">\r\n <!-- <span class=\"remind\" style=\"color:red;\">[\u6709\u4EBA\u63D0\u5230\u6211]</span> -->\r\n <span class=\"text\" [title]=\"conversation.lastMessage.messageForShow\">\r\n {{messageForShow}}\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"date\">\r\n {{date}}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".conversation-item-container{padding:15px 10px;cursor:pointer;position:relative;overflow:hidden;transition:.2s}.conversation-item-container:hover{background-color:#404953}.conversation-item-container:hover .close-btn{right:3px}.conversation-item-container .close-btn{position:absolute;right:-20px;top:3px;color:#76828c;transition:all .2s ease}.conversation-item-container .close-btn:hover{color:#f35f5f}.conversation-item-container .warp{display:flex}.conversation-item-container .warp im-avatar{padding-right:10px}.conversation-item-container .content{flex:1;height:40px;overflow:hidden}.conversation-item-container .content .row-1{display:flex;line-height:21px}.conversation-item-container .content .row-1 .name{color:#f7f7f8;flex:1;min-width:0px}.conversation-item-container .content .row-1 .unread-count{padding-left:10px;flex-shrink:0;color:#76828c;font-size:12px}.conversation-item-container .content .row-1 .unread-count .badge{vertical-align:bottom;background-color:#f35f5f;border-radius:10px;color:#fff;display:inl