diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js --- a/lib/utils/url-utils.js +++ b/lib/utils/url-utils.js @@ -13,6 +13,8 @@ +apps?: boolean, +thread?: string, +settings?: 'account' | 'danger-zone', + +threadCreation?: boolean, + +selectedUserList?: $ReadOnlyArray, ... }; @@ -31,6 +33,10 @@ `(/|^)thread/(${locallyUniqueThreadIDRegex})(/|$)`, 'i', ); +const threadCreationRegex = new RegExp( + '(/|^)thread/new(/([0-9+]*))?(/|$)', + 'i', +); function infoFromURL(url: string): URLInfo { const yearMatches = yearRegex.exec(url); @@ -43,6 +49,7 @@ const accountSettingsTest = accountSettingsRegex.test(url); const dangerZoneTest = dangerZoneRegex.test(url); const threadPendingMatches = threadPendingRegex.exec(url); + const threadCreateMatches = threadCreationRegex.exec(url); const returnObj = {}; if (yearMatches) { @@ -61,6 +68,10 @@ if (threadPendingMatches) { returnObj.thread = threadPendingMatches[2]; } + if (threadCreateMatches) { + returnObj.threadCreation = true; + returnObj.selectedUserList = threadCreateMatches[3]?.split('+') ?? []; + } if (verifyMatches) { returnObj.verify = verifyMatches[2]; } diff --git a/web/types/nav-types.js b/web/types/nav-types.js --- a/web/types/nav-types.js +++ b/web/types/nav-types.js @@ -7,12 +7,16 @@ export type NavigationSettingsSection = 'account' | 'danger-zone'; +export type NavigationChatMode = 'view' | 'create'; + export type NavInfo = { ...$Exact, +tab: NavigationTab, +activeChatThreadID: ?string, +pendingThread?: ThreadInfo, +settingsSection?: NavigationSettingsSection, + +selectedUserList?: $ReadOnlyArray, + +chatMode?: NavigationChatMode, }; export const updateNavInfoActionType = 'UPDATE_NAV_INFO'; diff --git a/web/url-utils.js b/web/url-utils.js --- a/web/url-utils.js +++ b/web/url-utils.js @@ -54,9 +54,15 @@ newURL += `month/${month}/`; } } else if (navInfo.tab === 'chat') { - const activeChatThreadID = navInfo.activeChatThreadID; - if (activeChatThreadID) { - newURL += `thread/${activeChatThreadID}/`; + if (navInfo.chatMode === 'create') { + const users = navInfo.selectedUserList?.join('+') ?? ''; + const trailingSlash = users.length ? '/' : ''; + newURL += `thread/new/${users}${trailingSlash}`; + } else { + const activeChatThreadID = navInfo.activeChatThreadID; + if (activeChatThreadID) { + newURL += `thread/${activeChatThreadID}/`; + } } } else if (navInfo.tab === 'settings' && navInfo.settingsSection) { newURL += `${navInfo.settingsSection}/`; @@ -108,21 +114,28 @@ tab = 'settings'; } - const newNavInfo = { + let chatMode = 'view'; + if (urlInfo.threadCreation) { + chatMode = 'create'; + } + + const newNavInfo: NavInfo = { tab, startDate: startDateForYearAndMonth(year, month), endDate: endDateForYearAndMonth(year, month), activeChatThreadID, + chatMode, }; - if (!urlInfo.settings) { - return newNavInfo; + if (urlInfo.selectedUserList) { + newNavInfo.selectedUserList = urlInfo.selectedUserList; } - return { - ...newNavInfo, - settingsSection: urlInfo.settings, - }; + if (urlInfo.settings) { + newNavInfo.settingsSection = urlInfo.settings; + } + + return newNavInfo; } export { canonicalURLFromReduxState, navInfoFromURL };