Infobox to Sidebar (rewrite)

- Sidebar now visible along content
- Interact with the content while the sidebar stays open
- Fixed "ctrl+a also selects the "about" tab #230"
- Sidebar redesign
- Own module for the sidebar
This commit is contained in:
Tobias Reich 2015-03-15 01:48:11 +01:00
parent 56443a16c2
commit 2b39f64c34
15 changed files with 197 additions and 148 deletions

BIN
dist/main.css vendored

Binary file not shown.

BIN
dist/main.js vendored

Binary file not shown.

BIN
dist/view.js vendored

Binary file not shown.

View File

@ -59,7 +59,7 @@
<a class="button button--right" id="button_trash_album" title="Delete Album">
<svg viewBox="0 0 8 8" class="iconic"><use xlink:href="src/images/iconic.svg#trash"></use></svg>
</a>
<a class="button button--right" id="button_info_album" title="About Album">
<a class="button button--right button--info" id="button_info_album" title="About Album">
<svg viewBox="0 0 8 8" class="iconic"><use xlink:href="src/images/iconic.svg#info"></use></svg>
</a>
<a class="button button--right" id="button_archive" title="Download Album">
@ -80,7 +80,7 @@
<a class="button button--right" id="button_trash" title="Delete">
<svg viewBox="0 0 8 8" class="iconic"><use xlink:href="src/images/iconic.svg#trash"></use></svg>
</a>
<a class="button button--right" id="button_info" title="About Photo">
<a class="button button--right button--info" id="button_info" title="About Photo">
<svg viewBox="0 0 8 8" class="iconic"><use xlink:href="src/images/iconic.svg#info"></use></svg>
</a>
<a class="button button--right" id="button_move" title="Move">
@ -103,13 +103,10 @@
<!-- ImageView -->
<div id="imageview"></div>
<!-- Infobox -->
<div id="infobox">
<!-- Sidebar -->
<div id="sidebar">
<div class='header'>
<h1>About</h1>
<a class='close' title='Close About'>
<svg viewBox="0 0 8 8" class="iconic"><use xlink:href="src/images/iconic.svg#circle-x"></use></svg>
</a>
</div>
<div class='wrapper'>
</div>

View File

@ -271,7 +271,7 @@ build.tags = function(tags, forView = false) {
}
build.infoboxPhoto = function(data, forView = false) {
build.sidebarPhoto = function(data, forView = false) {
var html = '',
visible = '',
@ -388,14 +388,13 @@ build.infoboxPhoto = function(data, forView = false) {
html += `
</table>
<div class='bumper'></div>
`
return html;
}
build.infoboxAlbum = function(data, forView = false) {
build.sidebarAlbum = function(data, forView = false) {
var html = '',
visible = '',
@ -439,8 +438,8 @@ build.infoboxAlbum = function(data, forView = false) {
}
if (forView===false&&lychee.publicMode===false) {
editTitleHTML = ' ' + build.editIcon('edit_title_album');
editDescriptionHTML = ' ' + build.editIcon('edit_description_album');
editTitleHTML = ' ' + build.editIcon('edit_title');
editDescriptionHTML = ' ' + build.editIcon('edit_description');
}
infos = [
@ -488,7 +487,6 @@ build.infoboxAlbum = function(data, forView = false) {
html += `
</table>
<div class='bumper'></div>
`
return html;

View File

@ -28,8 +28,8 @@ $(document).ready(function() {
});
header.dom('#button_signin') .on(eventName, lychee.loginDialog);
header.dom('#button_settings') .on(eventName, contextMenu.settings);
header.dom('#button_info_album') .on(eventName, view.infobox.show);
header.dom('#button_info') .on(eventName, view.infobox.show);
header.dom('#button_info_album') .on(eventName, sidebar.toggle);
header.dom('#button_info') .on(eventName, sidebar.toggle);
header.dom('.button_add') .on(eventName, contextMenu.add);
header.dom('#button_more') .on(eventName, function(e) { contextMenu.photoMore(photo.getID(), e) });
header.dom('#button_move') .on(eventName, function(e) { contextMenu.move([photo.getID()], e) });
@ -50,23 +50,11 @@ $(document).ready(function() {
search.reset();
});
/* Infobox */
lychee.infobox.find('.header .close').on(eventName, view.infobox.hide);
/* Image View */
lychee.imageview
.on(eventName, '.arrow_wrapper--previous', photo.previous)
.on(eventName, '.arrow_wrapper--next', photo.next);
/* Infobox */
lychee.infobox
.on(eventName, '#edit_title_album', function() { album.setTitle([album.getID()]) })
.on(eventName, '#edit_description_album', function() { album.setDescription(album.getID()) })
.on(eventName, '#edit_title', function() { photo.setTitle([photo.getID()]) })
.on(eventName, '#edit_description', function() { photo.setDescription(photo.getID()) })
.on(eventName, '#edit_tags', function() { photo.editTags([photo.getID()]) })
.on(eventName, '#tags .tag span', function() { photo.deleteTag(photo.getID(), $(this).data('index')) });
/* Keyboard */
Mousetrap
.bind('left', function() { if (visible.photo()) $('#imageview a#previous').click() })
@ -97,9 +85,8 @@ $(document).ready(function() {
}
})
.bind('i', function() {
if (visible.infobox()) view.infobox.hide();
else if (visible.multiselect()) return false;
else if (visible.infoboxbutton()) view.infobox.show();
if (visible.multiselect()) return false;
else sidebar.toggle();
})
.bind(['command+backspace', 'ctrl+backspace'], function() {
if (visible.photo()&&!visible.message()) photo.delete([photo.getID()]);
@ -118,7 +105,6 @@ $(document).ready(function() {
e.preventDefault();
if (basicModal.visible()===true) basicModal.cancel();
else if (visible.contextMenu()) contextMenu.close();
else if (visible.infobox()) view.infobox.hide();
else if (visible.photo()) lychee.goto(album.getID());
else if (visible.album()) lychee.goto('');
else if (visible.albums()&&$('#search').val().length!==0) search.reset();
@ -158,9 +144,6 @@ $(document).ready(function() {
.on('contextmenu', '.photo', function(e) { contextMenu.photo(photo.getID(), e) })
.on('contextmenu', '.album', function(e) { contextMenu.album(album.getID(), e) })
/* Infobox */
.on(eventName, '#infobox_overlay', view.infobox.hide)
/* Upload */
.on('change', '#upload_files', function() { basicModal.close(); upload.start.local(this.files) })
.on('dragover', function(e) { e.preventDefault(); }, false)

View File

@ -26,8 +26,7 @@ lychee = {
dropboxKey: '',
content: $('#content'),
imageview: $('#imageview'),
infobox: $('#infobox')
imageview: $('#imageview')
}
@ -227,8 +226,8 @@ lychee.load = function() {
photo.json = null;
// Show Albums
if (visible.album()) view.album.hide();
if (visible.photo()) view.photo.hide();
if (visible.sidebar()) sidebar.toggle();
albums.load();
}

View File

@ -18,11 +18,12 @@ multiselect.show = function(e) {
if (lychee.publicMode) return false;
if (visible.search()) return false;
if (visible.infobox()) return false;
if (!visible.albums()&&!visible.album) return false;
if ($('.album:hover, .photo:hover').length!==0) return false;
if (visible.multiselect()) $('#multiselect').remove();
sidebar.setSelectable(false);
multiselect.position.top = e.pageY;
multiselect.position.right = -1 * (e.pageX - $(document).width());
multiselect.position.bottom = -1 * (multiselect.position.top - $(window).height());
@ -41,10 +42,11 @@ multiselect.selectAll = function() {
if (lychee.publicMode) return false;
if (visible.search()) return false;
if (visible.infobox()) return false;
if (!visible.albums()&&!visible.album) return false;
if (visible.multiselect()) $('#multiselect').remove();
sidebar.setSelectable(false);
multiselect.position.top = 70;
multiselect.position.right = 40;
multiselect.position.bottom = 90;
@ -189,6 +191,8 @@ multiselect.getSelection = function(e) {
multiselect.close = function() {
sidebar.setSelectable(true);
multiselect.stopResize();
multiselect.position.top = null;

88
src/scripts/sidebar.js Normal file
View File

@ -0,0 +1,88 @@
/**
* @description This module takes care of the sidebar.
* @copyright 2015 by Tobias Reich
*/
sidebar = {
_dom: $('#sidebar')
}
sidebar.dom = function(selector) {
if (selector===undefined||selector===null||selector==='') return sidebar._dom;
return sidebar._dom.find(selector);
}
sidebar.bind = function() {
// This function should be called after building and appending
// the sidebars content to the DOM
// Event Name
var eventName = ('ontouchend' in document.documentElement) ? 'touchend' : 'click';
sidebar.dom('#edit_title').on(eventName, function() {
if (visible.photo()) photo.setTitle([photo.getID()]);
else if (visible.album()) album.setTitle([album.getID()]);
});
sidebar.dom('#edit_description').on(eventName, function() {
if (visible.photo()) photo.setDescription(photo.getID());
else if (visible.album()) album.setDescription(album.getID());
});
sidebar.dom('#edit_tags') .on(eventName, function() { photo.editTags([photo.getID()]) });
sidebar.dom('#tags .tag span') .on(eventName, function() { photo.deleteTag(photo.getID(), $(this).data('index')) });
return true;
}
sidebar.toggle = function() {
if (visible.sidebar()||
visible.sidebarbutton()) {
header.dom('.button--info').toggleClass('active')
lychee.content.toggleClass('sidebar');
sidebar.dom().toggleClass('active');
return true;
}
return false;
}
sidebar.setSelectable = function(selectable = true) {
// Attributes/Values inside the sidebar are selectable by default.
// Selection needs to be deactivated to prevent an unwanted selection
// while using multiselect.
if (selectable===true) sidebar.dom().removeClass('notSelectable');
else sidebar.dom().addClass('notSelectable');
}
sidebar.changeAttr = function(attr, value, editable = false) {
if (attr===undefined||attr===null||attr==='') return false;
// This will add an edit-icon next to the value when editable is true.
// The id of the edit-icon always starts with 'edit_' followed by the name of the attribute.
if (editable===true) value = value + ' ' + build.editIcon('edit_' + attr);
sidebar.dom('.attr_' + attr).html(value);
// The new edit-icon needs an event, therefore the binding function
// should be executed again after changing the value
if (editable===true) sidebar.bind();
return true;
}

View File

@ -5,25 +5,6 @@
view = {}
view.infobox = {
show: function() {
if (!visible.infobox()) $('body').append("<div id='infobox_overlay' class='fadeIn'></div>");
lychee.infobox.addClass('active');
},
hide: function() {
lychee.animate('#infobox_overlay', 'fadeOut');
setTimeout(function() { $('#infobox_overlay').remove() }, 300);
lychee.infobox.removeClass('active');
}
}
view.albums = {
init: function() {
@ -114,7 +95,7 @@ view.albums = {
marginLeft: 0
}, 300, function() {
$(this).remove();
if (albums.json.num<=0) lychee.animate('.divider:last-of-type', 'fadeOut');
if (albums.json.num<=0) lychee.animate('#content .divider:last-of-type', 'fadeOut');
});
}
@ -129,7 +110,7 @@ view.album = {
album.parse();
view.album.infobox();
view.album.sidebar();
view.album.title();
view.album.public();
view.album.content.init();
@ -138,12 +119,6 @@ view.album = {
},
hide: function() {
view.infobox.hide();
},
title: function() {
if ((visible.album()||!album.json.init)&&!visible.photo()) {
@ -162,7 +137,7 @@ view.album = {
lychee.setTitle('Unsorted', false);
break;
default:
if (album.json.init) $('#infobox .attr_title').html(album.json.title + ' ' + build.editIcon('edit_title_album'));
if (album.json.init) sidebar.changeAttr('title', album.json.title, true);
lychee.setTitle(album.json.title, true);
break;
}
@ -241,13 +216,13 @@ view.album = {
description: function() {
$('#infobox .attr_description').html(album.json.description + ' ' + build.editIcon('edit_description_album'));
sidebar.changeAttr('description', album.json.description, true);
},
num: function() {
$('#infobox .attr_images').html(album.json.num);
sidebar.changeAttr('images', album.json.num);
},
@ -261,7 +236,7 @@ view.album = {
$('.photo .iconic-share').remove();
if (album.json.init) $('#infobox .attr_public').html('Yes');
if (album.json.init) sidebar.changeAttr('public', 'Yes');
} else {
@ -269,28 +244,31 @@ view.album = {
.removeClass('active')
.attr('title', 'Make Public');
if (album.json.init) $('#infobox .attr_public').html('No');
if (album.json.init) sidebar.changeAttr('public', 'No');
}
},
password: function() {
if (album.json.password==='1') $('#infobox .attr_password').html('Yes');
else $('#infobox .attr_password').html('No');
if (album.json.password==='1') sidebar.changeAttr('password', 'Yes');
else sidebar.changeAttr('password', 'No');
},
downloadable: function() {
if (album.json.downloadable==='1') $('#infobox .attr_downloadable').html('Yes');
else $('#infobox .attr_downloadable').html('No');
if (album.json.downloadable==='1') sidebar.changeAttr('downloadable', 'Yes');
else sidebar.changeAttr('downloadable', 'No');
},
infobox: function() {
sidebar: function() {
if ((visible.album()||!album.json.init)&&!visible.photo()) lychee.infobox.find('.wrapper').html(build.infoboxAlbum(album.json));
if ((visible.album()||!album.json.init)&&!visible.photo()) {
sidebar.dom('.wrapper').html(build.sidebarAlbum(album.json));
sidebar.bind();
}
}
@ -302,7 +280,7 @@ view.photo = {
photo.parse();
view.photo.infobox();
view.photo.sidebar();
view.photo.title();
view.photo.star();
view.photo.public();
@ -333,7 +311,6 @@ view.photo = {
hide: function() {
header.show();
if (visible.infobox) view.infobox.hide();
lychee.content.removeClass('view');
header.setMode('album');
@ -350,21 +327,21 @@ view.photo = {
lychee.animate(lychee.imageview, 'fadeOut');
setTimeout(function() {
lychee.imageview.hide();
view.album.infobox();
view.album.sidebar();
}, 300);
},
title: function() {
if (photo.json.init) $('#infobox .attr_title').html(photo.json.title + ' ' + build.editIcon('edit_title'));
if (photo.json.init) sidebar.changeAttr('title', photo.json.title, true);
lychee.setTitle(photo.json.title, true);
},
description: function() {
if (photo.json.init) $('#infobox .attr_description').html(photo.json.description + ' ' + build.editIcon('edit_description'));
if (photo.json.init) sidebar.changeAttr('description', photo.json.description, true);
},
@ -390,20 +367,21 @@ view.photo = {
$('#button_share')
.addClass('active')
.attr('title', 'Share Photo');
if (photo.json.init) $('#infobox .attr_public').html('Yes');
if (photo.json.init) sidebar.changeAttr('public', 'Yes');
} else {
// Photo private
$('#button_share')
.removeClass('active')
.attr('title', 'Make Public');
if (photo.json.init) $('#infobox .attr_public').html('No');
if (photo.json.init) sidebar.changeAttr('public', 'No');
}
},
tags: function() {
$('#infobox #tags').html(build.tags(photo.json.tags));
sidebar.dom('#tags').html(build.tags(photo.json.tags));
sidebar.bind();
},
@ -438,9 +416,10 @@ view.photo = {
},
infobox: function() {
sidebar: function() {
lychee.infobox.find('.wrapper').html(build.infoboxPhoto(photo.json));
sidebar.dom('.wrapper').html(build.sidebarPhoto(photo.json));
sidebar.bind();
}

View File

@ -25,12 +25,12 @@ visible.search = function() {
return false;
}
visible.infobox = function() {
if ($('#infobox.active').length>0) return true;
visible.sidebar = function() {
if (sidebar.dom().hasClass('active')===true) return true;
return false;
}
visible.infoboxbutton = function() {
visible.sidebarbutton = function() {
if (visible.albums()) return false;
if (visible.photo()) return true;
if (visible.album()&&$('#button_info_album:visible').length>0) return true;

View File

@ -18,6 +18,8 @@
border-top: 1px solid white(.02);
}
&.sidebar { width: calc(100% - 300px); }
/* Albums and Photos ------------------------------------------------*/
.album,
.photo {

View File

@ -96,6 +96,8 @@ header {
&--eye.active .iconic { fill: #ff9737; }
&--info.active .iconic { fill: $colorBlue; }
&#button_signin { display: none; }
}

View File

@ -2,62 +2,24 @@
* @copyright 2015 by Tobias Reich
*/
#infobox_overlay {
z-index: 3;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: black(.8);
}
#sidebar {
#infobox {
z-index: 4;
position: fixed;
top: 50px;
right: -370px;
width: 350px;
height: 100%;
background-color: rgba(30, 30, 30, .98);
box-shadow: -1px 0 2px black(.7);
height: calc(100% - 50px);
background-color: rgba(25, 25, 25, .98);
border-left: 1px solid black(.2);
transform: translateX(0);
transition: transform .3s $timingBounce;
&.active { transform: translateX(-92%); }
&.active { transform: translateX(-320px); }
/* Misc ------------------------------------------------*/
.wrapper {
float: left;
height: 100%;
width: 300px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
.edit {
display: inline-block;
margin-left: 3px;
width: 10px;
.iconic {
fill: white(.5);
filter: drop-shadow($shadow);
transition: fill .2s ease-out;
}
&:hover .iconic { fill: white(1); }
&:active .iconic {
transition: none;
fill: white(.8);
}
}
.bumper {
float: left;
width: 100%;
height: 50px;
&.notSelectable table tr td:last-child {
-webkit-user-select: none !important;
-moz-user-select: none !important;
user-select: none !important;
}
/* Header ------------------------------------------------*/
@ -65,14 +27,14 @@
float: left;
height: 49px;
width: 100%;
background: linear-gradient(to bottom, #1f1f1f, #1a1a1a);
border-bottom: 1px solid #0f0f0f;
background: linear-gradient(to bottom, white(.02), black(0));
border-top: 1px solid $colorBlue;
}
.header h1 {
position: absolute;
margin: 15px 30% 15px calc(30% - 25px);
width: 40%;
margin: 15px 50px 15px 0;
width: calc(100% - 50px);
color: #fff;
font-size: 16px;
font-weight: bold;
@ -99,6 +61,15 @@
}
}
/* Wrapper ------------------------------------------------*/
.wrapper {
float: left;
height: calc(100% - 49px);
width: 300px;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
/* Divider ------------------------------------------------*/
.divider {
float: left;
@ -107,6 +78,11 @@
border-top: 1px solid white(.02);
box-shadow: $shadow;
&:first-child {
border-top: 0;
box-shaodw: none;
}
h1 {
margin: 0 0 0 20px;
color: white(.6);
@ -115,6 +91,26 @@
}
}
/* Edit ------------------------------------------------*/
.edit {
display: inline-block;
margin-left: 3px;
width: 10px;
.iconic {
fill: white(.5);
filter: drop-shadow($shadow);
transition: fill .2s ease-out;
}
&:hover .iconic { fill: white(1); }
&:active .iconic {
transition: none;
fill: white(.8);
}
}
/* Table ------------------------------------------------*/
table {
float: left;
@ -127,13 +123,14 @@
font-size: 14px;
line-height: 19px;
-webkit-user-select: text;
-moz-user-select: text;
user-select: text;
&:first-child { width: 110px; }
&:last-child { padding-right: 10px; }
&:last-child {
padding-right: 10px;
-webkit-user-select: text;
-moz-user-select: text;
user-select: text;
}
}
/* Tags ------------------------------------------------*/

View File

@ -47,7 +47,7 @@ input {
@import 'contextmenu';
@import 'header';
@import 'imageview';
@import 'infobox';
@import 'sidebar';
@import 'loading';
@import 'message';
@import 'multiselect';