Browse Source

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
Tobias Reich 9 years ago
parent
commit
2b39f64c34

File diff suppressed because it is too large
+ 0 - 0
dist/main.css


File diff suppressed because it is too large
+ 0 - 0
dist/main.js


File diff suppressed because it is too large
+ 0 - 0
dist/view.js


+ 4 - 7
index.html

@@ -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>

+ 4 - 6
src/scripts/build.js

@@ -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;

+ 4 - 21
src/scripts/init.js

@@ -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)

+ 2 - 3
src/scripts/lychee.js

@@ -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();
 
 	}

+ 6 - 2
src/scripts/multiselect.js

@@ -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 - 0
src/scripts/sidebar.js

@@ -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;
+
+}

+ 27 - 48
src/scripts/view.js

@@ -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();
 
 	}
 

+ 3 - 3
src/scripts/visible.js

@@ -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;

+ 2 - 0
src/styles/_content.scss

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

+ 2 - 0
src/styles/_header.scss

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

+ 54 - 57
src/styles/_infobox.scss → src/styles/_sidebar.scss

@@ -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);
-}
-
-#infobox {
+#sidebar {
 
-	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%); }
-
-	/* 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 { transform: translateX(-320px); }
 
-		&: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 ------------------------------------------------*/

+ 1 - 1
src/styles/main.scss

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

Some files were not shown because too many files changed in this diff