1 <%include include/head.html>
3 <div class="page-id hidden">image-browser</div>
5 <script language="javascript">
7 /* hide all those forms. */
8 function hideAndShowBlock(blockElement, clickToShowElement, clickToHideElement) {
9 $(blockElement).hide();
10 $(clickToShowElement).removeClass("hidden");
11 $(clickToShowElement).click(function() {
12 $(blockElement).slideDown();
13 $(clickToShowElement).addClass("hidden");
14 $(clickToHideElement).removeClass("hidden");
16 $(clickToHideElement).click(function() {
17 $(blockElement).slideUp();
18 $(clickToHideElement).addClass("hidden");
19 $(clickToShowElement).removeClass("hidden");
23 /* ID of the image currently being edited. */
24 var editingImageId = null;
27 * Shows the form for editing an image.
29 * @param imageId The ID of the image to edit.
31 function editImage(imageId) {
32 if (editingImageId != imageId) {
37 editingImageId = imageId;
38 $(".show-data", getImage(imageId)).hide();
39 $(".edit-data", getImage(imageId)).show();
40 $(document).bind("click.sone", function(event) {
41 if ($(event.target).closest("#image-" + imageId).size() == 0) {
48 * Cancels all image editing.
50 function cancelImageEditing() {
51 $(".image .show-data").show();
52 $(".image .edit-data").hide();
53 $("form.edit-image").each(function() {
56 $(document).unbind("click.sone");
57 editingImageId = null;
61 * Returns the image element with the given ID.
63 * @param imageId The ID of the image
64 * @return The image element
66 function getImage(imageId) {
67 return $("#sone .image .image-id:contains('" + imageId + "')").closest(".image");
73 * @param sourceId The ID of the source image
74 * @param destinationId The ID of the destionation image
76 function swapImage(sourceId, destinationId) {
77 sourceElement = getImage(sourceId);
78 destinationElement = getImage(destinationId);
79 sourceParent = sourceElement.closest(".image-row");
80 sourcePrevSibling = sourceElement.prev();
81 sourceElement.detach();
82 destinationElement.before(sourceElement);
83 if (sourcePrevSibling.get(0) != destinationElement.get(0)) {
84 destinationElement.detach();
85 (sourcePrevSibling.size() > 0) ? sourcePrevSibling.after(destinationElement) : sourceParent.prepend(destinationElement);
87 if ($("button[name='moveLeft']", sourceElement).hasClass("hidden") != $("button[name='moveLeft']", destinationElement).hasClass("hidden")) {
88 $("button[name='moveLeft']", sourceElement).toggleClass("hidden");
89 $("button[name='moveLeft']", destinationElement).toggleClass("hidden");
91 if ($("button[name='moveRight']", sourceElement).hasClass("hidden") != $("button[name='moveRight']", destinationElement).hasClass("hidden")) {
92 $("button[name='moveRight']", sourceElement).toggleClass("hidden");
93 $("button[name='moveRight']", destinationElement).toggleClass("hidden");
98 * Prepare all images for inline editing.
100 function prepareImages() {
101 $(".image").each(function() {
102 imageId = $(this).closest(".image").find(".image-id").text();
103 (function(element, imageId) {
104 $(".show-data", element).click(function() {
107 $("button[name='moveLeft'], button[name='moveRight']", element).click(function() {
108 ajaxGet("editImage.ajax", { "formPassword": getFormPassword(), "image": imageId, "moveLeft": this.name == "moveLeft", "moveRight": this.name == "moveRight" }, function(data) {
109 if (data && data.success) {
110 swapImage(data.sourceImageId, data.destinationImageId);
115 $("button[name='submit']", element).click(function() {
116 title = $(":input[name='title']:enabled", this.form).val();
117 description = $(":input[name='description']:enabled", this.form).val();
118 ajaxGet("editImage.ajax", { "formPassword": getFormPassword(), "image": imageId, "title": title, "description": description }, function(data) {
119 if (data && data.success) {
120 getImage(data.imageId).find(".image-title").text(data.title);
121 getImage(data.imageId).find(".image-description").html(data.parsedDescription);
122 getImage(data.imageId).find(":input[name='title']").attr("defaultValue", title);
123 getImage(data.imageId).find(":input[name='description']").attr("defaultValue", data.description);
124 cancelImageEditing();
133 /* ID of the album currently being edited. */
134 var editingAlbumId = null;
137 * Shows the form for editing an album.
139 * @param albumId The ID of the album to edit.
141 function editAlbum(albumId) {
142 if (editingAlbumId != albumId) {
143 if (editingAlbumId != null) {
144 cancelAlbumEditing();
147 console.log("already editing " + albumId);
150 editingAlbumId = albumId;
151 $(".show-data", getAlbum(albumId)).hide();
152 $(".edit-data", getAlbum(albumId)).show();
153 console.log(getAlbum(albumId));
154 $(document).bind("click.sone", function(event) {
155 if ($(event.target).closest("#album-" + albumId).size() == 0) {
156 cancelAlbumEditing();
162 * Cancels all album editing.
164 function cancelAlbumEditing() {
165 console.log("cancel-album-edit");
166 $(".album .show-data").show();
167 $(".album .edit-data").hide();
168 $("form.edit-album").each(function() {
171 $(document).unbind("click.sone");
172 editingAlbumId = null;
176 * Returns the album element with the given ID.
178 * @param albumId The ID of the album
179 * @return The album element
181 function getAlbum(albumId) {
182 return $("#sone .album .album-id:contains('" + albumId + "')").closest(".album");
188 * @param sourceId The ID of the source album
189 * @param destinationId The ID of the destionation album
191 function swapAlbum(sourceId, destinationId) {
192 sourceElement = getAlbum(sourceId);
193 destinationElement = getAlbum(destinationId);
194 sourceParent = sourceElement.closest(".album-row");
195 sourcePrevSibling = sourceElement.prev();
196 sourceElement.detach();
197 destinationElement.before(sourceElement);
198 if (sourcePrevSibling.get(0) != destinationElement.get(0)) {
199 destinationElement.detach();
200 (sourcePrevSibling.size() > 0) ? sourcePrevSibling.after(destinationElement) : sourceParent.prepend(destinationElement);
202 if ($("button[name='moveLeft']", sourceElement).hasClass("hidden") != $("button[name='moveLeft']", destinationElement).hasClass("hidden")) {
203 $("button[name='moveLeft']", sourceElement).toggleClass("hidden");
204 $("button[name='moveLeft']", destinationElement).toggleClass("hidden");
206 if ($("button[name='moveRight']", sourceElement).hasClass("hidden") != $("button[name='moveRight']", destinationElement).hasClass("hidden")) {
207 $("button[name='moveRight']", sourceElement).toggleClass("hidden");
208 $("button[name='moveRight']", destinationElement).toggleClass("hidden");
213 * Prepare all albums for inline editing.
215 function prepareAlbums() {
216 $(".album").each(function() {
217 albumId = $(this).closest(".album").find(".album-id").text();
218 (function(element, albumId) {
219 $(".show-data", element).click(function() {
220 console.log("show-data");
223 $("button[name='moveLeft'], button[name='moveRight']", element).click(function() {
224 ajaxGet("editAlbum.ajax", { "formPassword": getFormPassword(), "album": albumId, "moveLeft": this.name == "moveLeft", "moveRight": this.name == "moveRight" }, function(data) {
225 if (data && data.success) {
226 swapAlbum(data.sourceAlbumId, data.destinationAlbumId);
231 $("button[name='submit']", element).click(function() {
232 title = $(":input[name='title']:enabled", this.form).val();
233 description = $(":input[name='description']:enabled", this.form).val();
234 ajaxGet("editAlbum.ajax", { "formPassword": getFormPassword(), "album": albumId, "title": title, "description": description }, function(data) {
235 if (data && data.success) {
236 getAlbum(data.albumId).find(".album-title").text(data.title);
237 getAlbum(data.albumId).find(".album-description").text(data.description);
238 getAlbum(data.albumId).find(":input[name='title']").attr("defaultValue", title);
239 getAlbum(data.albumId).find(":input[name='description']").attr("defaultValue", description);
240 cancelAlbumEditing();
255 <p><%= Page.ImageBrowser.Album.Error.NotFound.Text|l10n|html></p>
257 <%elseifnull album.title>
259 <p><%= Page.ImageBrowser.Album.Error.NotFound.Text|l10n|html></p>
263 <%if album.sone.local>
264 <script language="javascript">
267 getTranslation("WebInterface.DefaultText.UploadImage.Title", function(text) {
268 $("#upload-image :input[name='title']").each(function() {
269 registerInputTextareaSwap(this, text, "title", false, true);
272 getTranslation("WebInterface.DefaultText.UploadImage.Description", function(text) {
273 $("#upload-image :input[name='description']").each(function() {
274 registerInputTextareaSwap(this, text, "description", true, false);
277 $("#upload-image label").hide();
278 getTranslation("WebInterface.DefaultText.CreateAlbum.Name", function(text) {
279 $("#create-album input[name='name']").each(function() {
280 registerInputTextareaSwap(this, text, "name", false, true);
283 getTranslation("WebInterface.DefaultText.CreateAlbum.Description", function(text) {
284 $("#create-album input[name='description']").each(function() {
285 registerInputTextareaSwap(this, text, "description", true, true);
288 $("#create-album label").hide();
289 getTranslation("WebInterface.DefaultText.EditAlbum.Title", function(text) {
290 $("#edit-album input[name='title']").each(function() {
291 registerInputTextareaSwap(this, text, "title", false, true);
294 getTranslation("WebInterface.DefaultText.EditAlbum.Description", function(text) {
295 $("#edit-album :input[name='description']").each(function() {
296 registerInputTextareaSwap(this, text, "description", true, false);
299 $("#edit-album label").hide();
301 /* hide non-js image move buttons. */
302 $(".move-buttons").hide();
304 hideAndShowBlock("div.edit-album", ".show-edit-album", ".hide-edit-album");
305 hideAndShowBlock("div.create-album", ".show-create-album", ".hide-create-album");
306 hideAndShowBlock("div.upload-image", ".show-upload-image", ".hide-upload-image");
307 hideAndShowBlock("div.delete-album", ".show-delete-album", ".hide-delete-album");
315 <h1 class="backlink"><%= Page.ImageBrowser.Album.Title|l10n|replace needle='{album}' replacementKey=album.title|html></h1>
317 <div class="backlinks">
318 <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
319 <div class="separator">></div>
320 <%foreach album.backlinks backlink backlinks>
321 <div class="backlink">
322 <a href="<% backlink.target|html>"><% backlink.name|html></a>
324 <%if ! backlinks.last>
325 <div class="separator">></div>
330 <p id="description"><% album.description|parse sone=album.sone></p>
332 <%if album.sone.local>
333 <div class="show-edit-album hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Album.Edit.Title|l10n|html></a></div>
334 <div class="hide-edit-album hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Album.Edit.Title|l10n|html></a></div>
335 <div class="edit-album">
336 <h2><%= Page.ImageBrowser.Album.Edit.Title|l10n|html></h2>
338 <form id="edit-album" action="editAlbum.html" method="post">
339 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
340 <input type="hidden" name="album" value="<%album.id|html>" />
342 <%if ! album.images.empty>
344 <label for="album-image"><%= Page.ImageBrowser.Album.Label.AlbumImage|l10n|html></label>
345 <select name="album-image">
346 <option disabled="disabled"><%= Page.ImageBrowser.Album.AlbumImage.Choose|l10n|html></option>
347 <%foreach album.images image>
348 <option value="<% image.id|html>"<%if album.albumImage.id|match key=image.id> selected="selected"<%/if>><% image.title|html></option>
354 <label for="title"><%= Page.ImageBrowser.Album.Label.Title|l10n|html></label>
355 <input type="text" name="title" value="<%album.title|html>" />
358 <label for="description"><%= Page.ImageBrowser.Album.Label.Description|l10n|html></label>
359 <textarea name="description"><%album.description|html></textarea>
361 <button type="submit"><%= Page.ImageBrowser.Album.Button.Save|l10n|html></button>
366 <%include include/browseAlbums.html albums=album.albums>
368 <%if album.sone.local>
369 <div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>
370 <div class="hide-create-album hidden toggle-link"><a class="small-link">« <%= View.CreateAlbum.Title|l10n|html></a></div>
371 <div class="create-album">
372 <%include include/createAlbum.html>
376 <%foreach album.images image>
377 <%first><h2><%= Page.ImageBrowser.Header.Images|l10n|html></h2><%/first>
378 <%if loop.count|mod divisor=3><div class="image-row"><%/if>
379 <div id="image-<% image.id|html>" class="image">
380 <div class="image-id hidden"><% image.id|html></div>
381 <div class="image-container">
382 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width=250 max-height=250 mode=enlarge title==image.title></a>
384 <div class="show-data">
385 <div class="image-title"><% image.title|html></div>
386 <div class="image-description"><% image.description|parse sone=image.sone></div>
388 <%if album.sone.local>
389 <form class="edit-image" action="editImage.html" method="post">
390 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
391 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
392 <input type="hidden" name="image" value="<%image.id|html>" />
394 <div class="move-buttons">
395 <button <%first>class="hidden" <%/first>type="submit" name="moveLeft" value="true"><%= Page.ImageBrowser.Image.Button.MoveLeft|l10n|html></button>
396 <button <%last>class="hidden" <%/last>type="submit" name="moveRight" value="true"><%= Page.ImageBrowser.Image.Button.MoveRight|l10n|html></button>
399 <div class="edit-data hidden">
401 <input type="text" name="title" value="<%image.title|html>" />
404 <textarea name="description"><%image.description|html></textarea>
407 <button <%first>class="hidden" <%/first>type="submit" name="moveLeft" value="true"><%= Page.ImageBrowser.Image.Button.MoveLeft|l10n|html></button>
408 <button type="submit" name="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
409 <button <%last>class="hidden" <%/last>type="submit" name="moveRight" value="true"><%= Page.ImageBrowser.Image.Button.MoveRight|l10n|html></button>
415 <%= false|store key=endRow>
416 <%if loop.count|mod divisor=3 offset=1><%= true|store key=endRow><%/if>
417 <%last><%= true|store key=endRow><%/last>
418 <%if endRow></div><%/if>
421 <%if album.sone.local>
422 <div class="show-upload-image hidden toggle-link"><a class="small-link">» <%= View.UploadImage.Title|l10n|html></a></div>
423 <div class="hide-upload-image hidden toggle-link"><a class="small-link">« <%= View.UploadImage.Title|l10n|html></a></div>
424 <div class="upload-image">
425 <%include include/uploadImage.html>
429 <div class="show-delete-album hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
430 <div class="hide-delete-album hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
431 <div class="delete-album">
432 <form id="delete-album" action="deleteAlbum.html" method="get">
433 <input type="hidden" name="album" value="<%album.id|html>" />
434 <button type="submit"><%= Page.ImageBrowser.Album.Button.Delete|l10n|html></button>
443 <%elseif imageRequested>
445 <h1 class="backlink"><%image.title|html></h1>
447 <div class="backlinks">
448 <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
449 <div class="separator">></div>
450 <%foreach image.album.backlinks backlink backlinks>
451 <div class="backlink">
452 <a href="<% backlink.target|html>"><% backlink.name|html></a>
454 <%if ! backlinks.last>
455 <div class="separator">></div>
458 <%ifnull !image.previous><div class="backlink"><a href="imageBrowser.html?image=<%image.previous.id|html>">« <%image.previous.title|html></a></div><%/if>
459 <%ifnull !image.next><div class="backlink"><a href="imageBrowser.html?image=<%image.next.id|html>">» <%image.next.title|html></a></div><%/if>
466 <%if image.sone.local>
467 <script language="javascript">
469 getTranslation("WebInterface.DefaultText.EditImage.Title", function(text) {
470 $("#edit-image input[name='title']").each(function() {
471 registerInputTextareaSwap(this, text, "title", false, true);
474 getTranslation("WebInterface.DefaultText.EditImage.Description", function(text) {
475 $("#edit-image :input[name='description']").each(function() {
476 registerInputTextareaSwap(this, text, "description", true, false);
479 $("#edit-image label").hide();
481 hideAndShowBlock(".edit-image", ".show-edit-image", ".hide-edit-image");
482 hideAndShowBlock(".delete-image", ".show-delete-image", ".hide-delete-image");
487 <div class="single-image">
489 <a href="/<%image.key|html>"><% image|image-link max-width=640 max-height=480></a>
491 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width=640 max-height=480></a>
495 <p class="parsed"><%image.description|parse sone=image.sone></p>
497 <%if image.sone.local>
499 <div class="show-edit-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
500 <div class="hide-edit-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
501 <div class="edit-image">
502 <h2><%= Page.ImageBrowser.Image.Edit.Title|l10n|html></h2>
504 <form id="edit-image" action="editImage.html" method="post">
505 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
506 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
507 <input type="hidden" name="image" value="<%image.id|html>" />
510 <label for="title"><%= Page.ImageBrowser.Image.Title.Label|l10n|html></label>
511 <input type="text" name="title" value="<%image.title|html>" />
514 <label for="description"><%= Page.ImageBrowser.Image.Description.Label|l10n|html></label>
515 <textarea name="description"><%image.description|html></textarea>
518 <button type="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
523 <div class="show-delete-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
524 <div class="hide-delete-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
525 <div class="delete-image">
526 <h2><%= Page.ImageBrowser.Image.Delete.Title|l10n|html></h2>
528 <form id="delete-image" action="deleteImage.html" method="get">
529 <input type="hidden" name="image" value="<%image.id|html>" />
530 <button type="submit"><%= Page.ImageBrowser.Image.Button.Delete|l10n|html></button>
538 <%elseif soneRequested>
541 <script language="javascript">
543 getTranslation("WebInterface.DefaultText.CreateAlbum.Name", function(text) {
544 $("#create-album input[name='name']").each(function() {
545 registerInputTextareaSwap(this, text, "name", false, true);
548 getTranslation("WebInterface.DefaultText.CreateAlbum.Description", function(text) {
549 $("#create-album input[name='description']").each(function() {
550 registerInputTextareaSwap(this, text, "description", true, true);
553 $("#create-album label").hide();
555 /* hide non-js move buttons. */
556 $(".move-buttons").hide();
558 hideAndShowBlock(".create-album", ".show-create-album", ".hide-create-album");
567 <p><%= Page.ImageBrowser.Sone.Error.NotFound.Text|l10n|html></p>
571 <h1><%= Page.ImageBrowser.Sone.Title|l10n|replace needle='{sone}' replacementKey=sone.niceName|html></h1>
573 <div class="backlinks">
574 <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
575 <div class="separator">></div>
576 <div class="backlink"><a href="imageBrowser.html?sone=<%sone.id|html>"><%sone.niceName|html></a></div>
579 <%include include/browseAlbums.html albums=sone.albums>
582 <div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>
583 <div class="hide-create-album hidden toggle-link"><a class="small-link">« <%= View.CreateAlbum.Title|l10n|html></a></div>
584 <div class="create-album">
585 <%include include/createAlbum.html>
591 <%elseif galleryRequested>
593 <%foreach albums album>
594 <%first><h2><%= Page.ImageBrowser.Header.Albums|l10n|html></h2><%/first>
595 <%if loop.count|mod divisor=3><div class="album-row"><%/if>
596 <div id="album-<% album.id|html>" class="album">
597 <div class="album-id hidden"><% album.id|html></div>
598 <div class="album-container">
599 <a href="imageBrowser.html?album=<% album.id|html>" title="<% album.title|html>">
600 <%ifnull album.albumImage>
601 <img src="images/unknown-image-0.png" width="333" height="250" alt="<% album.title|html> (<%album.sone.niceName|html>)" title="<% album.title|html> (<%album.sone.niceName|html>)" style="position: relative; top: 0px; left: -41px;" />
603 <% album.albumImage|image-link max-width=250 max-height=250 mode=enlarge title==album.title>
607 <div class="show-data">
608 <div class="album-sone"><a href="imageBrowser.html?sone=<%album.sone.id|html>"><%album.sone.niceName|html></a></div>
609 <div class="album-title"><% album.title|html> (<%= View.Sone.Stats.Images|l10n 0=album.images.size>)</div>
610 <div class="album-description"><% album.description|parse sone=album.sone></div>
613 <%= false|store key=endRow>
614 <%if loop.count|mod divisor=3 offset=1><%= true|store key=endRow><%/if>
615 <%last><%= true|store key=endRow><%/last>
616 <%if endRow></div><%/if>
621 <%include include/tail.html>