Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Highlighted Categories (aka like button) #1173

Draft
wants to merge 25 commits into
base: dev
Choose a base branch
from

Conversation

psilabs-dev
Copy link
Contributor

@psilabs-dev psilabs-dev commented Jan 25, 2025

Issue #1129

Completed:

  • backend
  • category settings UI
  • reader UI
  • index/datatables UI
  • integration testing
  • i18n
  • documentation
  • permissions/no-fun mode, etc.

Ongoing implementation of the like button backend and frontend logic. To strive for a neutral term, "highlight" is tentatively used (English is hard...) but everything so far, naming and logic, can be changed.

A static category is "highlighted" if archives in the index and reader page can be added and removed from this category via a 1-click icon toggle. Only one category may be highlighted at any time. The assignment and un-assignment of a highlight may be done via the API or on the browser via the config/categories page. If a highlighted category is deleted, the highlight will point to an empty string.

Additionally, all new installs of LRR will create a highlighted category called "Favorites". In such cases where the category corresponds to liked archives, the toggle is equivalent to a like button.

As for the UI I am thinking of doing something like this (but move Highlight row below "Delete Category"):

Screen Shot 2025-01-24 at 17 47 39 PM

Expanding it shows a list of static categories + "No Category". Choosing a static category moves the highlight to that category. If a highlight is assigned, "No Category" will instead be replaced with the name of the highlighted category.


There is quite a bit left to do, but I think now is a good time to checkpoint. There is settling on a UI, and icons to replace the placeholder toggle icons. If this backend is approved, we can move forward with API documentation.

This is also a request for feedback/available help, as I haven't decided on the design of the frontend, and I am not familiar with *cough* basically any frontend. Now these are things I can eventually learn and come up with something, but I'm expecting this will take a while.

Copy link
Owner

@Difegue Difegue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks overall good, sweet and simple. I don't have much to complain about.

I'm a bit iffy on the "highlighted" term, but I don't really have a better one coming to mind at the moment.

@Difegue
Copy link
Owner

Difegue commented Jan 27, 2025

Regarding UI, I'd just add a checkmark below "pin this category" that makes the selected cat the highlighted one. Ofc, you can only do this with static categories.

In the index, i think you can add the "like" button to the javascript-created thumbnails fairly easily, that's in a dedicated function.
For compact mode, I would add a button inline to the left of the title, like how we used to do for the download/edit metadata buttons before the context menu came around. (that was a while ago...)

You need however to know the "initial" state of the like button when the index loads (aka whether an ID is in the highlighted category or not).
We could either do this purely with API calls and JS, or do some search engine work to easily surface that a given archive belongs or not to the highlighted category. (Get the ID list of the highlighted category, then when iterating over the final search results, check whether or not your IDs are in there)

@psilabs-dev
Copy link
Contributor Author

Yeah I'm not too sure about the naming either, we can sit on that for a while, see if anyone has thoughts, or ask an AI for ideas. I wouldn't mind if we just gave it a Japanese phrase either.

I'm sure the front end work isn't difficult, I just need to spend some good time learning the basic principles and HTML/CSS/JS structure/DSL and speaking the frontend language. Right now I don't know what I don't know or what I should know, or if a term is used in a informal or technical setting.

@Difegue
Copy link
Owner

Difegue commented Jan 31, 2025

Fair enough - Maybe someone will come up with a better name by the time we wrap up the UI!
I don't know if there's an equivalent japanese term in Pixiv or such people would be familar with.

@psilabs-dev
Copy link
Contributor Author

psilabs-dev commented Feb 10, 2025

Ok I have a first draft down. I'm going to test this on my server for a bit and clean up the code (also I really want to start using it lol).

A lot of sync-related bugs were squashed, but I'm sure there are still more.. I'll see how it works in prod-like environments. Also added some python API integration tests on my side. Didn't do much code standardization, I figure more changes will be made.

I've decided to go with the name "bookmark" for the frontend, and "bookmark link" for the backend. The word highlight is too confusing, and this backend functionality is a conceptually abstract; most websites don't allow you to flexibly change where the bookmark points to. It's like youtube letting you choose which playlist the like button saves videos to. A readonly user would never see the "bookmark link" terminology; they would only interact with the bookmark button.

(We could also go for "like", "star", "love", "save", and replace "link" with "reference" or "connect". I realized midway the repo uses fontawesome which supplies icons, so we don't need to cook up in-house icons. However, "save" and "star" are overloaded terms, and "like/love" generally implies the notion of a "dislike". Another idea is "quick save" or something along the lines of that...)

Now, for functionality: the bookmark icon/button is implemented in three locations mainly: categories, reader, and index, with helpers in LRR and server. Generally, the bookmark category ID will be fetched on initialization and put in local storage.

Categories page: Enables changing which category the bookmark toggle points to, and whether the bookmark toggle should exist.

Reader: adds a bookmark icon to the absolute-left divs. This icon appears only when the bookmark is configured. The icon toggles the membership of an archive to that category, and is synced with the archive metadata settings, i.e. if you unbookmark the archive via the icon, it will remove the bookmark category from the metadata page, and vice versa.

Index page: adds a bookmark icon to the bottom left of each image thumbnail. For every archive, their icons are synced; e.g., when the same archive appears in carousel and in datatables. Also, these icons are synced with the context menu categories section. If you unbookmark/bookmark an archive through any channel, all other indications will be updated. Also, this bookmark icon will show only when the bookmark is configured. I'm not sure about the way we check if an archive is bookmarked or not, I don't want to make many api calls though

Index page (compact): prepends a checkbox col before the title col. Likewise this checkbox column is synced with all other channels. When the bookmark is not configured, this column will display off and be disabled from toggling. Maybe we'd want to disable this column instead, but I haven't gotten that to work. I still don't really understand the datatables-related code.

@@ -48,7 +48,7 @@

</head>

<body>
<body data-user-logged="[% userlogged %]">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since userlogged is a server-side variable, it's not exposed to the client so the client doesn't really know whether the user is logged in.

Toggleability of bookmark icon should be enabled only if the user is logged in (i.e. user has "write" permissions). In readonly mode (i.e. user viewing site with no-fun-mode disabled), bookmark icons and checkboxes should not be toggleable. This decision requires exposing the logged-in status to the client somewhat, hence the use of html data attributes here

</p>

<!-- i18n client-side access -->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to put i18n translations that are dynamically required by clients in this central location and made accessible by common.js, to avoid making script initializations in every tt2 file that corresponds to a js file that dynamically generates elts with translatable text

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid making script initializations in every tt2 file that corresponds to a js file that dynamically generates elts with translatable text

How did you figure out that was what I was working on for frontend translations? 🫠
I've pushed my WIP here for reference -- 2eefd23

I'm not sure if I prefer putting it all in the footer -- It feels less clear when working on the codebase that this is where the glue for frontend TLs would end up.

Also, this requires double-declaring every string in common.js, which is going to add a lot of heft to that file.

Copy link
Owner

@Difegue Difegue Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I'm also still undecided on how to work with placeholders in localized text.. The backend didn't have this issue for obvious reason, but I need to move everything to JS template strings with ${...})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I didn't know how the i18n system worked initially, when I found it was generated by the server I figured this problem would come up sooner or later 😅

Yeah I wasn't too excited about this approach either, If you're working on this part then I'll just use yours when it's implemented, then I can do away with this awkward workaround

@@ -1028,6 +1031,8 @@ msgstr "档案概览"
msgid "FullScreen"
msgstr "全屏"

msgid "Toggle Bookmark"
msgstr "切换书签"
# ------End of Reader.html.tt2------
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept the Chinese translations minimal, but alternative suggestions are welcome.

const icon = e.currentTarget;
const id = icon.id;

// TODO: Considering removing this toast
Copy link
Contributor Author

@psilabs-dev psilabs-dev Mar 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These types of toasts might be too noisy, so I wouldn't mind if we remove them, or replace with something else (same with adding/removing archives to/from categories)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants