UNPKG

ringcentral-widgets

Version:
347 lines (309 loc) 8.66 kB
import { assoc, converge, flip, identity, keys, mergeWith, pick, useWith, } from 'ramda'; import { Module } from 'ringcentral-integration/lib/di'; import ensureExist from 'ringcentral-integration/lib/ensureExist'; import RcModule from 'ringcentral-integration/lib/RcModule'; import { selector } from 'ringcentral-integration/lib/selector'; import { proxify } from 'ringcentral-integration/lib/proxy/proxify'; import { Mapping } from '../../typings'; import actionTypes from './actionTypes'; import { CallLogSectionCallStatus } from './CallLogSection.interface'; import getCallLogSectionReducer from './getCallLogSectionReducer'; import getStorageReducer from './getStorageReducer'; @Module({ deps: [ 'Storage', { dep: 'CallLogSectionOptions', optional: true, }, ], }) export default class CallLogSection extends RcModule { _notSyncOpenState: boolean; _storageKey: string; _storageReducer: any; constructor({ storage, notSyncOpenState = false, ...options }) { super({ storage, actionTypes, ...options, }); this._storage = storage; this._notSyncOpenState = notSyncOpenState; this._storageReducer = getStorageReducer( this.actionTypes, notSyncOpenState, ); this._storageKey = 'callLogSection'; this._storage.registerReducer({ key: this._storageKey, reducer: this._storageReducer, }); this._reducer = getCallLogSectionReducer( this.actionTypes, notSyncOpenState, ); } async _onStateChange() { if (this._shouldInit()) { this.store.dispatch({ type: this.actionTypes.init, }); if (typeof this._onInit === 'function') { await this._onInit(); } this.store.dispatch({ type: this.actionTypes.initSuccess, }); } else if (this._shouldReset()) { if (typeof this._onReset === 'function') { await this._onReset(); } this.store.dispatch({ type: this.actionTypes.resetSuccess, }); } } _shouldInit() { return this._storage.ready && this._readyCheckFunction() && this.pending; } _shouldReset() { return (!this._storage.ready || !this._readyCheckFunction()) && this.ready; } _handleSuccess(identify, ...args) { this.store.dispatch({ type: this.actionTypes.saveSuccess, identify, }); if (typeof this._onSuccess === 'function') this._onSuccess(identify, ...args); } _handleError(identify, ...args) { this.store.dispatch({ type: this.actionTypes.saveError, identify, }); if (typeof this._onError === 'function') this._onError(identify, ...args); } @proxify async _showLogSection(identify: string) { if (!this.show || identify !== this.currentIdentify) { this.store.dispatch({ type: this.actionTypes.showLogSection, identify, }); } } @proxify async _showLogNotification(identify: string) { if ( !this.showNotification || identify !== this.currentNotificationIdentify ) { this.store.dispatch({ type: this.actionTypes.showLogNotification, identify, }); } } addLogHandler({ logFunction, readyCheckFunction, onUpdate, onSuccess, onError, }) { this._logFunction = ensureExist.call(this, logFunction, 'logFunction'); this._readyCheckFunction = ensureExist.call( this, readyCheckFunction, 'readyCheckFunction', ); this._onUpdate = onUpdate; this._onSuccess = onSuccess; this._onError = onError; } @proxify async updateCallLog(identify, ...args) { this.store.dispatch({ type: this.actionTypes.update, identify, }); await this._onUpdate(identify, ...args); } @proxify async saveCallLog(identify, ...args) { if ( identify && (!this.callsMapping[identify] || !this.callsMapping[identify].isSaving) ) { this.store.dispatch({ type: this.actionTypes.saving, identify, }); try { const result = await this._logFunction(identify, ...args); if (result) { this._handleSuccess(identify, ...args); } else { this._handleError(identify, ...args); } return result; } catch (e) { this._handleError(identify, ...args); console.warn(e); } } return null; } @proxify async handleLogSection(identify: string) { // prevent `isSameCall` for repeat run more time. const isSameCall = this.currentIdentify === identify; if (!this.show) { // Preferentially show call log section. await this._showLogSection(identify); } else if (!this.notificationIsExpand && !isSameCall) { // Check it to show log notification when the call log notification isn't expanded. await this._showLogNotification(identify); } } @proxify async closeLogSection() { if (this.show) { this.store.dispatch({ type: this.actionTypes.closeLogSection, }); } } @proxify async discardAndHandleNotification() { const currentNotificationIdentify = this.currentNotificationIdentify; await this.closeLogNotification(); await this.closeLogSection(); await this._showLogSection(currentNotificationIdentify); } @proxify async saveAndHandleNotification() { const currentNotificationIdentify = this.currentNotificationIdentify; const currentIdentify = this.currentIdentify; await this.saveCallLog(currentIdentify); await this.closeLogNotification(); await this.closeLogSection(); await this._showLogSection(currentNotificationIdentify); } @proxify async closeLogNotification() { if (this.showNotification) { this.store.dispatch({ type: this.actionTypes.closeLogNotification, }); } } // shrink the popover menu appear when click log button at call notificaiton @proxify async shrinkNotification() { if (this.notificationIsExpand) { this.store.dispatch({ type: this.actionTypes.shrinkNotification, }); } } @proxify async expandLogNotification() { if (!this.show) { await this._showLogSection(this.currentNotificationIdentify); await this.closeLogNotification(); } else if (!this.notificationIsExpand) { this.store.dispatch({ type: this.actionTypes.expandNotification, }); } } @selector calls = [ () => this.callsList, () => this.callsMapping, (list, mapping) => { const a = list.map((identify) => mapping[identify]); console.log('calls', a); return a; }, ]; /** * Merge isSaving property from reducer to callsMapping */ @selector callsMapping: Mapping<CallLogSectionCallStatus> = [ () => this._callsMapping, () => this._callsSavingStatus, converge(mergeWith(flip(assoc('isSaving'))), [ identity, // eslint-disable-next-line react-hooks/rules-of-hooks useWith(pick, [keys, identity]), ]), ] as any; get callsList() { return this._storage.getItem(this._storageKey).callsList; } /** * Private calls mapping relationship without isSaving property */ get _callsMapping() { return this._storage.getItem(this._storageKey).callsMapping; } get _callsSavingStatus() { return this.state.callsSavingStatus; } get _storageCurrentIdentify() { return this._storage.getItem(this._storageKey).currentIdentify; } get _stateCurrentIdentify() { return this.state.currentIdentify; } get currentIdentify() { return this._notSyncOpenState ? this._stateCurrentIdentify : this._storageCurrentIdentify; } get show() { return !!this.currentIdentify; } get _storageCurrentNotificationIdentify() { return this._storage.getItem(this._storageKey).currentNotificationIdentify; } get _stateCurrentNotificationIdentify() { return this.state.currentNotificationIdentify; } get currentNotificationIdentify() { return this._notSyncOpenState ? this._stateCurrentNotificationIdentify : this._storageCurrentNotificationIdentify; } get showNotification() { return !!this.currentNotificationIdentify; } get _storageNotificationIsExpand() { return this._storage.getItem(this._storageKey).notificationIsExpand; } get _stateNotificationIsExpand() { return this.state.notificationIsExpand; } get notificationIsExpand() { return this._notSyncOpenState ? this._stateNotificationIsExpand : this._storageNotificationIsExpand; } get status() { return this.state.status; } }