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
CoverBrowser: adjustable mosaic grid #11232
Conversation
text_func = function() | ||
local nb_cols_portrait = tonumber(BookInfoManager:getSetting("nb_cols_portrait") or 3) | ||
local nb_rows_portrait = tonumber(BookInfoManager:getSetting("nb_rows_portrait") or 3) | ||
return T(_("Items per page in mosaic portrait mode: %1 x %2"), nb_cols_portrait, nb_rows_portrait) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly ×
instead of plain x
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, @poire-z okay with the new settings?
default_value = default_perpage, | ||
callback = function(touchmenu_instance) | ||
local current_value = FileChooser.perpage | ||
local default_value = FileChooser.items_per_page_default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Wondered if you forgot to add changes to filechooser - but I see items_per_page_default
is defined in Menu, which FileChooser is a subclass, so it will be found. Just saying just in case.)
table.insert (menu_items.filebrowser_settings.sub_item_table, 4, { | ||
table.insert (menu_items.filebrowser_settings.sub_item_table, 5, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Screenshot of the upper menu where we see this reordering please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order was wrong after adding "Show finished books".
left_text = _("Columns"), | ||
left_value = nb_cols_portrait, | ||
left_min = 2, | ||
left_max = 5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I argued against going up to 30 :) but may be 5 is too little ? I guess one could be happy with 8 or 10 on large devices ? There's still some limit with the font size and reability of text covers - I don't know what limit it would bring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting for @mergen3107 with big screen limits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's mostly a matter of taste in the end, but I probably wouldn't go higher than 6 or 8?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On larger screens (monitors/TVs) it could make sense, but on the flip side when more than that makes sense you might also want 4 pages at once or something.
There's possibly still the issue I mentionned at #11186 (comment):
All the things involving the variables We could let that to the user so he has to "Refresh cached book info & refresh all", but I somehow like that things happen as needed as you browse. |
Re-extracting covers on every change of the grid dimensions takes time and resources. |
I don't know, does it make sense to optimize for the edge case when you'll probably only change the setting a few times if ever? |
I don't think we have the real size it would take with 3x3, when we are in 5x4.
We also don't need larger than needed thumbnails in the db (it takes space, and cpu decoding), and cpu up/down-scaling that could slow down the display (maybe not noticable when 3x3, but probably more if 8x8).
That's what we do in Detailed list. May be a ConfirmBox when we leave the DoubleSpinWidget, asking the user if he wants to get thumbnails refreshed for the new size ? May be we would not need to change all the sizetag related code (until we get a better idea on how to handle this), if we were just marking such covers as "dirty" with something like: |
Thank you @hius07 for this new settings! Can you please allow max limit for landscpe rows to 5? Thanks! |
I can't find these settings in the Meanwhile, let me try some extremes by setting grids in the code... |
My verdict: Anything denser is merely usable, I think. |
They are in settings/bookinfo_cache.sqlite3. |
Understood! |
For recalculating the image to proper size depending on the settings - I would agree, but only if there was an option to extract all History/Favorites icons during the global cache extraction (from Plus menu in FM). Last time I asked about this the problem was that History/Favorites can containt various books. But why can't we take the list from Then, at the moment when global cache extraction is happenning, the mosaic thumbnails would be extracted once for all books in History/Favorites. Then, any new books' mosaic thumbnail would be extracted once History/Favorites is open (the way it is done now). I didn't see any worring performance hit even at 10x10 in my recent tests. |
Additionally to that:
I don't think this is a problem (for me), just my observations. (I don't know how hard it would be to calculate how much space book cover frame can afford, and the calculate where to truncate the filename with ellipsis...) |
I am soon gonna be an active proponent of |
So, then this calculation of sizes can be done upon clicking |
@hius07 , I tested it quickly, feel free to add this here if you want: #11234 (comment) (I don't know if what I did is optimal, so please give feedback) |
I'd fully expect to recompute new thumbnails when changing the grid size, FWIW. (And possibly go so far as trashing the now irrelevant ones, but, eeeeh, ;D). |
True, but we should ;p. (/s) Basically, it creates a table with two elements, but many Geom methods will actually write to the full set of four, which would incur a realloc to resize the table. Since Geoms are fairly small and ubiquitous, there's a fair chance something will attempt to write to all four along the way, and it's easy & quick to do it right ;). I'm not advocating for a full pass on the codebase, mind you, just not gratuitously breaking it when it's being done right ;p. |
In that case, what's being kept is whatever the very first extraction generated, then, right? |
Yes, and it will be kept until we build a grid with small enough cells. |
The latest commits reduces writing to sql db while grid tunng, by keeping and maintaining grid dimensions in the menu instance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status: 1 of 7 files reviewed, 14 unresolved discussions (waiting on @Frenzie, @mergen3107, @NiLuJe, and @poire-z)
frontend/ui/widget/keyvaluepage.lua
line 75 at r4 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
Please restore the missing fields, it's very much on purpose to avoid a potential table resize.
(c.f., 3743229, but I'm sure there are others, I might have done a pass on the codebase a while ago).
Done.
frontend/ui/widget/keyvaluepage.lua
line 308 at r4 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
Ditto.
Done.
plugins/coverbrowser.koplugin/listmenu.lua
line 274 at r4 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
I'd probably update that comment to say
thumbnail
instead ofcover
, to avoid confusion with the real, full-size cover.
Done.
plugins/coverbrowser.koplugin/main.lua
line 173 at r1 (raw file):
Previously, Frenzie (Frans de Jonge) wrote…
Possibly
×
instead of plainx
?
Done.
plugins/coverbrowser.koplugin/main.lua
line 174 at r4 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
I'd possibly move the type coercion directly into
BookInfoManager:loadSettings
(e.g.,self.settings[key] = tonumber(values[i]) or values[i]
).
Done.
plugins/coverbrowser.koplugin/main.lua
line 178 at r4 (raw file):
Previously, Frenzie (Frans de Jonge) wrote…
Agreed
Done.
plugins/coverbrowser.koplugin/mosaicmenu.lua
line 864 at r3 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
Gah, thought this came from a LuaSettings, but, nope, it's straight from the db...
-- To keep track of CoverBrowser settings CREATE TABLE IF NOT EXISTS config ( key TEXT PRIMARY KEY, value TEXT );
Hence the
strings
...
Done.
plugins/coverbrowser.koplugin/mosaicmenu.lua
line 545 at r4 (raw file):
Previously, NiLuJe (NiLuJe) wrote…
Same comment as in ListMenu about
cover
->thumbnail
Done.
Not bad. After refreshing the cache for certain grid koreader/plugins/coverbrowser.koplugin/mosaicmenu.lua Lines 593 to 598 in 934d214
|
self.settings[key] = values[i] | ||
local value = values[i] | ||
if value then | ||
value = tonumber(value) or value -- convert cdata<int64_t> to lua number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically it's going to be a string, because the SQL table has a TEXT
type, but eh, that's the spirit ;p.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 1 of 1 files at r5, 1 of 1 files at r6, 4 of 4 files at r7, all commit messages.
Reviewable status: all files reviewed, 8 unresolved discussions (waiting on @Frenzie, @hius07, @mergen3107, and @poire-z)
plugins/coverbrowser.koplugin/bookinfomanager.lua
line 276 at r7 (raw file):
if value then value = tonumber(value) or value -- convert cdata<int64_t> to lua number end
tonumber(nil)
is perfectly safe, so you can simplify the whole inner loop to self.settings[key] = tonumber(values[i]) or values[i]
(I wouldn't worry about duplicating the indexing either, it's insignificant, and liable to be faster than the extra store/load anyway).
(Plus the nit about the comment mentioned on GH ;)).
Code quote:
local value = values[i]
if value then
value = tonumber(value) or value -- convert cdata<int64_t> to lua number
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed 2 of 2 files at r8, all commit messages.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @Frenzie, @hius07, @mergen3107, and @poire-z)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine.
But may be keep that for after v2023.12 (if there is a v2023.12), so we get another full 1 or 2 months for @NiLuJe other ideas (or to tame them) and we get to trash only dev-build users's bookinfo caches multiple time?
@@ -39,7 +39,7 @@ local BOOKINFO_DB_SCHEMA = [[ | |||
cover_fetched TEXT, -- NULL / 'Y' = we tried to fetch a cover (but we may not have gotten one) | |||
has_meta TEXT, -- NULL / 'Y' = has metadata (title, authors...) | |||
has_cover TEXT, -- NULL / 'Y' = has cover image (cover_*) | |||
cover_sizetag TEXT, -- 'M' (Medium, MosaicMenuItem) / 's' (small, ListMenuItem) | |||
cover_sizetag TEXT, -- '1072x1448' (example, is the original cover image width and height) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we stay with one thumbnail and downscaling, no need of new columns at all.
I understand, but reusing a column named "cover sizetag" to store the original cover image width and height concatenated as a string, even if it is good for the planet :), is not the most clear and explicite DB design and naming :)
So, if this ends up being good and stable, one day, on the next DB schema change, we'll probably change it to have 2 columns of numbers for source cover image w & h. No need to change it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I'll keep that in mind, as I may end up tweaking that to some extent, depending on how it all shakes up ;).
@@ -270,7 +270,7 @@ function BookInfoManager:loadSettings(db_conn) | |||
local keys = res[1] | |||
local values = res[2] | |||
for i, key in ipairs(keys) do | |||
self.settings[key] = values[i] | |||
self.settings[key] = tonumber(values[i]) or values[i] -- TEXT db field |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd possibly move the type coercion directly into BookInfoManager:loadSettings (e.g., self.settings[key] = tonumber(values[i]) or values[i]).
I guess I'm fine with that, because we are in a little limited context of code that save & load stuff thru here, and it's possible most actually save & load numbers.
But generically, I find this change worse. Previously, only code saving numbers had to know they would get strings and need to do the conversion themselves. With this, any code saving strings may now get numbers for strings that looked like a number, and would have to be sure to coerce them back to be strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lua is generally pretty lenient about string/number automatic conversions, especially number -> string ones, so I wouldn't expect any surprises.
(I did indeed plan to double-check what the hell we store in there, though ;)).
local max_img_h = cover_specs.max_cover_h | ||
if img_w > max_img_w or img_h > max_img_h then -- original image bigger than placeholder | ||
local new_cover_w, new_cover_h = BookInfoManager.getCachedCoverSize(img_w, img_h, max_img_w, max_img_h) | ||
if new_cover_w > bookinfo.cover_w or new_cover_h > bookinfo.cover_h then return true end -- bigger thumbnail needed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Would be easier to read with "return true" as usual on a new indented line.)
Trusting you both on all the maths :)
table.insert(sub_item_table, { | ||
sub_item_table[i] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing against it, but just curious: why this change ? :)
(I personally find indexing less flexisble than insert(), ie. if you were to want to skip one of the item in some cases.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One day I met
koreader/plugins/exporter.koplugin/main.lua
Line 241 in e7ee900
submenu[#submenu + 1] = v:getMenuTable() |
and made a simple performance test of
(1)
t[i] = a
(2)
table.insert(t, a)
(3)
t[#t + 1] = a
(1) is the fastest, (3) is the slowest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, unlikely to matter outside of extremely hot codepaths though, but it's mostly harmless here ;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, for UI stuff, we don't really need any optimisation of this kind.
When we just fill/append stuff in an array, table.insert() is just obvious - no need to read around to be sure that [i]
is always the right value.
I should theoretically have a couple of hours later today so if that pans out I'll distill out the more important commits. :) I won't have much upload to speak of though. |
Welp, it's Azure time anyway ;D. |
Oh, I only meant slower than I have at home, no data limit issues. |
If we have a couple of weeks until the January release, this can be safely merged I believe. |
Fixes #11186. Fixes #11171.
This change is