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}' replacement=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 value=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|paginate pageSize=core.preferences.imagesPerPage page=page>
378 <h2><%= Page.ImageBrowser.Header.Images|l10n|html></h2>
379 <%include include/pagination.html pageParameter=="page">
381 <%if loop.count|mod divisor==3><div class="image-row"><%/if>
382 <div id="image-<% image.id|html>" class="image">
383 <div class="image-id hidden"><% image.id|html></div>
384 <div class="image-container">
385 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width==250 max-height==250 mode==enlarge title=image.title></a>
387 <div class="show-data">
388 <div class="image-title"><% image.title|html></div>
389 <div class="image-description"><% image.description|parse sone=image.sone></div>
391 <%if album.sone.local>
392 <form class="edit-image" action="editImage.html" method="post">
393 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
394 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
395 <input type="hidden" name="image" value="<%image.id|html>" />
397 <div class="move-buttons">
398 <button <%first>class="hidden" <%/first>type="submit" name="moveLeft" value="true"><%= Page.ImageBrowser.Image.Button.MoveLeft|l10n|html></button>
399 <button <%last>class="hidden" <%/last>type="submit" name="moveRight" value="true"><%= Page.ImageBrowser.Image.Button.MoveRight|l10n|html></button>
402 <div class="edit-data hidden">
404 <input type="text" name="title" value="<%image.title|html>" />
407 <textarea name="description"><%image.description|html></textarea>
410 <button <%first>class="hidden" <%/first>type="submit" name="moveLeft" value="true"><%= Page.ImageBrowser.Image.Button.MoveLeft|l10n|html></button>
411 <button type="submit" name="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
412 <button <%last>class="hidden" <%/last>type="submit" name="moveRight" value="true"><%= Page.ImageBrowser.Image.Button.MoveRight|l10n|html></button>
418 <%= false|store key==endRow>
419 <%if loop.count|mod divisor==3 offset==1><%= true|store key==endRow><%/if>
420 <%last><%= true|store key==endRow><%/last>
423 <%include include/pagination.html pageParameter=="page">
427 <%if album.sone.local>
428 <div class="clear show-upload-image hidden toggle-link"><a class="small-link">» <%= View.UploadImage.Title|l10n|html></a></div>
429 <div class="clear hide-upload-image hidden toggle-link"><a class="small-link">« <%= View.UploadImage.Title|l10n|html></a></div>
430 <div class="upload-image">
431 <%include include/uploadImage.html>
435 <div class="show-delete-album hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
436 <div class="hide-delete-album hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
437 <div class="delete-album">
438 <form id="delete-album" action="deleteAlbum.html" method="get">
439 <input type="hidden" name="album" value="<%album.id|html>" />
440 <button type="submit"><%= Page.ImageBrowser.Album.Button.Delete|l10n|html></button>
449 <%elseif imageRequested>
451 <h1 class="backlink"><%image.title|html></h1>
453 <div class="backlinks">
454 <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
455 <div class="separator">></div>
456 <%foreach image.album.backlinks backlink backlinks>
457 <div class="backlink">
458 <a href="<% backlink.target|html>"><% backlink.name|html></a>
460 <%if ! backlinks.last>
461 <div class="separator">></div>
464 <%ifnull !image.previous><div class="backlink"><a href="imageBrowser.html?image=<%image.previous.id|html>">« <%image.previous.title|html></a></div><%/if>
465 <%ifnull !image.next><div class="backlink"><a href="imageBrowser.html?image=<%image.next.id|html>">» <%image.next.title|html></a></div><%/if>
472 <%if image.sone.local>
473 <script language="javascript">
475 getTranslation("WebInterface.DefaultText.EditImage.Title", function(text) {
476 $("#edit-image input[name='title']").each(function() {
477 registerInputTextareaSwap(this, text, "title", false, true);
480 getTranslation("WebInterface.DefaultText.EditImage.Description", function(text) {
481 $("#edit-image :input[name='description']").each(function() {
482 registerInputTextareaSwap(this, text, "description", true, false);
485 $("#edit-image label").hide();
487 hideAndShowBlock(".edit-image", ".show-edit-image", ".hide-edit-image");
488 hideAndShowBlock(".delete-image", ".show-delete-image", ".hide-delete-image");
493 <div class="single-image">
495 <a href="/<%image.key|html>"><% image|image-link max-width==640 max-height==480></a>
497 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width==640 max-height==480></a>
501 <p class="parsed"><%image.description|parse sone=image.sone></p>
503 <%if image.sone.local>
505 <div class="show-edit-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
506 <div class="hide-edit-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
507 <div class="edit-image">
508 <h2><%= Page.ImageBrowser.Image.Edit.Title|l10n|html></h2>
510 <form id="edit-image" action="editImage.html" method="post">
511 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
512 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
513 <input type="hidden" name="image" value="<%image.id|html>" />
516 <label for="title"><%= Page.ImageBrowser.Image.Title.Label|l10n|html></label>
517 <input type="text" name="title" value="<%image.title|html>" />
520 <label for="description"><%= Page.ImageBrowser.Image.Description.Label|l10n|html></label>
521 <textarea name="description"><%image.description|html></textarea>
524 <button type="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
529 <div class="show-delete-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
530 <div class="hide-delete-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
531 <div class="delete-image">
532 <h2><%= Page.ImageBrowser.Image.Delete.Title|l10n|html></h2>
534 <form id="delete-image" action="deleteImage.html" method="get">
535 <input type="hidden" name="image" value="<%image.id|html>" />
536 <button type="submit"><%= Page.ImageBrowser.Image.Button.Delete|l10n|html></button>
544 <%elseif soneRequested>
547 <script language="javascript">
549 getTranslation("WebInterface.DefaultText.CreateAlbum.Name", function(text) {
550 $("#create-album input[name='name']").each(function() {
551 registerInputTextareaSwap(this, text, "name", false, true);
554 getTranslation("WebInterface.DefaultText.CreateAlbum.Description", function(text) {
555 $("#create-album input[name='description']").each(function() {
556 registerInputTextareaSwap(this, text, "description", true, true);
559 $("#create-album label").hide();
561 /* hide non-js move buttons. */
562 $(".move-buttons").hide();
564 hideAndShowBlock(".create-album", ".show-create-album", ".hide-create-album");
573 <p><%= Page.ImageBrowser.Sone.Error.NotFound.Text|l10n|html></p>
577 <h1><%= Page.ImageBrowser.Sone.Title|l10n|replace needle=='{sone}' replacement=sone.niceName|html></h1>
579 <div class="backlinks">
580 <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
581 <div class="separator">></div>
582 <div class="backlink"><a href="imageBrowser.html?sone=<%sone.id|html>"><%sone.niceName|html></a></div>
585 <%include include/browseAlbums.html albums=sone.albums>
588 <div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>
589 <div class="hide-create-album hidden toggle-link"><a class="small-link">« <%= View.CreateAlbum.Title|l10n|html></a></div>
590 <div class="create-album">
591 <%include include/createAlbum.html>
597 <%elseif galleryRequested>
599 <%foreach albums album|paginate pageSize=core.preferences.imagesPerPage pageParameter=request.page pagination=albumPagination>
601 <h2><%= Page.ImageBrowser.Header.Albums|l10n|html></h2>
602 <%include include/pagination.html pagination=albumPagination pageParameter=="page">
604 <%if loop.count|mod divisor==3><div class="album-row"><%/if>
605 <div id="album-<% album.id|html>" class="album">
606 <div class="album-id hidden"><% album.id|html></div>
607 <div class="album-container">
608 <a href="imageBrowser.html?album=<% album.id|html>" title="<% album.title|html>">
609 <%ifnull album.albumImage>
610 <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;" />
612 <% album.albumImage|image-link max-width==250 max-height==250 mode==enlarge title=album.title>
616 <div class="show-data">
617 <div class="album-sone"><a href="imageBrowser.html?sone=<%album.sone.id|html>"><%album.sone.niceName|html></a></div>
618 <div class="album-title"><% album.title|html> (<%= View.Sone.Stats.Images|l10n 0=album.images.size>)</div>
619 <div class="album-description"><% album.description|parse sone=album.sone></div>
622 <%= false|store key==endRow>
623 <%if loop.count|mod divisor==3 offset==1><%= true|store key==endRow><%/if>
624 <%last><%= true|store key==endRow><%/last>
629 <%include include/pagination.html pagination=albumPagination pageParameter=="page">
635 <%include include/tail.html>