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
@@ -8,6 +8,7 @@
verify?: string,
calendar?: boolean,
chat?: boolean,
+ apps?: boolean,
thread?: string,
...
};
@@ -18,6 +19,7 @@
const verifyRegex = new RegExp('(/|^)verify/([a-f0-9]+)(/|$)', 'i');
const calendarRegex = new RegExp('(/|^)calendar(/|$)', 'i');
const chatRegex = new RegExp('(/|^)chat(/|$)', 'i');
+const appsRegex = new RegExp('(/|^)apps(/|$)', 'i');
function infoFromURL(url: string): URLInfo {
const yearMatches = yearRegex.exec(url);
@@ -26,6 +28,7 @@
const verifyMatches = verifyRegex.exec(url);
const calendarTest = calendarRegex.test(url);
const chatTest = chatRegex.test(url);
+ const appsTest = appsRegex.test(url);
const returnObj = {};
if (yearMatches) {
returnObj.year = parseInt(yearMatches[2], 10);
@@ -47,6 +50,8 @@
returnObj.calendar = true;
} else if (chatTest) {
returnObj.chat = true;
+ } else if (appsTest) {
+ returnObj.apps = true;
}
return returnObj;
}
diff --git a/web/app.react.js b/web/app.react.js
--- a/web/app.react.js
+++ b/web/app.react.js
@@ -31,6 +31,7 @@
import type { Dispatch } from 'lib/types/redux-types';
import { registerConfig } from 'lib/utils/config';
+import AppsDirectory from './apps/apps-directory.react';
import Calendar from './calendar/calendar.react';
import Chat from './chat/chat.react';
import InputStateContainer from './input/input-state-container.react';
@@ -149,6 +150,8 @@
mainContent = ;
} else if (this.props.navInfo.tab === 'chat') {
mainContent = ;
+ } else if (this.props.navInfo.tab === 'apps') {
+ mainContent = ;
}
return (
diff --git a/web/apps/apps-directory.react.js b/web/apps/apps-directory.react.js
new file mode 100644
--- /dev/null
+++ b/web/apps/apps-directory.react.js
@@ -0,0 +1,9 @@
+// @flow
+
+import * as React from 'react';
+
+function AppsDirectory(): React.Node {
+ return
Apps directory
;
+}
+
+export default AppsDirectory;
diff --git a/web/sidebar/app-switcher.react.js b/web/sidebar/app-switcher.react.js
--- a/web/sidebar/app-switcher.react.js
+++ b/web/sidebar/app-switcher.react.js
@@ -71,6 +71,19 @@
],
);
+ const onClickApps = React.useCallback(
+ (event: SyntheticEvent) => {
+ event.preventDefault();
+ dispatch({
+ type: updateNavInfoActionType,
+ payload: {
+ tab: 'apps',
+ },
+ });
+ },
+ [dispatch],
+ );
+
invariant(viewerID, 'should be set');
let chatBadge = null;
if (boundUnreadCount > 0) {
@@ -83,6 +96,9 @@
const chatNavClasses = classNames({
[css['current-tab']]: navInfo.tab === 'chat',
});
+ const appsNavClasses = classNames({
+ [css['current-tab']]: navInfo.tab === 'apps',
+ });
return (
);
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
@@ -5,7 +5,7 @@
export type NavInfo = {
...$Exact,
- +tab: 'calendar' | 'chat',
+ +tab: 'calendar' | 'chat' | 'apps',
+activeChatThreadID: ?string,
+pendingThread?: ThreadInfo,
};
diff --git a/web/url-utils.js b/web/url-utils.js
--- a/web/url-utils.js
+++ b/web/url-utils.js
@@ -97,8 +97,15 @@
activeChatThreadID = navInfo.activeChatThreadID;
}
+ let tab = 'chat';
+ if (urlInfo.calendar) {
+ tab = 'calendar';
+ } else if (urlInfo.apps) {
+ tab = 'apps';
+ }
+
return {
- tab: urlInfo.chat ? 'chat' : 'calendar',
+ tab,
startDate: startDateForYearAndMonth(year, month),
endDate: endDateForYearAndMonth(year, month),
activeChatThreadID,