3 const _ = require('lodash');
4 const urlJoin = require('url-join');
5 const asyncHandler = require('express-async-handler');
7 const clientEnv = require('gitter-client-env');
8 const contextGenerator = require('../../web/context-generator');
9 const mixinHbsDataForVueLeftMenu = require('./vue/mixin-vue-left-menu-data');
10 const exploreService = require('../../services/explore-service');
11 const suggestionsService = require('../../services/suggestions-service');
12 const exploreTagUtils = require('../../utils/explore-tag-utils');
13 const generateExploreSnapshot = require('../snapshots/explore-snapshot');
14 const generateUserThemeSnapshot = require('../snapshots/user-theme-snapshot');
15 const fonts = require('../../web/fonts');
16 const isMobile = require('../../web/is-phone');
18 function getExploreBaseUrl(req) {
19 return urlJoin(req.baseUrl, req.path).replace(/\/(|tags.*)$/, '');
22 function processTagInput(req) {
23 let input = req.params.tags;
25 const urlTagStringMatches = req.path.match(/\/tags\/(.*)/);
26 input = urlTagStringMatches && urlTagStringMatches[1];
29 input = input || exploreTagUtils.tagConstants.SUGGESTED_TAG_LABEL.toLowerCase();
30 const selectedTagsInput = input
32 .filter(function(inputItem) {
33 return inputItem.trim().length > 0;
36 return tag.toLowerCase();
39 return selectedTagsInput;
42 const FAUX_TAG_MAP = {};
43 FAUX_TAG_MAP[exploreTagUtils.tagConstants.SUGGESTED_TAG_LABEL] = [
44 exploreTagUtils.tagConstants.SUGGESTED_BACKEND_TAG
46 _.extend(FAUX_TAG_MAP, {
48 Mobile: ['curated:ios', 'curated:android', 'objective-c'],
54 Frameworks: ['frameworks'],
55 JavaScript: ['javascript'],
59 'Material Design': [],
65 Node: ['node', 'nodejs'],
74 async function renderExplorePage(req, res) {
75 const troupeContext = await contextGenerator.generateBasicContext(req);
76 const user = troupeContext.user;
77 const isLoggedIn = !!user;
79 // Copy so we can modify later on
80 const fauxTagMap = _.extend({}, FAUX_TAG_MAP);
82 const selectedTagsInput = processTagInput(req)
83 // We only take one selected tag
86 // We only generate the tag map here to grab the list of selected tags so
87 // we can populate our rooms from the explore service
88 const tagMap = exploreTagUtils.generateTagMap(fauxTagMap);
89 const selectedTagMap = exploreTagUtils.getSelectedEntriesInTagMap(tagMap, selectedTagsInput);
91 let hasSuggestedTag = false;
93 // Mush into an array of selected tags
94 const selectedBackendTags = Object.keys(selectedTagMap).reduce(function(prev, key) {
95 // Check for the selected tag for easy reference later
96 selectedTagMap[key].tags.forEach(function(tag) {
97 if (tag === exploreTagUtils.tagConstants.SUGGESTED_BACKEND_TAG) {
98 hasSuggestedTag = true;
102 return prev.concat(selectedTagMap[key].tags);
106 if (hasSuggestedTag && isLoggedIn) {
107 const suggestedRooms = await suggestionsService.findSuggestionsForUserId(user.id);
109 if (suggestedRooms && suggestedRooms.length) {
110 userSuggestions = suggestedRooms.map(function(room) {
111 room.tags = room.tags || [];
112 room.tags.push(exploreTagUtils.tagConstants.SUGGESTED_BACKEND_TAG);
119 if (userSuggestions && userSuggestions.length) {
120 rooms = userSuggestions;
122 rooms = await exploreService.fetchByTags(selectedBackendTags);
125 const snapshots = await generateExploreSnapshot({
126 isLoggedIn: isLoggedIn,
127 fauxTagMap: fauxTagMap,
128 selectedTags: selectedTagsInput,
132 //Not 100% sure this is the best thing to do here
133 //but I dont really want to refactor this whole thing
134 const userThemeSnapshot = await generateUserThemeSnapshot(req);
135 // Anyone know why we're putting this on the
136 // context? Probably not.
137 troupeContext.snapshots = snapshots;
141 await mixinHbsDataForVueLeftMenu(
143 _.extend({}, snapshots, {
144 bootScriptName: 'explore',
145 cssFileName: 'styles/explore.css',
146 hasDarkTheme: userThemeSnapshot.theme === 'gitter-dark',
147 isMobile: isMobile(req),
148 elementUrl: clientEnv.elementUrl,
149 exploreBaseUrl: getExploreBaseUrl(req),
150 troupeContext: troupeContext,
151 isLoggedIn: isLoggedIn,
152 createRoomUrl: urlJoin(clientEnv.basePath, '#createroom'),
153 fonts: fonts.getFonts(),
154 hasCachedFonts: fonts.hasCachedFonts(req.cookies)
161 renderExplorePage: asyncHandler(renderExplorePage)