3 var Marionette = require('backbone.marionette');
4 var Backbone = require('backbone');
5 var _ = require('lodash');
6 var log = require('../../utils/log');
7 var appEvents = require('../../utils/appevents');
8 const clientEnv = require('gitter-client-env');
9 var template = require('./profile-menu-view.hbs');
10 var itemTemplate = require('./profile-menu-item-view.hbs');
11 var toggleClass = require('../../utils/toggle-class');
12 var logout = require('../../utils/logout');
13 var isNative = require('../../utils/is-native');
14 var context = require('gitter-web-client-context');
15 var toggleDarkTheme = require('../../utils/toggle-dark-theme');
16 var autoModelSave = require('../../utils/auto-model-save');
17 var showDesktopNotification = require('../../utils/show-desktop-notification');
18 var apiClient = require('../../components/api-client');
20 require('@gitterhq/styleguide/css/components/dropdowns.css');
22 function getProfileCollection() {
23 var result = new Backbone.Collection([{ name: 'Home', stub: '/home' }]);
25 var isWebApp = !isNative();
27 var user = context.user();
29 // This is more fragile than i'd like it to be
30 function showHideRepoAccess() {
31 var scopes = user.get('scopes');
32 var existing = result.find(function(f) {
33 return f.get('upgradeItem');
36 if (!user.id || !scopes || scopes.private_repo) {
38 if (!existing) return;
39 result.remove(existing);
43 var appsItem = result.find(function(f) {
44 return f.get('stub') === '/apps';
49 name: 'Allow Private Repo Access',
50 stub: '/login/upgrade?scopes=repo',
54 at: result.indexOf(appsItem) + 1
61 user.on('change:id', showHideRepoAccess);
62 user.on('change:scopes', showHideRepoAccess);
64 var currentTheme = hasDarkTheme() ? 'gitter-dark' : '';
66 name: 'Toggle Dark Theme',
71 var newTheme = currentTheme === 'gitter-dark' ? '' : 'gitter-dark';
73 toggleDarkTheme(!!newTheme.length);
75 apiClient.user.put('/settings/userTheme', { theme: newTheme }).catch(err => {
76 showDesktopNotification({
77 title: 'Problem persisting /settings/userTheme',
78 text: '(see devtools console for details)'
80 log.error('Problem persisting /settings/userTheme', { exception: err });
83 currentTheme = newTheme;
88 name: 'Terms of Service',
89 stub: 'https://element.io/terms-of-service',
94 name: 'Contribute to Gitter',
95 stub: 'https://gitlab.com/gitterHQ/webapp',
100 name: 'Help (Documentation)',
101 stub: 'https://gitlab.com/gitterHQ/webapp/tree/develop/docs#documentation',
107 stub: 'https://gitlab.com/gitterHQ/webapp/blob/develop/CHANGELOG.md',
111 if (clientEnv.exportEnabled) {
113 name: 'Export user data',
116 appEvents.trigger('route', 'export-user-data');
122 name: 'Delete Account',
125 appEvents.trigger('route', 'delete-account');
143 function hasDarkTheme() {
144 var r = document.getElementById('gitter-dark');
148 var ProfileMenuModel = Backbone.Model.extend({
149 initialize: function() {
150 autoModelSave(this, ['theme'], this.autoPersist);
154 var ItemView = Marionette.ItemView.extend({
156 className: 'dropdown__item--positive profile-menu__item',
157 template: itemTemplate,
159 'click a': 'onItemClicked'
162 onItemClicked: function(e) {
163 const cb = this.model.get('onClick');
170 module.exports = Marionette.CompositeView.extend({
173 childViewContainer: '#profile-menu-items',
175 constructor: function() {
176 this.collection = getProfileCollection();
178 this.model = new ProfileMenuModel();
181 Marionette.CollectionView.prototype.constructor.apply(this, arguments);
185 menu: '#profile-menu-items',
186 menuBackdrop: '#profile-menu-items-backdrop'
190 'click #profile-menu-avatar': 'onAvatarClicked',
191 'mouseleave @ui.menu': 'onMouseLeave',
192 'click @ui.menuBackdrop': 'onBackdropClicked'
196 'change:active': 'onActiveStateChange'
199 serializeData: function() {
200 var data = this.model.toJSON();
201 var user = context.user();
202 return _.extend({}, data, {
203 avatarUrl: user.get('avatarUrl'),
204 username: user.get('username')
209 this.model.set('active', false);
212 onBackdropClicked() {
213 this.model.set('active', false);
216 onAvatarClicked: function(e) {
218 this.model.set({ active: true });
221 onActiveStateChange: function() {
222 var state = this.model.get('active');
223 toggleClass(this.ui.menu[0], 'hidden', !state);
224 toggleClass(this.ui.menuBackdrop[0], 'hidden', !state);