Browse Source

Basic implementation for tags
- Edit Tags
- Delete Tags
- Search Tags

Multiselect:
- Only when logged in

Tobias Reich 11 years ago
parent
commit
be404366bc

+ 6 - 1
assets/css/modules/infobox.css

@@ -131,10 +131,15 @@
 
 
 	/* Tags ------------------------------------------------*/
 	/* Tags ------------------------------------------------*/
 	#infobox #tags {
 	#infobox #tags {
-		margin: 20px 20px 15px 20px;
+		width: calc(100% - 40px);
+		margin: 16px 20px 12px 20px;
 		color: #fff;
 		color: #fff;
 		display: inline-block;
 		display: inline-block;
 	}
 	}
+	#infobox #tags .empty {
+		font-size: 14px;
+		margin-bottom: 8px;
+	}
 	#infobox .tag {
 	#infobox .tag {
 		float: left;
 		float: left;
 		padding: 4px 7px;
 		padding: 4px 7px;

+ 33 - 9
assets/js/modules/build.js

@@ -18,11 +18,11 @@ build = {
 		return "<div id='" + id + "' class='edit'><a class='icon-pencil'></a></div>";
 		return "<div id='" + id + "' class='edit'><a class='icon-pencil'></a></div>";
 
 
 	},
 	},
-		
+
 	multiselect: function(top, left) {
 	multiselect: function(top, left) {
-	
+
 		return "<div id='multiselect' style='top: " + top + "px; left: " + left + "px;'></div>";
 		return "<div id='multiselect' style='top: " + top + "px; left: " + left + "px;'></div>";
-	
+
 	},
 	},
 
 
 	album: function(albumJSON) {
 	album: function(albumJSON) {
@@ -37,7 +37,7 @@ build = {
 			title = albumJSON.title.substr(0, 18) + "...";
 			title = albumJSON.title.substr(0, 18) + "...";
 			longTitle = albumJSON.title;
 			longTitle = albumJSON.title;
 		}
 		}
-		
+
 		typeThumb0 = albumJSON.thumb0.split('.').pop();
 		typeThumb0 = albumJSON.thumb0.split('.').pop();
 		typeThumb1 = albumJSON.thumb1.split('.').pop();
 		typeThumb1 = albumJSON.thumb1.split('.').pop();
 		typeThumb2 = albumJSON.thumb2.split('.').pop();
 		typeThumb2 = albumJSON.thumb2.split('.').pop();
@@ -241,6 +241,32 @@ build = {
 
 
 	},
 	},
 
 
+	tags: function(tags, forView) {
+
+		var html = "",
+			editTagsHTML;
+
+		if (tags!=="") {
+
+			tags = tags.split(",");
+
+			tags.forEach(function(tag, index, array) {
+
+				html += "<a class='tag'>" + tag + "<span class='icon-remove' data-index='" + index + "'></span></a>";
+
+			});
+
+		} else {
+
+			editTagsHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_tags");
+			html = "<div class='empty'>No Tags" + editTagsHTML + "</div>";
+
+		}
+
+		return html;
+
+	},
+
 	infoboxPhoto: function(photoJSON, forView) {
 	infoboxPhoto: function(photoJSON, forView) {
 
 
 		if (!photoJSON) return "";
 		if (!photoJSON) return "";
@@ -272,7 +298,6 @@ build = {
 		editTitleHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_title");
 		editTitleHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_title");
 		editDescriptionHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_description");
 		editDescriptionHTML = (forView===true||lychee.publicMode) ? "" : " " + build.editIcon("edit_description");
 
 
-		//["Tags", "<a class='tag'>Abstract<span class='icon-remove'></span></a><a class='tag'>Colors<span class='icon-remove'></span></a><a class='tag'>Photoshop<span class='icon-remove'></span></a><a class='tag'>Something<span class='icon-remove'></span></a><a class='tag'>Lychee<span class='icon-remove'></span></a><a class='tag'>Tags<span class='icon-remove'></span></a><a class='tag icon-plus'></a>"]
 		infos = [
 		infos = [
 			["", "Basics"],
 			["", "Basics"],
 			["Name", photoJSON.title + editTitleHTML],
 			["Name", photoJSON.title + editTitleHTML],
@@ -281,7 +306,8 @@ build = {
 			["", "Image"],
 			["", "Image"],
 			["Size", photoJSON.size],
 			["Size", photoJSON.size],
 			["Format", photoJSON.type],
 			["Format", photoJSON.type],
-			["Resolution", photoJSON.width + " x " + photoJSON.height]
+			["Resolution", photoJSON.width + " x " + photoJSON.height],
+			["Tags", build.tags(photoJSON.tags, forView)]
 		];
 		];
 
 
 		if ((photoJSON.takedate+photoJSON.make+photoJSON.model+photoJSON.shutter+photoJSON.aperture+photoJSON.focal+photoJSON.iso)!="") {
 		if ((photoJSON.takedate+photoJSON.make+photoJSON.model+photoJSON.shutter+photoJSON.aperture+photoJSON.focal+photoJSON.iso)!="") {
@@ -319,9 +345,7 @@ build = {
 				case "Tags":	// Tags
 				case "Tags":	// Tags
 								infobox += "</table>";
 								infobox += "</table>";
 								infobox += "<div class='separator'><h1>" + infos[index][0] + "</h1></div>";
 								infobox += "<div class='separator'><h1>" + infos[index][0] + "</h1></div>";
-								infobox += "<tr>";
-								infobox +=		"<div id='tags'>" + infos[index][1] + "</div>";
-								infobox += "</tr>";
+								infobox += "<div id='tags'>" + infos[index][1] + "</div>";
 								break;
 								break;
 
 
 				default:		// Item
 				default:		// Item

+ 2 - 2
assets/js/modules/contextMenu.js

@@ -110,8 +110,8 @@ contextMenu = {
 		if (albumID==="0"||albumID==="f"||albumID==="s") return false;	
 		if (albumID==="0"||albumID==="f"||albumID==="s") return false;	
 
 
 		contextMenu.fns = [
 		contextMenu.fns = [
-			function() { album.setTitle(albumID) },
-			function() { album.delete(albumID) }
+			function() { album.setTitle([albumID]) },
+			function() { album.delete([albumID]) }
 		];
 		];
 
 
 		items = [
 		items = [

+ 6 - 4
assets/js/modules/init.js

@@ -35,7 +35,7 @@ $(document).ready(function(){
 		else modal.show("Share Album", "All photos inside this album will be public and visible for everyone. Existing public photos will have the same sharing permission as this album. Are your sure you want to share this album? <input class='text' type='password' placeholder='password (optional)' value=''>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]]);
 		else modal.show("Share Album", "All photos inside this album will be public and visible for everyone. Existing public photos will have the same sharing permission as this album. Are your sure you want to share this album? <input class='text' type='password' placeholder='password (optional)' value=''>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]]);
 	});
 	});
 	$("#button_download").on(event_name, function() { photo.getArchive(photo.getID()) });
 	$("#button_download").on(event_name, function() { photo.getArchive(photo.getID()) });
-	$("#button_trash_album").on(event_name, function() { album.delete(album.getID()) });
+	$("#button_trash_album").on(event_name, function() { album.delete([album.getID()]) });
 	$("#button_move").on(event_name, function(e) { contextMenu.move([photo.getID()], e) });
 	$("#button_move").on(event_name, function(e) { contextMenu.move([photo.getID()], e) });
 	$("#button_trash").on(event_name, function() { photo.delete([photo.getID()]) });
 	$("#button_trash").on(event_name, function() { photo.delete([photo.getID()]) });
 	$("#button_info_album").on(event_name, function() { view.infobox.show() });
 	$("#button_info_album").on(event_name, function() { view.infobox.show() });
@@ -68,10 +68,12 @@ $(document).ready(function(){
 	/* Infobox */
 	/* Infobox */
 	$("#infobox")
 	$("#infobox")
 		.on(event_name, ".header a", function() { view.infobox.hide() })
 		.on(event_name, ".header a", function() { view.infobox.hide() })
-		.on(event_name, "#edit_title_album", function() { album.setTitle(album.getID()) })
+		.on(event_name, "#edit_title_album", function() { album.setTitle([album.getID()]) })
 		.on(event_name, "#edit_description_album", function() { album.setDescription(album.getID()) })
 		.on(event_name, "#edit_description_album", function() { album.setDescription(album.getID()) })
 		.on(event_name, "#edit_title", function() { photo.setTitle([photo.getID()]) })
 		.on(event_name, "#edit_title", function() { photo.setTitle([photo.getID()]) })
-		.on(event_name, "#edit_description", function() { photo.setDescription(photo.getID()) });
+		.on(event_name, "#edit_description", function() { photo.setDescription(photo.getID()) })
+		.on(event_name, "#edit_tags", function() { photo.editTags([photo.getID()]) })
+		.on(event_name, "#tags .tag span", function() { photo.deleteTag(photo.getID(), $(this).data('index')) });
 
 
 	/* Keyboard */
 	/* Keyboard */
 	Mousetrap
 	Mousetrap
@@ -108,7 +110,7 @@ $(document).ready(function(){
 		/* Header */
 		/* Header */
 		.on(event_name, "#title.editable", function() {
 		.on(event_name, "#title.editable", function() {
 			if (visible.photo()) photo.setTitle([photo.getID()]);
 			if (visible.photo()) photo.setTitle([photo.getID()]);
-			else album.setTitle(album.getID());
+			else album.setTitle([album.getID()]);
 		})
 		})
 
 
 		/* Navigation */
 		/* Navigation */

+ 3 - 2
assets/js/modules/multiselect.js

@@ -19,6 +19,7 @@ multiselect = {
 	show: function(e) {
 	show: function(e) {
 	
 	
 		if (mobileBrowser()) return false;
 		if (mobileBrowser()) return false;
+		if (lychee.publicMode) return false;
 		if ($('.album:hover, .photo:hover').length!=0) return false;
 		if ($('.album:hover, .photo:hover').length!=0) return false;
 		if (visible.multiselect()) $('#multiselect').remove();
 		if (visible.multiselect()) $('#multiselect').remove();
 	
 	
@@ -133,7 +134,7 @@ multiselect = {
 				
 				
 					id = $(this).data('id');
 					id = $(this).data('id');
 					
 					
-					if (id!=="0"&&id!==0&&id!=="f"&&id!=="s"&&id!==null&id!==undefined) {
+					if (id!=='0'&&id!==0&&id!=='f'&&id!=='s'&&id!==null&id!==undefined) {
 				
 				
 						ids.push(id);
 						ids.push(id);
 						$(this).addClass('active');
 						$(this).addClass('active');
@@ -159,7 +160,7 @@ multiselect = {
 		multiselect.position.bottom = null;
 		multiselect.position.bottom = null;
 		multiselect.position.left = null;
 		multiselect.position.left = null;
 		
 		
-		lychee.animate('#multiselect', "fadeOut");
+		lychee.animate('#multiselect', 'fadeOut');
 		setTimeout(function() {
 		setTimeout(function() {
 			$('#multiselect').remove();
 			$('#multiselect').remove();
 		}, 300);
 		}, 300);

+ 62 - 0
assets/js/modules/photo.js

@@ -302,7 +302,69 @@ photo = {
 		modal.show("Set Description", "Please enter a description for this photo: <input class='text' type='text' placeholder='Description' value='" + oldDescription + "'>", buttons);
 		modal.show("Set Description", "Please enter a description for this photo: <input class='text' type='text' placeholder='Description' value='" + oldDescription + "'>", buttons);
 
 
 	},
 	},
+	
+	editTags: function(photoIDs) {
+	
+		var oldTags = "";
+	
+		if (!photoIDs) return false;
+		if (photoIDs instanceof Array===false) photoIDs = [photoIDs];
+		if (visible.photo()) oldTags = photo.json.tags;
+	
+		buttons = [
+			["Set Tags", function() {
+
+				tags = $(".message input.text").val();
 
 
+				if (tags.length<800) {
+
+					if (visible.photo()) {
+						photo.json.tags = tags;
+						view.photo.tags();
+					}
+
+					photo.setTags(photoIDs, tags)
+
+				} else loadingBar.show("error", "Description too long. Please try again!");
+
+			}],
+			["Cancel", function() {}]
+		];
+		modal.show("Set Tags", "Please enter your tags for this photo. You can add multiple tags by separating them with a comma: <input class='text' type='text' placeholder='Tags' value='" + oldTags + "'>", buttons);
+	
+	},
+	
+	setTags: function(photoIDs, tags) {
+		
+		var params;
+	
+		if (!photoIDs) return false;
+		if (photoIDs instanceof Array===false) photoIDs = [photoIDs];
+		
+		params = "setTags&photoIDs=" + photoIDs + "&tags=" + tags;
+		lychee.api(params, function(data) {
+
+			if (data!==true) lychee.error(null, params, data);
+
+		});
+	
+	},
+		
+	deleteTag: function(photoID, index) {
+		
+		var tags;
+	
+		// Remove
+		tags = photo.json.tags.split(',');
+		tags.splice(index, 1);
+				
+		// Save
+		photo.json.tags = tags.toString();
+		view.photo.tags();
+		photo.setTags([photoID], photo.json.tags);
+	
+	},
+		
 	share: function(photoID, service) {
 	share: function(photoID, service) {
 
 
 		var link = "",
 		var link = "",

+ 6 - 0
assets/js/modules/view.js

@@ -447,6 +447,12 @@ view = {
 			}
 			}
 
 
 		},
 		},
+		
+		tags: function() {
+		
+			$("#infobox #tags").html(build.tags(photo.json.tags));
+		
+		},
 
 
 		photo: function() {
 		photo: function() {
 
 

+ 11 - 0
php/api.php

@@ -24,6 +24,7 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
 	require('modules/upload.php');
 	require('modules/upload.php');
 	require('modules/album.php');
 	require('modules/album.php');
 	require('modules/photo.php');
 	require('modules/photo.php');
+	require('modules/tags.php');
 	require('modules/misc.php');
 	require('modules/misc.php');
 
 
 	if (file_exists('config.php')) require('config.php');
 	if (file_exists('config.php')) require('config.php');
@@ -157,6 +158,16 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
 			case 'search':			if (isset($_POST['term']))
 			case 'search':			if (isset($_POST['term']))
 										echo json_encode(search($_POST['term']));
 										echo json_encode(search($_POST['term']));
 									break;
 									break;
+									
+			// Tag Functions
+			
+			case 'getTags':			if (isset($_POST['photoID']))
+										echo json_encode(getTags($_POST['photoID']));
+									break;
+			
+			case 'setTags':			if (isset($_POST['photoIDs'])&&isset($_POST['tags']))
+										echo setTags($_POST['photoIDs'], $_POST['tags']);
+									break;
 
 
 			// Session Function
 			// Session Function
 
 

+ 1 - 1
php/modules/album.php

@@ -16,8 +16,8 @@ function addAlbum($title) {
     if (strlen($title)<1||strlen($title)>30) return false;
     if (strlen($title)<1||strlen($title)>30) return false;
     $sysdate = date("d.m.Y");
     $sysdate = date("d.m.Y");
     $result = $database->query("INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');");
     $result = $database->query("INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');");
+    
     if (!$result) return false;
     if (!$result) return false;
-
     return $database->insert_id;
     return $database->insert_id;
 
 
 }
 }

+ 1 - 0
php/modules/db.php

@@ -152,6 +152,7 @@ function createTables($database) {
 				`title` varchar(50) NOT NULL,
 				`title` varchar(50) NOT NULL,
 				`description` varchar(1000) NOT NULL DEFAULT '',
 				`description` varchar(1000) NOT NULL DEFAULT '',
 				`url` varchar(100) NOT NULL,
 				`url` varchar(100) NOT NULL,
+				`tags` varchar(1000) NOT NULL DEFAULT '',
 				`public` tinyint(1) NOT NULL,
 				`public` tinyint(1) NOT NULL,
 				`type` varchar(10) NOT NULL,
 				`type` varchar(10) NOT NULL,
 				`width` int(11) NOT NULL,
 				`width` int(11) NOT NULL,

+ 3 - 3
php/modules/misc.php

@@ -44,13 +44,13 @@ function search($term) {
 
 
 	$return["albums"] = "";
 	$return["albums"] = "";
 
 
-    $result = $database->query("SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%';");
+    $result = $database->query("SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%' OR tags like '%$term%';");
     while($row = $result->fetch_array()) {
     while($row = $result->fetch_array()) {
         $return['photos'][$row['id']] = $row;
         $return['photos'][$row['id']] = $row;
         $return['photos'][$row['id']]['sysdate'] = date('d F Y', strtotime($row['sysdate']));
         $return['photos'][$row['id']]['sysdate'] = date('d F Y', strtotime($row['sysdate']));
     }
     }
 
 
-    $result = $database->query("SELECT * FROM lychee_albums WHERE title like '%$term%';");
+    $result = $database->query("SELECT * FROM lychee_albums WHERE title like '%$term%' OR description like '%$term%';");
     $i=0;
     $i=0;
     while($row = $result->fetch_object()) {
     while($row = $result->fetch_object()) {
 
 
@@ -85,7 +85,7 @@ function update() {
 	if($database->query("SELECT `password` FROM `lychee_albums` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_albums` CHANGE  `password` `password` VARCHAR( 100 ) NULL DEFAULT ''");
 	if($database->query("SELECT `password` FROM `lychee_albums` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_albums` CHANGE  `password` `password` VARCHAR( 100 ) NULL DEFAULT ''");
 
 
 	if($database->query("SELECT `description` FROM `lychee_photos` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_photos` CHANGE  `description` `description` VARCHAR( 1000 ) NULL DEFAULT ''");
 	if($database->query("SELECT `description` FROM `lychee_photos` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_photos` CHANGE  `description` `description` VARCHAR( 1000 ) NULL DEFAULT ''");
-	if($database->query("SELECT `shortlink` FROM `lychee_photos` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_photos` DROP  `shortlink`");
+	if(!$database->query("SELECT `tags` FROM `lychee_photos` LIMIT 1;")) $database->query("ALTER TABLE  `lychee_photos` ADD  `tags` VARCHAR( 1000 ) NULL DEFAULT ''");
 	$database->query("UPDATE `lychee_photos` SET url = replace(url, 'uploads/big/', ''), thumbUrl = replace(thumbUrl, 'uploads/thumb/', '')");
 	$database->query("UPDATE `lychee_photos` SET url = replace(url, 'uploads/big/', ''), thumbUrl = replace(thumbUrl, 'uploads/thumb/', '')");
 	
 	
 	$result = $database->query("SELECT `value` FROM `lychee_settings` WHERE `key` = 'importFilename' LIMIT 1;");
 	$result = $database->query("SELECT `value` FROM `lychee_settings` WHERE `key` = 'importFilename' LIMIT 1;");

+ 38 - 0
php/modules/tags.php

@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @name        Album Module
+ * @author      Tobias Reich
+ * @copyright   2014 by Philipp Maurer, Tobias Reich
+ */
+
+if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
+
+function getTags($photoID) {
+
+	global $database;
+
+	$result = $database->query("SELECT tags FROM lychee_photos WHERE id = '$photoID';");
+	$return = $result->fetch_array();
+
+	if (!$result) return false;
+	return $return;
+
+}
+
+function setTags($photoIDs, $tags) {
+
+	global $database;
+
+	if (substr($tags, strlen($tags)-1)===',') $tags = substr($tags, 0, strlen($tags)-1);
+	$tags = str_replace(' , ', ',', $tags);
+	$tags = str_replace(', ', ',', $tags);
+	$tags = str_replace(' ,', ',', $tags);
+	$tags = str_replace(',,', ',', $tags);
+
+	$result = $database->query("UPDATE lychee_photos SET tags = '$tags' WHERE id IN ($photoIDs);");
+
+	if (!$result) return false;
+	return true;
+
+}