3 var env = require('gitter-web-env');
4 var nconf = env.config;
5 var Promise = require('bluebird');
6 var _ = require('lodash');
7 const asyncHandler = require('express-async-handler');
9 const mongoUtils = require('gitter-web-persistence-utils/lib/mongo-utils');
10 var contextGenerator = require('../../web/context-generator');
11 var restful = require('../../services/restful');
12 var burstCalculator = require('../../utils/burst-calculator');
13 const userSort = require('gitter-web-shared/sorting/user-sort');
14 var getSubResources = require('./sub-resources');
15 var fixMongoIdQueryParam = require('../../web/fix-mongo-id-query-param');
16 var fonts = require('../../web/fonts');
17 var generateRightToolbarSnapshot = require('../snapshots/right-toolbar-snapshot');
18 var generateUserThemeSnapshot = require('../snapshots/user-theme-snapshot');
19 var getHeaderViewOptions = require('gitter-web-shared/templates/get-header-view-options');
20 const mixinHbsDataForVueLeftMenu = require('./vue/mixin-vue-left-menu-data');
21 const getChatSnapshotOptions = require('./chat/chat-snapshot-options');
22 const socialMetadataGenerator = require('../social-metadata-generator');
24 const ROSTER_SIZE = 25;
26 const getPermalinkMessageId = request => fixMongoIdQueryParam(request.query.at);
28 function getSocialMetaDataForRoom(room, permalinkChatSerialized) {
30 if (room && permalinkChatSerialized) {
31 socialMetadata = socialMetadataGenerator.getMetadataForChatPermalink({
33 chat: permalinkChatSerialized
36 socialMetadata = socialMetadataGenerator.getMetadata({ room });
39 return socialMetadata;
42 // eslint-disable-next-line max-statements, complexity
43 async function renderChat(req, res, next, options) {
44 const { uriContext, embedded } = options;
46 var troupe = uriContext.troupe;
48 var userId = user && user.id;
50 const userSerializerOptions = {
54 const chatSnapshotOptions = await getChatSnapshotOptions(userId, troupe.id, req);
56 const permalinkChatId = getPermalinkMessageId(req);
65 ] = await Promise.all([
66 contextGenerator.generateTroupeContext(req, {
67 snapshots: { chat: chatSnapshotOptions },
69 // Are we using /~embed ?
72 restful.serializeChatsForTroupe(troupe.id, userId, chatSnapshotOptions),
73 options.fetchEvents === false ? null : restful.serializeEventsForTroupe(troupe.id, userId),
74 options.fetchUsers === false
76 : restful.serializeUsersForTroupe(troupe.id, userId, userSerializerOptions),
77 generateRightToolbarSnapshot(req),
78 generateUserThemeSnapshot(req)
81 var initialChat = _.find(chats, function(chat) {
84 var initialBottom = !initialChat;
86 const permalinkChatSerialized = _.find(chats, function(chat) {
87 return mongoUtils.objectIDsEqual(chat.id, permalinkChatId);
90 var classNames = options.classNames || [];
91 var isStaff = req.user && req.user.staff;
93 troupeContext.snapshots = {
94 rightToolbar: rightToolbarSnapshot
97 if (!user) classNames.push('logged-out');
101 if (troupeContext && troupeContext.isNativeDesktopApp) {
102 integrationsUrl = nconf.get('web:basepath') + '/' + troupeContext.troupe.uri + '#integrations';
104 integrationsUrl = '#integrations';
107 const script = options.script;
108 var cssFileName = options.stylesheet
109 ? 'styles/' + options.stylesheet + '.css'
110 : 'styles/' + script + '.css'; // css filename matches bootscript
112 var chatsWithBurst = burstCalculator(chats);
113 if (options.filterChats) {
114 chatsWithBurst = options.filterChats(chatsWithBurst);
117 /* This is less than ideal way of checking if the user is the admin */
119 troupeContext.troupe &&
120 troupeContext.troupe.permissions &&
121 troupeContext.troupe.permissions.admin;
123 var isRightToolbarPinned = rightToolbarSnapshot && rightToolbarSnapshot.isPinned;
124 if (isRightToolbarPinned === undefined) {
125 isRightToolbarPinned = true;
128 const socialMetadata = getSocialMetaDataForRoom(troupeContext.troupe, permalinkChatSerialized);
130 var renderOptions = await mixinHbsDataForVueLeftMenu(
134 embedded: options.embedded || false,
135 hasDarkTheme: userThemeSnapshot.theme === 'gitter-dark',
136 hasCachedFonts: fonts.hasCachedFonts(req.cookies),
137 fonts: fonts.getFonts(),
139 isRepo: troupe.sd.type === 'GH_REPO', // Used by chat_toolbar patial
140 bootScriptName: script,
141 cssFileName: cssFileName,
142 troupeName: uriContext.uri,
143 oneToOne: troupe.oneToOne, // Used by the old left menu
145 troupeContext: troupeContext,
146 initialBottom: initialBottom,
147 chats: chatsWithBurst,
148 classNames: classNames.join(' '),
149 subresources: getSubResources(script),
150 activityEvents: activityEvents,
151 users: users && users.sort(userSort),
152 userCount: troupe.userCount,
153 hasHiddenMembers: troupe.userCount > 25,
154 integrationsUrl: integrationsUrl,
155 isMobile: options.isMobile,
156 roomMember: uriContext.roomMember,
157 isRightToolbarPinned: isRightToolbarPinned,
158 matrixRoomLink: troupeContext.troupe.matrixRoomLink,
159 elementUrl: nconf.get('element:appUrl'),
161 //Feature Switch Left Menu
162 troupeTopic: troupeContext.troupe.topic,
163 premium: troupeContext.troupe.premium,
164 troupeFavourite: troupeContext.troupe.favourite,
165 headerView: getHeaderViewOptions(troupeContext.troupe),
166 canChangeGroupAvatar: !!troupe.groupId && (isStaff || isAdmin),
168 isNativeDesktopApp: troupeContext.isNativeDesktopApp
174 res.render(options.template, renderOptions);
177 module.exports = asyncHandler(renderChat);