mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Some BookStatus QoL tweaks (#5100)
* Make the cover thumbnail respect the cover's AR in the widget * Add a "Mark as read/unread" button in the FM's longpress menu. * Make sure the cover_info cache is wiped if necessary (sidecar purge/BookInfo cache clear).
This commit is contained in:
@@ -17,6 +17,7 @@ local LeftContainer = require("ui/widget/container/leftcontainer")
|
||||
local LineWidget = require("ui/widget/linewidget")
|
||||
local OverlapGroup = require("ui/widget/overlapgroup")
|
||||
local ProgressWidget = require("ui/widget/progresswidget")
|
||||
local RenderImage = require("ui/renderimage")
|
||||
local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
@@ -56,12 +57,27 @@ local BookStatusWidget = InputContainer:new{
|
||||
|
||||
function BookStatusWidget:init()
|
||||
if self.settings then
|
||||
self.summary = self.settings:readSetting("summary") or {
|
||||
-- What a blank, full summary table should look like
|
||||
local new_summary = {
|
||||
rating = nil,
|
||||
note = nil,
|
||||
status = "",
|
||||
modified = "",
|
||||
}
|
||||
local summary = self.settings:readSetting("summary")
|
||||
-- Check if the summary table we get is a full one, or a minimal one from CoverMenu...
|
||||
if summary then
|
||||
if summary.modified then
|
||||
-- Complete, use it as-is
|
||||
self.summary = summary
|
||||
else
|
||||
-- Incomplete, fill it up
|
||||
self.summary = new_summary
|
||||
util.tableMerge(self.summary, summary)
|
||||
end
|
||||
else
|
||||
self.summary = new_summary
|
||||
end
|
||||
end
|
||||
self.total_pages = self.view.document:getPageCount()
|
||||
stats_book = self:getStats()
|
||||
@@ -343,10 +359,19 @@ function BookStatusWidget:genBookInfoGroup()
|
||||
}
|
||||
-- thumbnail
|
||||
if self.thumbnail then
|
||||
-- Much like BookInfoManager, honor AR here
|
||||
local cbb_w, cbb_h = self.thumbnail:getWidth(), self.thumbnail:getHeight()
|
||||
if cbb_w > img_width or cbb_h > img_height then
|
||||
local scale_factor = math.min(img_width / cbb_w, img_height / cbb_h)
|
||||
cbb_w = math.min(math.floor(cbb_w * scale_factor)+1, img_width)
|
||||
cbb_h = math.min(math.floor(cbb_h * scale_factor)+1, img_height)
|
||||
self.thumbnail = RenderImage:scaleBlitBuffer(self.thumbnail, cbb_w, cbb_h, true)
|
||||
end
|
||||
|
||||
table.insert(book_info_group, ImageWidget:new{
|
||||
image = self.thumbnail,
|
||||
width = img_width,
|
||||
height = img_height,
|
||||
width = cbb_w,
|
||||
height = cbb_h,
|
||||
})
|
||||
-- dereference thumbnail since we let imagewidget manages its lifecycle
|
||||
self.thumbnail = nil
|
||||
|
||||
@@ -31,6 +31,7 @@ local _ = require("gettext")
|
||||
|
||||
local Button = InputContainer:new{
|
||||
text = nil, -- mandatory
|
||||
text_func = nil,
|
||||
icon = nil,
|
||||
preselect = false,
|
||||
callback = nil,
|
||||
@@ -48,6 +49,11 @@ local Button = InputContainer:new{
|
||||
}
|
||||
|
||||
function Button:init()
|
||||
-- Prefer an optional text_func over text
|
||||
if self.text_func and type(self.text_func) == "function" then
|
||||
self.text = self.text_func()
|
||||
end
|
||||
|
||||
if self.text then
|
||||
self.label_widget = TextWidget:new{
|
||||
text = self.text,
|
||||
|
||||
@@ -51,6 +51,7 @@ function ButtonTable:init()
|
||||
local btn_entry = row[j]
|
||||
local button = Button:new{
|
||||
text = btn_entry.text,
|
||||
text_func = btn_entry.text_func,
|
||||
enabled = btn_entry.enabled,
|
||||
callback = btn_entry.callback,
|
||||
hold_callback = btn_entry.hold_callback,
|
||||
|
||||
@@ -184,6 +184,16 @@ function util.arrayAppend(t1, t2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Merge t2 into t1, overwriting existing elements if they already exist
|
||||
-- Probably not safe with nested tables (c.f., https://stackoverflow.com/q/1283388)
|
||||
---- @param t1 Lua table
|
||||
---- @param t2 Lua table
|
||||
function util.tableMerge(t1, t2)
|
||||
for k, v in pairs(t2) do
|
||||
t1[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Gets last index of string in character
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local DocSettings = require("docsettings")
|
||||
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
|
||||
local ImageViewer = require("ui/widget/imageviewer")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
@@ -224,7 +225,77 @@ function CoverMenu:updateItems(select_number)
|
||||
UIManager:close(self.file_dialog)
|
||||
end
|
||||
|
||||
-- Fudge the "Purge .sdr" button ([1][3]) callback to also trash the cover_info_cache
|
||||
local orig_purge_callback = orig_buttons[1][3].callback
|
||||
orig_buttons[1][3].callback = function()
|
||||
-- Wipe the cache
|
||||
if self.cover_info_cache[file] then
|
||||
self.cover_info_cache[file] = nil
|
||||
end
|
||||
-- And then purge the sidecar folder as expected
|
||||
orig_purge_callback()
|
||||
end
|
||||
|
||||
-- Add some new buttons to original buttons set
|
||||
table.insert(orig_buttons, {
|
||||
{ -- Mark the book as read/unread
|
||||
text_func = function()
|
||||
-- If the book has a cache entry, it means it has a sidecar file, and it *may* have the info we need.
|
||||
local status
|
||||
if self.cover_info_cache[file] then
|
||||
local _, _, c_status = unpack(self.cover_info_cache[file])
|
||||
status = c_status
|
||||
end
|
||||
-- NOTE: status may still be nil if the BookStatus widget was never opened in this book.
|
||||
-- For our purposes, we assume this means reading or on hold, which is just fine.
|
||||
-- NOTE: This also means we assume "on hold" means reading, meaning it'll be flipped to "finished",
|
||||
-- which I'm personally okay with, too.
|
||||
-- c.f., BookStatusWidget:generateSwitchGroup for the three possible constant values.
|
||||
return status == "complete" and _("Mark as reading") or _("Mark as read")
|
||||
end,
|
||||
enabled = true,
|
||||
callback = function()
|
||||
local status
|
||||
if self.cover_info_cache[file] then
|
||||
local c_pages, c_percent_finished, c_status = unpack(self.cover_info_cache[file])
|
||||
status = c_status == "complete" and "reading" or "complete"
|
||||
-- Update the cache, even if it had a nil status before
|
||||
self.cover_info_cache[file] = {c_pages, c_percent_finished, status}
|
||||
else
|
||||
-- We assumed earlier an empty status meant "reading", so, flip that to "complete"
|
||||
status = "complete"
|
||||
end
|
||||
|
||||
-- In case the book doesn't have a sidecar file, this'll create it
|
||||
local docinfo = DocSettings:open(file)
|
||||
if docinfo.data.summary and docinfo.data.summary.status then
|
||||
-- Book already had the full BookStatus table in its sidecar, easy peasy!
|
||||
docinfo.data.summary.status = status
|
||||
else
|
||||
-- No BookStatus table, create a minimal one...
|
||||
if docinfo.data.summary then
|
||||
-- Err, a summary table with no status entry? Should never happen...
|
||||
local summary = { status = status }
|
||||
-- Append the status entry to the existing summary...
|
||||
require("util").tableMerge(docinfo.data.summary, summary)
|
||||
else
|
||||
-- No summary table at all, create a minimal one
|
||||
local summary = { status = status }
|
||||
docinfo:saveSetting("summary", summary)
|
||||
end
|
||||
end
|
||||
docinfo:flush()
|
||||
|
||||
UIManager:close(self.file_dialog)
|
||||
self:updateItems()
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
-- Move the "Convert" button ([4][2]) to the left of the "Mark as..." button [5][1] we've just added
|
||||
table.insert(orig_buttons[5], 1, table.remove(orig_buttons[4], 2))
|
||||
|
||||
-- Keep on adding new buttons
|
||||
table.insert(orig_buttons, {
|
||||
{ -- Allow user to view real size cover in ImageViewer
|
||||
text = _("View full size cover"),
|
||||
@@ -262,8 +333,8 @@ function CoverMenu:updateItems(select_number)
|
||||
title = bookinfo.title,
|
||||
text = description,
|
||||
}
|
||||
UIManager:show(textviewer)
|
||||
UIManager:close(self.file_dialog)
|
||||
UIManager:show(textviewer)
|
||||
end,
|
||||
},
|
||||
})
|
||||
@@ -296,6 +367,10 @@ function CoverMenu:updateItems(select_number)
|
||||
text = _("Refresh cached book information"),
|
||||
enabled = bookinfo and true or false,
|
||||
callback = function()
|
||||
-- Wipe the cache
|
||||
if self.cover_info_cache[file] then
|
||||
self.cover_info_cache[file] = nil
|
||||
end
|
||||
BookInfoManager:deleteBookInfo(file)
|
||||
UIManager:close(self.file_dialog)
|
||||
self:updateItems()
|
||||
@@ -391,8 +466,8 @@ function CoverMenu:onHistoryMenuHold(item)
|
||||
title = bookinfo.title,
|
||||
text = description,
|
||||
}
|
||||
UIManager:show(textviewer)
|
||||
UIManager:close(self.histfile_dialog)
|
||||
UIManager:show(textviewer)
|
||||
end,
|
||||
},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user