Add Marionette 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 is a core element from Nextcloud, and
SidebarView is a Marionette wrapper around it. Therefore, it has to be
used along an "#app-content" element that takes into account the
"with-app-sidebar" CSS class.

However, this right sidebar extends the standard right sidebar with an
icon shown on the right border of the screen that makes possible for the
user to show it when hidden (as there is no other element in the UI
suitable for that purpose).

That icon is just a right-pointing triangle created with a CSS trick (a
zero-sized div with width borders, but all of them transparent except
for the left one). However, as the icon will be shown on different
coloured backgrounds it can not have just a single colour; it must
provide a border on its own too, which is achieved with another triangle
slightly larger underneath. The triangle border is 2px instead of just
1px used in other UI elements (like in the sidebar itself) to make it
more noticeable on a white background.

The triangle used for the icon is a large one, with a width of 24px and
a height of 48px. Using this trick has an added benefit, as its
clickable area is larger than the triangle itself (48x48px), which
improves its usability on touchable screens (and does not negatively
affect the experience on other devices).

Currently the SidebarView is empty. The content will be added in
following commits.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2017-10-12 13:55:15 +02:00
Родитель aa24728518
Коммит 0fff33484b
2 изменённых файлов: 177 добавлений и 0 удалений

Просмотреть файл

@ -565,6 +565,58 @@ video {
display: inline-block;
}
#app-sidebar-trigger {
position: fixed;
/* Although it would be desirable due to their complementary behaviour, the
* trigger can not be placed at the same position as the close button
* (top: 45px) due to the "Switch to fullscreen" icon shown during calls. */
top: 150px;
right: 0;
width: 48px;
height: 48px;
/* Higher than the z-index of the emptycontent */
z-index: 50;
cursor: pointer;
}
#app-sidebar-trigger .large-outer-left-triangle {
position: absolute;
top: 0;
right: 0;
border-width: 24px;
border-color: #ebebeb;
border-style: solid;
border-left-color: transparent;
border-top-color: transparent;
border-bottom-color: transparent;
cursor: pointer;
}
#app-sidebar-trigger .large-inner-left-triangle {
position: absolute;
top: 2px;
right: 0;
border-width: 22px;
border-color: #fff;
border-style: solid;
border-left-color: transparent;
border-top-color: transparent;
border-bottom-color: transparent;
cursor: pointer;
}
#app-sidebar .close {
position: absolute;
top: 0;
right: 0;
/* The app uses border-box sizing, so the padding is 15px like in the Files
* app plus 8px of half the size of the icon */
padding: 23px;
opacity: 0.5;
/* Higher index than the trigger to hide it when the sidebar is open */
z-index: 20;
}
#videos .videoContainer.speaking:not(.videoView) .nameIndicator,
#videos .videoContainer.videoView.speaking .nameIndicator .icon-audio-white {
animation: pulse 1s;

125
js/views/sidebarview.js Normal file
Просмотреть файл

@ -0,0 +1,125 @@
/* 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">' +
' <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.
*
* 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',
},
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.render();
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();
},
});
OCA.SpreedMe.Views.SidebarView = SidebarView;
})(OCA, Marionette, Handlebars);