summaryrefslogtreecommitdiffstats
path: root/js/views/sidebarview.js
blob: 614230ec80b379cf1172dc841287aff45bc9aa65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/* global Marionette, Handlebars */

/**
 *
 * @copyright Copyright (c) 2017, Daniel Calviño Sánchez (danxuliu@gmail.com)
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

(function(OCA, Marionette, Handlebars) {
	'use strict';

	OCA.SpreedMe = OCA.SpreedMe || {};
	OCA.SpreedMe.Views = OCA.SpreedMe.Views || {};

	var TEMPLATE =
		'<div id="app-sidebar-trigger">' +
		'	<div class="large-outer-left-triangle"/>' +
		'	<div class="large-inner-left-triangle"/>' +
		'</div>' +
		'<div id="app-sidebar" class="detailsView scroll-container">' +
		'	<div class="detailCallInfoContainer">' +
		'	</div>' +
		'	<div class="tabs">' +
		'	</div>' +
		'	<a class="close icon-close" href="#"><span class="hidden-visually">{{closeLabel}}</span></a>' +
		'</div>';

	/**
	 * View for the right sidebar.
	 *
	 * The right sidebar is an area that can be shown or hidden from the right
	 * border of the document. It contains a view intended to provide details of
	 * the current call at the top and a TabView to which different sections can
	 * be added as needed. The call details view can be set through
	 * "setCallInfoView()" while new tabs can be added through "addTab()".
	 *
	 * The SidebarView can be shown or hidden programatically using "show()" and
	 * "hide()". It will delegate on "OC.Apps.showAppSidebar()" and
	 * "OC.Apps.hideAppSidebar()", so it must be used along an "#app-content"
	 * that takes into account the "with-app-sidebar" CSS class.
	 *
	 * In order for the user to be able to show the sidebar when it is hidden,
	 * the SidebarView shows a small icon ("#app-sidebar-trigger") on the right
	 * border of the document that shows the sidebar when clicked. When the
	 * sidebar is shown the icon is hidden.
	 *
	 * By default the sidebar is disabled, that is, it is hidden and can not be
	 * shown, neither by the user nor programatically. Calling "enable()" will
	 * make possible for the sidebar to be shown, and calling "disable()" will
	 * prevent it again (also hidden it if it was shown).
	 */
	var SidebarView = Marionette.View.extend({

		id: 'app-sidebar-wrapper',

		ui: {
			trigger: '#app-sidebar-trigger',
			sidebar: '#app-sidebar',
		},

		regions: {
			callInfoView: '@ui.sidebar .detailCallInfoContainer',
			tabView: '@ui.sidebar .tabs'
		},

		events: {
			'click @ui.trigger': 'open',
			'click @ui.sidebar a.close': 'close',
		},

		template: Handlebars.compile(TEMPLATE),

		templateContext: {
			closeLabel: t('spreed', 'Close')
		},

		initialize: function() {
			this._enabled = false;

			this._callInfoView = null;

			this._tabView = new OCA.SpreedMe.Views.TabView();

			// In Marionette 3.0 the view is not rendered automatically if
			// needed when showing a child view, so it must be rendered
			// explicitly to ensure that the DOM element in which the child view
			// will be appended exists.
			this.render();
			this.showChildView('tabView', this._tabView, { replaceElement: true } );

			this.getUI('trigger').hide();
			this.getUI('sidebar').hide();
		},

		enable: function() {
			this._enabled = true;

			this.getUI('trigger').show('slide', { direction: 'right' }, 400);
		},

		disable: function() {
			if (this.getUI('sidebar').css('display') === 'none') {
				this.getUI('trigger').hide('slide', { direction: 'right' }, 200);
			} else {
				// FIXME if the sidebar is being shown or hidden and thus the
				// trigger is only partially visible this would hide it
				// abruptly... But that should not usually happen.
				this.getUI('trigger').hide();
				this.close();
			}

			this._enabled = false;
		},

		open: function() {
			if (!this._enabled) {
				return;
			}

			OC.Apps.showAppSidebar();
		},

		close: function() {
			OC.Apps.hideAppSidebar();
		},

		/**
		 * Sets a new call info view.
		 *
		 * Once set, the Sidebar takes ownership of the view, and it will
		 * destroy it if a new one is set.
		 *
		 * @param Marionette.View callInfoView the view to set.
		 */
		setCallInfoView: function(callInfoView) {
			this._callInfoView = callInfoView;

			this.showChildView('callInfoView', this._callInfoView);
		},

		/**
		 * Adds a new tab.
		 *
		 * The tabHeaderOptions must provide a 'label' string which will be
		 * rendered as the tab header. Optionally, it can provide a 'priority'
		 * integer to set the order of the tab header with respect to the other
		 * tab headers (tabs with higher priorities appear before tabs with
		 * lower priorities; tabs with the same priority are sorted based on
		 * their insertion order); if it is not explicitly set the value 0 is
		 * used. If needed, the tabHeaderOptions can provide other values that
		 * will override the default TabHeaderView properties (for example, it
		 * can provide an 'onRender' function to extend the default rendering of
		 * the header).
		 *
		 * The Sidebar takes ownership of the given content view, and it will
		 * destroy it when the Sidebar is destroyed.
		 *
		 * @param string tabId the ID of the tab.
		 * @param Object tabHeaderOptions the options for the constructor of the
		 *        TabHeaderView that will be added as the header of the tab.
		 * @param Marionette.View tabContentView the View to be shown when the
		 *        tab is selected.
		 */
		addTab: function(tabId, tabHeaderOptions, tabContentView) {
			this._tabView.addTab(tabId, tabHeaderOptions, tabContentView);
		},

	});

	OCA.SpreedMe.Views.SidebarView = SidebarView;

})(OCA, Marionette, Handlebars);