diff --git a/images/iconic.svg b/images/iconic.svg index 2af18c55..75723894 100644 --- a/images/iconic.svg +++ b/images/iconic.svg @@ -324,6 +324,20 @@ + + + + diff --git a/scripts/main/album.js b/scripts/main/album.js index cfba7a51..4489a5e5 100644 --- a/scripts/main/album.js +++ b/scripts/main/album.js @@ -483,6 +483,28 @@ album.setDescription = function (albumID) { }); }; +album.toggleCover = function (photoID) { + if (!photoID) return false; + + album.json.cover_id = album.json.cover_id === photoID ? "" : photoID; + + let params = { + albumID: album.json.id, + photoID: album.json.cover_id, + }; + + api.post("Album::setCover", params, function (data) { + if (data !== true) { + lychee.error(null, params, data); + } else { + view.album.content.cover(photoID); + if (!album.getParent()) { + albums.refresh(); + } + } + }); +}; + album.setLicense = function (albumID) { const callback = function () { $("select#license").val(album.json.license === "" ? "none" : album.json.license); diff --git a/scripts/main/albums.js b/scripts/main/albums.js index 79936a7d..e33ed709 100644 --- a/scripts/main/albums.js +++ b/scripts/main/albums.js @@ -80,81 +80,107 @@ albums.load = function () { albums.parse = function (album) { let i; - for (i = 0; i < 3; i++) { - if (!album.thumbs[i]) { - album.thumbs[i] = album.password === "1" ? "img/password.svg" : "img/no_images.svg"; + if (lychee.api_V2) { + if (!album.thumb) { + album.thumb = {}; + album.thumb.id = ""; + album.thumb.thumb = album.password === "1" ? "img/password.svg" : "img/no_images.svg"; + album.thumb.type = ""; + album.thumb.thumb2x = ""; + } + } else { + for (i = 0; i < 3; i++) { + if (!album.thumbs[i]) { + album.thumbs[i] = album.password === "1" ? "img/password.svg" : "img/no_images.svg"; + } } } }; // TODO: REFACTOR THIS albums._createSmartAlbums = function (data) { - if (data.unsorted) { - data.unsorted = { - id: "unsorted", - title: lychee.locale["UNSORTED"], - // sysdate: data.unsorted.num + " " + lychee.locale["NUM_PHOTOS"], - sysdate: "", - unsorted: "1", - thumbs: data.unsorted.thumbs, - thumbs2x: data.unsorted.thumbs2x ? data.unsorted.thumbs2x : null, - types: data.unsorted.types, - }; - } - - if (data.starred) { - data.starred = { - id: "starred", - title: lychee.locale["STARRED"], - sysdate: "", - // sysdate: data.starred.num + " " + lychee.locale["NUM_PHOTOS"], - star: "1", - thumbs: data.starred.thumbs, - thumbs2x: data.starred.thumbs2x ? data.starred.thumbs2x : null, - types: data.starred.types, - }; - } + if (!lychee.api_V2) { + if (data.unsorted) { + data.unsorted = { + id: "unsorted", + title: lychee.locale["UNSORTED"], + sysdate: "", + unsorted: "1", + thumbs: data.unsorted.thumbs, + thumbs2x: data.unsorted.thumbs2x ? data.unsorted.thumbs2x : null, + types: data.unsorted.types, + }; + } - if (data.public) { - data.public = { - id: "public", - title: lychee.locale["PUBLIC"], - sysdate: "", - // sysdate: data.public.num + " " + lychee.locale["NUM_PHOTOS"], - public: "1", - thumbs: data.public.thumbs, - thumbs2x: data.public.thumbs2x ? data.public.thumbs2x : null, - visible: "0", - types: data.public.types, - }; - } + if (data.starred) { + data.starred = { + id: "starred", + title: lychee.locale["STARRED"], + sysdate: "", + star: "1", + thumbs: data.starred.thumbs, + thumbs2x: data.starred.thumbs2x ? data.starred.thumbs2x : null, + types: data.starred.types, + }; + } - if (data.recent) { - data.recent = { - id: "recent", - title: lychee.locale["RECENT"], - sysdate: "", - // sysdate: data.recent.num + " " + lychee.locale["NUM_PHOTOS"], - recent: "1", - thumbs: data.recent.thumbs, - thumbs2x: data.recent.thumbs2x ? data.recent.thumbs2x : null, - types: data.recent.types, - }; - } + if (data.public) { + data.public = { + id: "public", + title: lychee.locale["PUBLIC"], + sysdate: "", + public: "1", + thumbs: data.public.thumbs, + thumbs2x: data.public.thumbs2x ? data.public.thumbs2x : null, + visible: "0", + types: data.public.types, + }; + } - Object.entries(data).forEach(([albumName, albumData]) => { - if (albumData["tag_album"] === "1") { - data[albumName] = { - id: albumData.id, - title: albumName, + if (data.recent) { + data.recent = { + id: "recent", + title: lychee.locale["RECENT"], sysdate: "", - tag_album: "1", - thumbs: albumData.thumbs, - thumbs2x: albumData.thumbs2x ? albumData.thumbs2x : null, - types: albumData.types, + recent: "1", + thumbs: data.recent.thumbs, + thumbs2x: data.recent.thumbs2x ? data.recent.thumbs2x : null, + types: data.recent.types, }; } - }); + } else { + if (data.unsorted) { + data.unsorted.title = lychee.locale["UNSORTED"]; + data.unsorted.sysdate = ""; + data.unsorted.unsorted = "1"; + } + + if (data.starred) { + data.starred.title = lychee.locale["STARRED"]; + data.starred.sysdate = ""; + data.starred.star = "1"; + } + + if (data.public) { + data.public.title = lychee.locale["PUBLIC"]; + data.public.sysdate = ""; + data.public.public = "1"; + data.public.visible = "0"; + } + + if (data.recent) { + data.recent.title = lychee.locale["RECENT"]; + data.recent.sysdate = ""; + data.recent.recent = "1"; + } + + Object.entries(data).forEach(([albumName, albumData]) => { + if (albumData["tag_album"] === "1") { + data[albumName].sysdate = ""; + data[albumName].tag_album = "1"; + } + }); + } }; albums.isShared = function (albumID) { diff --git a/scripts/main/build.js b/scripts/main/build.js index f5b7fcbd..29a44a5b 100644 --- a/scripts/main/build.js +++ b/scripts/main/build.js @@ -32,10 +32,22 @@ build.multiselect = function (top, left) { return lychee.html`
`; }; -build.getAlbumThumb = function (data, i) { - let isVideo = data.types[i] && data.types[i].indexOf("video") > -1; - let isRaw = data.types[i] && data.types[i].indexOf("raw") > -1; - let thumb = data.thumbs[i]; +// two additional images that are barely visible seems a bit overkill - use same image 3 times +// if this simplification comes to pass data.types, data.thumbs and data.thumbs2x no longer need to be arrays +build.getAlbumThumb = function (data) { + let isVideo; + let isRaw; + let thumb; + + if (lychee.api_V2) { + isVideo = data.thumb.type && data.thumb.type.indexOf("video") > -1; + isRaw = data.thumb.type && data.thumb.type.indexOf("raw") > -1; + thumb = data.thumb.thumb; + } else { + isVideo = data.types[0] && data.type.indexOf("video") > -1; + isRaw = data.types[0] && data.types[0].indexOf("raw") > -1; + thumb = data.thumbs[0]; + } var thumb2x = ""; if (thumb === "uploads/thumb/" && isVideo) { @@ -45,13 +57,11 @@ build.getAlbumThumb = function (data, i) { return `Photo thumbnail`; } - if (data.thumbs2x) { - if (data.thumbs2x[i]) { - thumb2x = data.thumbs2x[i]; - } + if (lychee.api_V2) { + thumb2x = data.thumb.thumb2x; } else { // Fallback code for Lychee v3 - var { path: thumb2x, isPhoto: isPhoto } = lychee.retinize(data.thumbs[i]); + var { path: thumb2x, isPhoto: isPhoto } = lychee.retinize(data.thumbs[0]); if (!isPhoto) { thumb2x = ""; } @@ -66,6 +76,7 @@ build.album = function (data, disabled = false) { let html = ""; let date_stamp = data.sysdate; let sortingAlbums = []; + let isCover = (album.json && album.json.cover_id && data.thumb.id === album.json.cover_id); // In the special case of take date sorting use the take stamps as title if (lychee.sortingAlbums !== "" && data.min_takestamp && data.max_takestamp) { @@ -86,9 +97,9 @@ build.album = function (data, disabled = false) { data-id='${data.id}' data-nsfw='${data.nsfw && data.nsfw === "1" ? `1` : `0`}' data-tabindex='${tabindex.get_next_tab_index()}'> - ${build.getAlbumThumb(data, 2)} - ${build.getAlbumThumb(data, 1)} - ${build.getAlbumThumb(data, 0)} + ${build.getAlbumThumb(data)} + ${build.getAlbumThumb(data)} + ${build.getAlbumThumb(data)}

$${data.title}

$${date_stamp} @@ -100,13 +111,14 @@ build.album = function (data, disabled = false) {
${build.iconic("warning")} ${build.iconic("star")} + ${build.iconic("clock")} ${build.iconic("eye")} ${build.iconic("list")} - ${build.iconic("clock")} ${build.iconic("lock-locked")} ${build.iconic("tag")} + ${build.iconic("folder-cover")}
`; } @@ -127,6 +139,7 @@ build.photo = function (data, disabled = false) { let html = ""; let thumbnail = ""; var thumb2x = ""; + let isCover = (data.id === album.json.cover_id); let isVideo = data.type && data.type.indexOf("video") > -1; let isRaw = data.type && data.type.indexOf("raw") > -1; @@ -226,8 +239,9 @@ build.photo = function (data, disabled = false) { if (album.isUploadable()) { html += lychee.html`
- ${build.iconic("star")} - ${build.iconic("eye")} + ${build.iconic("star")} + ${build.iconic("eye")} + ${build.iconic("folder-cover")}
`; } diff --git a/scripts/main/contextMenu.js b/scripts/main/contextMenu.js index 3e03b9da..eedb536d 100644 --- a/scripts/main/contextMenu.js +++ b/scripts/main/contextMenu.js @@ -63,6 +63,19 @@ contextMenu.album = function (albumID, e) { { title: build.iconic("cloud-download") + lychee.locale["DOWNLOAD"], fn: () => album.getArchive([albumID]) }, ]; + if (album.json) { + // not top level + let myalbum = album.getSubByID(albumID); + if (myalbum.thumb.id) { + let coverActive = (myalbum.thumb.id === album.json.cover_id); + // prepend context menu item + items.unshift({ + title: build.iconic("folder-cover", coverActive ? "active" : "") + lychee.locale[coverActive ? "REMOVE_COVER" : "SET_COVER"], + fn: () => album.toggleCover(myalbum.thumb.id), + }); + } + } + $('.album[data-id="' + albumID + '"]').addClass("active"); basicContext.show(items, e.originalEvent, contextMenu.close); @@ -209,13 +222,16 @@ contextMenu.albumTitle = function (albumID, e) { }; contextMenu.photo = function (photoID, e) { - // Notice for 'Move': - // fn must call basicContext.close() first, - // in order to keep the selection + let coverActive = (photoID === album.json.cover_id); let items = [ { title: build.iconic("star") + lychee.locale["STAR"], fn: () => photo.setStar([photoID]) }, { title: build.iconic("tag") + lychee.locale["TAGS"], fn: () => photo.editTags([photoID]) }, + // for future work, use a list of all the ancestors. + { + title: build.iconic("folder-cover", coverActive ? "active" : "") + lychee.locale[coverActive ? "REMOVE_COVER" : "SET_COVER"], + fn: () => album.toggleCover(photoID), + }, {}, { title: build.iconic("pencil") + lychee.locale["RENAME"], fn: () => photo.setTitle([photoID]) }, { @@ -225,6 +241,9 @@ contextMenu.photo = function (photoID, e) { contextMenu.move([photoID], e, photo.copyTo, "UNSORTED"); }, }, + // Notice for 'Move': + // fn must call basicContext.close() first, + // in order to keep the selection { title: build.iconic("folder") + lychee.locale["MOVE"], fn: () => { diff --git a/scripts/main/view.js b/scripts/main/view.js index b481caac..a035c526 100644 --- a/scripts/main/view.js +++ b/scripts/main/view.js @@ -276,6 +276,25 @@ view.album = { else $badge.removeClass("badge--visible badge--hidden"); }, + cover: function (photoID) { + $('.album .icn-cover').removeClass("badge--cover"); + $('.photo .icn-cover').removeClass("badge--cover"); + + if (album.json.cover_id === photoID) { + let badge = $('.photo[data-id="' + photoID + '"] .icn-cover'); + if (badge.length > 0) { + badge.addClass("badge--cover"); + } else { + $.each(album.json.albums, function() { + if (this.thumb.id === photoID) { + $('.album[data-id="' + this.id + '"] .icn-cover').addClass("badge--cover"); + return false; + } + }); + } + } + }, + delete: function (photoID, justify = false) { $('.photo[data-id="' + photoID + '"]') .css("opacity", 0) diff --git a/styles/main/_basicContext.extended.scss b/styles/main/_basicContext.extended.scss index d06b2dc3..372edda1 100644 --- a/styles/main/_basicContext.extended.scss +++ b/styles/main/_basicContext.extended.scss @@ -20,6 +20,10 @@ fill: white(1); } + &__data .iconic.active { + fill: $colorOrange; + } + &__data .iconic.ionicons { margin: 0 8px -2px 0; width: 14px; diff --git a/styles/main/_content.scss b/styles/main/_content.scss index b5308ea9..fe3ff794 100644 --- a/styles/main/_content.scss +++ b/styles/main/_content.scss @@ -234,6 +234,10 @@ &--hidden { background: $colorOrange; } + &--cover { + display: "inline-block"; + background: $colorOrange; + } &--star { display: inline-block; background: $colorYellow;