diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 0aa77050a..9e48da81c 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -335,13 +335,52 @@ function FileManager:setupLayout() end, } ) + table.insert(buttons, {}) -- separator end if is_file then + local status = nil + if DocSettings:hasSidecarFile(file) then + local docinfo = DocSettings:open(file) -- no io handles created, do not close + if docinfo.data.summary and docinfo.data.summary.status and docinfo.data.summary.status ~= "" then + status = docinfo.data.summary.status + else + status = "reading" + end + end + table.insert(buttons, { + { + text = _("Mark as reading"), + enabled = status ~= "reading", + callback = function() + filemanagerutil.setStatus(file, "reading") + self:refreshPath() + UIManager:close(self.file_dialog) + end, + }, + { + text = _("Mark as read"), + enabled = status ~= "complete", + callback = function() + filemanagerutil.setStatus(file, "complete") + self:refreshPath() + UIManager:close(self.file_dialog) + end, + }, + { + text = _("Put on hold"), + enabled = status ~= "abandoned", + callback = function() + filemanagerutil.setStatus(file, "abandoned") + self:refreshPath() + UIManager:close(self.file_dialog) + end, + }, + }) + table.insert(buttons, {}) -- separator table.insert(buttons, { { text = _("Reset settings"), - id = "reset_settings", -- used by covermenu enabled = is_file and DocSettings:hasSidecarFile(BaseUtil.realpath(file)), callback = function() UIManager:show(ConfirmBox:new{ diff --git a/frontend/apps/filemanager/filemanagerutil.lua b/frontend/apps/filemanager/filemanagerutil.lua index f91e54da1..1e266d7d5 100644 --- a/frontend/apps/filemanager/filemanagerutil.lua +++ b/frontend/apps/filemanager/filemanagerutil.lua @@ -63,4 +63,35 @@ function filemanagerutil.resetDocumentSettings(file) end end +-- Set a document's status +function filemanagerutil.setStatus(file, status) + -- In case the book doesn't have a sidecar file, this'll create it + local docinfo = DocSettings:open(file) + local summary = nil + 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 + docinfo.data.summary.modified = os.date("%Y-%m-%d", os.time()) + summary = docinfo.data.summary + else + -- No BookStatus table, create a minimal one... + if docinfo.data.summary then + -- Err, a summary table with no status entry? Should never happen... + summary = { status = status } + -- Append the status entry to the existing summary... + require("util").tableMerge(docinfo.data.summary, summary) + docinfo.data.summary.modified = os.date("%Y-%m-%d", os.time()) + summary = docinfo.data.summary + else + -- No summary table at all, create a minimal one + summary = { + status = status, + modified = os.date("%Y-%m-%d", os.time()) + } + end + end + docinfo:saveSetting("summary", summary) + docinfo:flush() +end + return filemanagerutil diff --git a/plugins/coverbrowser.koplugin/covermenu.lua b/plugins/coverbrowser.koplugin/covermenu.lua index d95818c60..df41f4f4f 100644 --- a/plugins/coverbrowser.koplugin/covermenu.lua +++ b/plugins/coverbrowser.koplugin/covermenu.lua @@ -1,6 +1,5 @@ local BD = require("ui/bidi") 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") @@ -306,59 +305,8 @@ function CoverMenu:updateItems(select_number) }, }) 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 and 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, - callback = function() - local status - if self.cover_info_cache and 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... - 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, - }, { -- Allow a new extraction (multiple interruptions, book replaced)... - text = _("Refresh book info"), + text = _("Refresh cached book information"), enabled = bookinfo and true or false, callback = function() -- Wipe the cache @@ -372,6 +320,28 @@ function CoverMenu:updateItems(select_number) }, }) + -- Fudge the setting resets (e.g. "Reset settings" button) to also trash the cover_info_cache + local orig_purgeSettings = filemanagerutil.purgeSettings + filemanagerutil.purgeSettings = function(f) + -- Wipe the cache + if self.cover_info_cache and self.cover_info_cache[f] then + self.cover_info_cache[f] = nil + end + -- And then purge the sidecar folder as expected + orig_purgeSettings(f) + end + + -- Fudge status changes (e.g. "Mark as read" button) to also update the cover_info_cache + local orig_setStatus = filemanagerutil.setStatus + filemanagerutil.setStatus = function(f, status) + -- Update the cache + if self.cover_info_cache and self.cover_info_cache[f] then + self.cover_info_cache[f][3] = status + end + -- And then set the status on file as expected + orig_setStatus(f, status) + end + -- Create the new ButtonDialogTitle, and let UIManager show it local ButtonDialogTitle = require("ui/widget/buttondialogtitle") self.file_dialog = ButtonDialogTitle:new{ @@ -380,20 +350,8 @@ function CoverMenu:updateItems(select_number) buttons = orig_buttons, } - -- Fudge the "Reset settings" button callback to also trash the cover_info_cache - local button = self.file_dialog.button_table:getButtonById("reset_settings") - local orig_purge_callback = button.callback - button.callback = function() - -- Wipe the cache - if self.cover_info_cache and 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 - -- Replace the "Book information" button callback to use directly our bookinfo - button = self.file_dialog.button_table:getButtonById("book_information") + local button = self.file_dialog.button_table:getButtonById("book_information") button.callback = function() FileManagerBookInfo:show(file, bookinfo) UIManager:close(self.file_dialog) @@ -511,6 +469,10 @@ function CoverMenu:onHistoryMenuHold(item) text = _("Refresh cached book information"), enabled = bookinfo and true or false, callback = function() + -- Wipe the cache + if self.cover_info_cache and self.cover_info_cache[file] then + self.cover_info_cache[file] = nil + end BookInfoManager:deleteBookInfo(file) UIManager:close(self.histfile_dialog) self:updateItems() @@ -630,12 +592,17 @@ function CoverMenu:onCollectionsMenuHold(item) text = _("Refresh cached book information"), enabled = bookinfo and true or false, callback = function() + -- Wipe the cache + if self.cover_info_cache and self.cover_info_cache[file] then + self.cover_info_cache[file] = nil + end BookInfoManager:deleteBookInfo(file) UIManager:close(self.collfile_dialog) self:updateItems() end, }, }) + -- Create the new ButtonDialog, and let UIManager show it local ButtonDialogTitle = require("ui/widget/buttondialogtitle") self.collfile_dialog = ButtonDialogTitle:new{