Skip to content
This repository has been archived by the owner on Dec 25, 2023. It is now read-only.

Fix various GUI issues #349

Merged
merged 3 commits into from
Nov 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions scripts/main/album.js
Original file line number Diff line number Diff line change
Expand Up @@ -1535,9 +1535,24 @@ album.apply_nsfw_filter = function () {
* - the method returns `true` for regular albums if and only if the album is
* owned by the currently authenticated user.
*
* Note, for the time being this method contains a work-around in case
* no album is loaded, but the root view is visible.
* Currently, this is necessary, because this method is (erroneously) called
* for the root view as well.
* In order to determine whether the work-around for the root view needs to
* be applied, this method checks if the root view is visible based on the
* visibility of the corresponding headers.
* Hence, the caller must ensure that the appropriate header is set first
* in order to obtain a correct result from this method.
*
* @returns {boolean}
*/
album.isUploadable = function () {
// Work-around in case this method is called for the root view
if (visible.albums()) {
return lychee.rights.is_admin || (lychee.user !== null && !lychee.publicMode && lychee.rights.may_upload);
ildyria marked this conversation as resolved.
Show resolved Hide resolved
}

// If no album is loaded, nobody (not even the admin) can upload photos.
// We must check this first, before we test for the admin short-cut.
//
Expand Down
20 changes: 20 additions & 0 deletions scripts/main/albums.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ const albums = {
*/
albums.load = function () {
const showRootAlbum = function () {
// DO NOT change the order of `header.setMode` and `view.albums.init`.
// The latter relies on the header being set correctly.
//
// `view.albums.init` builds the HTML of the albums view (note the
// plural-s).
// Internally, this exploits code for regular albums which in
// turn calls `album.isUploadabe` (note the missing plural-s) to
// check whether the current album supports drag-&-drop.
// In order to return the correct value `album.isUploadabe` resorts
// to a hack: if no (regular) album is loaded `album.isUploadabe`
// normally returns `false` except the root album is visible.
// In that case `album.isUploadabe` returns a "fake" `true`.
// However, in order to do so `album.isUploadabe` needs to check
// whether the root album is visible which is determined by the
// visibility of the corresponding header.
// That is why the header needs to be set first.
//
// However, the actual bug is to call `album.isUploadable` for the
// root view.
// TODO: Fix the bug described above.
header.setMode("albums");
view.albums.init();
lychee.animate(lychee.content, "contentZoomIn");
Expand Down
31 changes: 31 additions & 0 deletions scripts/main/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,37 @@ build.album = function (data, disabled = false) {
const formattedCreationTs = lychee.locale.printMonthYear(data.created_at);
const formattedMinTs = lychee.locale.printMonthYear(data.min_taken_at);
const formattedMaxTs = lychee.locale.printMonthYear(data.max_taken_at);
// The condition below is faulty wrt. to two issues:
//
// a) The condition only checks whether the owning/current album is
// uploadable (aka "editable"), but it does not check whether the
// album at hand whose icon is built is editable.
// But this is of similar importance.
// Currently, we only check whether the album at hand is a smart
// album or tag album which are always considered non-editable.
// But this is only half of the story.
// For example, a regular album might still be non-editable, if the
// current user is not the owner of that album.
// b) This method is not only called if the owning/current album is a
// proper album, but also for the root view.
// However, `album.isUploadable` should not be called for the root
// view.
//
// Moreover, we have to distinguish between "drag" and "drop".
// Doing so would also solve the problems above:
//
// - "Drag": If the current child album at hand can be dragged (away)
// is mostly determined by the user's rights on the parent album.
// Instead of (erroneously) using `album.isUploadable()` for that
// (even for the root view), the "right to drag" should be passed to
// this method as a parameter very much like `disabled` such that this
// method can be used for both regular albums and the root view.
// - "Drop": If something (e.g. a photo) can be dropped onto the child
// album at hand is independent of the user's rights on the containing
// album.
// Whether the child album supports the drop event depends on the type
// of the album (i.e. it must not be a smart or tag album), but also
// on the ownership of the album.
const disableDragDrop = !album.isUploadable() || disabled || album.isSmartID(data.id) || data.is_tag_album;
let subtitle = formattedCreationTs;

Expand Down
10 changes: 9 additions & 1 deletion scripts/main/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,15 @@ header.setMode = function (mode) {
tabindex.makeFocusable(e);
}

if (album.json && album.json.hasOwnProperty("is_share_button_visible") && !album.json.is_share_button_visible) {
if (
album.json &&
album.json.is_share_button_visible === false &&
// The owner of an album (or the admin) shall always see
// the share button and be unaffected by the settings of
// the album
(lychee.user === null || lychee.user.username !== album.json.owner_name) &&
!lychee.rights.is_admin
) {
const e = $("#button_share_album");
e.hide();
tabindex.makeUnfocusable(e);
Expand Down
18 changes: 18 additions & 0 deletions scripts/main/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,24 @@ $(document).ready(function () {
},
false
)
// In the long run, the "drop" event should not be defined on the
// global document element, but on the `DIV` which corresponds to the
// view onto which something is dropped.
// This would also avoid this highly fragile condition below.
// For example, in order to avoid that a photo unintentionally ends
// up in the root album when someone drops a photo while the
// setting screen is opened, we check for `!visible.config()`.
// This would simply not be necessary, if the drop event was directly
// defined on the albums view where it belongs.
// The conditions whether a user is allowed to upload to the root
// album (cp. `visible.albums()` below) or to a regular album
// (cp. `visible.album()` below) are slightly different.
// Nonetheless, we only have a single method `album.isUploadable`
// which tries to cover both cases and is prone to fail in certain
// corner cases.
// If the drop event was defined on the DIV for the root view and on
// the DIV for an album view, the whole problem would not exist.
// TODO: Fix that
.on(
"drop",
/** @param {jQuery.Event} e */ function (e) {
Expand Down
4 changes: 2 additions & 2 deletions scripts/main/photo.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ photo.setProtectionPolicy = function (photoID) {
// users?
formElements.requires_link.checked = false;
formElements.is_downloadable.checked = album.json.is_downloadable;
formElements.is_share_button_visible = album.json.is_share_button_visible;
formElements.is_share_button_visible.checked = album.json.is_share_button_visible;
formElements.has_password.checked = album.json.has_password;
}
basicModal.hideActionButton();
Expand All @@ -685,7 +685,7 @@ photo.setProtectionPolicy = function (photoID) {
formElements.grants_full_photo.checked = lychee.full_photo;
formElements.requires_link.checked = lychee.public_photos_hidden;
formElements.is_downloadable.checked = lychee.downloadable;
formElements.is_share_button_visible = lychee.share_button_visible;
formElements.is_share_button_visible.checked = lychee.share_button_visible;
formElements.has_password.checked = false;
}
};
Expand Down