ringcentral-widgets
Version:
RingCentral Integration Widget Library
250 lines (245 loc) • 8.07 kB
text/typescript
import {
RcUIModuleV2,
UIFunctions,
UIProps,
} from '@ringcentral-integration/core';
import { Module } from 'ringcentral-integration/lib/di';
import {
Deps,
ConversationsContainerProps,
ConversationsPanelProps,
} from './ConversationsUI.interface';
({
name: 'ConversationsUI',
deps: [
'Brand',
'Locale',
'Conversations',
'DateTimeFormat',
'RegionSettings',
'ExtensionFeatures',
'Call',
'ConnectivityMonitor',
'RateLimiter',
'MessageStore',
'ConnectivityManager',
'ExtensionInfo',
'RouterInteraction',
'ComposeText',
'ContactSearch',
{ dep: 'DialerUI', optional: true },
{ dep: 'ContactDetailsUI', optional: true },
{ dep: 'ContactMatcher', optional: true },
{ dep: 'ConversationLogger', optional: true },
{ dep: 'ConversationsUIOptions', optional: true },
],
})
export class ConversationsUI<T> extends RcUIModuleV2<Deps & T> {
constructor(deps: Deps & T) {
super({
deps,
});
}
getUIProps({
showTitle = false,
enableContactFallback = false,
showGroupNumberName = false,
}: ConversationsContainerProps): UIProps<ConversationsPanelProps> {
const {
brand,
locale,
conversations,
contactMatcher,
dateTimeFormat,
regionSettings,
extensionFeatures,
call,
conversationLogger,
connectivityMonitor,
rateLimiter,
messageStore,
connectivityManager,
extensionInfo,
} = this._deps;
return {
showTitle,
enableContactFallback,
showGroupNumberName,
brand: brand.fullName,
currentLocale: locale.currentLocale,
currentSiteCode: extensionInfo?.site?.code ?? '',
isMultipleSiteEnabled: extensionInfo?.isMultipleSiteEnabled ?? false,
conversations: conversations.pagingConversations,
areaCode: regionSettings.areaCode,
countryCode: regionSettings.countryCode,
disableLinks:
connectivityManager.isOfflineMode ||
connectivityManager.isVoipOnlyMode ||
rateLimiter.throttling,
disableCallButton:
connectivityManager.isOfflineMode ||
connectivityManager.isWebphoneUnavailableMode ||
connectivityManager.isWebphoneInitializing ||
rateLimiter.throttling,
disableClickToDial: !(call && call.isIdle),
outboundSmsPermission: extensionFeatures.hasOutboundSMSPermission,
internalSmsPermission: extensionFeatures.hasInternalSMSPermission,
composeTextPermission: extensionFeatures.hasComposeTextPermission,
loggingMap: conversationLogger && conversationLogger.loggingMap,
showSpinner: !(
locale.ready &&
conversations.ready &&
(!contactMatcher || contactMatcher.ready) &&
dateTimeFormat.ready &&
regionSettings.ready &&
extensionFeatures.ready &&
connectivityMonitor.ready &&
rateLimiter.ready &&
(!call || call.ready) &&
(!conversationLogger || conversationLogger.ready)
),
searchInput: conversations.searchInput,
autoLog: !!(conversationLogger && conversationLogger.autoLog),
typeFilter: conversations.typeFilter,
textUnreadCounts: messageStore.textUnreadCounts,
voiceUnreadCounts: messageStore.voiceUnreadCounts,
faxUnreadCounts: messageStore.faxUnreadCounts,
readTextPermission: extensionFeatures.hasReadTextPermission,
readVoicemailPermission: extensionFeatures.hasVoicemailPermission,
readFaxPermission: extensionFeatures.hasReadFaxPermission,
loadingNextPage: conversations.loadingOldConversations,
};
}
getUIFunctions({
showViewContact = true,
dateTimeFormatter,
dialerRoute = '/dialer',
onCreateContact,
onLogConversation,
onViewContact,
conversationDetailRoute = '/conversations/{conversationId}',
composeTextRoute = '/composeText',
previewFaxMessages,
onFaxDownload,
}: ConversationsContainerProps): UIFunctions<ConversationsPanelProps> {
const {
dateTimeFormat,
conversations,
messageStore,
conversationLogger,
contactMatcher,
call,
dialerUI,
routerInteraction,
contactDetailsUI,
composeText,
contactSearch,
extensionFeatures,
} = this._deps;
return {
dateTimeFormatter:
dateTimeFormatter ??
((...args) => dateTimeFormat.formatDateTime(...args)),
onViewContact: showViewContact
? onViewContact ||
(({ contact: { id, type } }) => {
if (contactDetailsUI) {
contactDetailsUI.showContactDetails({ id, type, direct: true });
}
})
: null,
onCreateContact: onCreateContact
? async ({ phoneNumber, name, entityType }) => {
const hasMatchNumber = await contactMatcher.hasMatchNumber({
phoneNumber,
ignoreCache: true,
});
// console.debug('confirm hasMatchNumber:', hasMatchNumber);
if (!hasMatchNumber) {
await onCreateContact({ phoneNumber, name, entityType });
await contactMatcher.forceMatchNumber({ phoneNumber });
}
}
: undefined,
onClickToDial:
dialerUI && extensionFeatures.isCallingEnabled
? (recipient) => {
if (call.isIdle) {
routerInteraction.push(dialerRoute);
// for track router
messageStore.onClickToCall({ fromType: recipient.fromType });
dialerUI.call({ recipient });
}
}
: undefined,
onClickToSms: extensionFeatures.hasComposeTextPermission
? (contact, isDummyContact = false) => {
if (routerInteraction) {
routerInteraction.push(composeTextRoute);
}
// if contact autocomplete, if no match fill the number only
if (contact.name && contact.phoneNumber && isDummyContact) {
composeText.updateTypingToNumber(contact.name);
contactSearch.search({ searchString: contact.name });
} else {
composeText.addToNumber(contact);
if (composeText.typingToNumber === contact.phoneNumber) {
composeText.cleanTypingToNumber();
}
}
// for track
messageStore.onClickToSMS();
}
: undefined,
onLogConversation:
onLogConversation ||
(conversationLogger &&
(async ({ redirect = true, ...options }) => {
await conversationLogger.logConversation({
...options,
redirect,
});
})),
onSearchInputChange(e) {
conversations.updateSearchInput(e.currentTarget.value);
},
showConversationDetail(conversationId) {
routerInteraction.push(
conversationDetailRoute.replace('{conversationId}', conversationId),
);
},
readMessage(conversationId) {
messageStore.readMessages(conversationId);
},
markMessage(conversationId) {
messageStore.unreadMessage(conversationId);
},
unmarkMessage(conversationId) {
messageStore.readMessages(conversationId);
messageStore.onUnmarkMessages();
},
goToComposeText: () => routerInteraction.push(composeTextRoute),
updateTypeFilter: (type) => conversations.updateTypeFilter(type),
deleteMessage(conversationId) {
conversations.deleteConversation(conversationId);
},
previewFaxMessages(uri, conversationId) {
if (!previewFaxMessages) {
window.open(uri);
} else {
previewFaxMessages(uri);
}
messageStore.readMessages(conversationId);
},
async loadNextPage() {
await conversations.loadNextPage();
},
onUnmount() {
if (conversations.currentPage > 2) {
conversations.resetCurrentPage();
}
},
onFaxDownload,
};
}
}