2
0
mirror of https://github.com/koreader/koreader synced 2024-11-10 01:10:34 +00:00

ReaderStatus, Book status widget: cleanup (#12343)

This commit is contained in:
hius07 2024-08-19 08:05:19 +03:00 committed by GitHub
parent 91c15d5277
commit f0c9a642d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 59 additions and 135 deletions

View File

@ -1,8 +1,6 @@
local BookStatusWidget = require("ui/widget/bookstatuswidget")
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
local ButtonDialog = require("ui/widget/buttondialog")
local Device = require("device")
local Event = require("ui/event")
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
local InfoMessage = require("ui/widget/infomessage")
local UIManager = require("ui/uimanager")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
@ -10,18 +8,10 @@ local util = require("util")
local _ = require("gettext")
local ReaderStatus = WidgetContainer:extend{
document = nil,
enabled = true,
total_pages = 0,
}
function ReaderStatus:init()
if self.ui.document.is_pic then
self.enabled = false
else
self.total_pages = self.document:getPageCount()
self.ui.menu:registerToMainMenu(self)
end
self.ui.menu:registerToMainMenu(self)
end
function ReaderStatus:addToMainMenu(menu_items)
@ -33,6 +23,20 @@ function ReaderStatus:addToMainMenu(menu_items)
}
end
function ReaderStatus:onShowBookStatus(before_show_callback)
local status_page = BookStatusWidget:new{
ui = self.ui,
}
if before_show_callback then
before_show_callback()
end
status_page.dithered = true
UIManager:show(status_page, "full")
return true
end
-- End of book
function ReaderStatus:onEndOfBook()
Device:performHapticFeedback("CONTEXT_CLICK")
local QuickStart = require("ui/quickstart")
@ -47,23 +51,25 @@ function ReaderStatus:onEndOfBook()
-- Should we start by marking the book as finished?
if G_reader_settings:isTrue("end_document_auto_mark") then
self:onMarkBook(true)
self:markBook(true)
end
local next_file_enabled = G_reader_settings:readSetting("collate") ~= "access"
local settings = G_reader_settings:readSetting("end_document_action")
local collate = G_reader_settings:readSetting("collate")
local next_file_enabled = collate ~= "access" and collate ~= "date"
local settings = G_reader_settings:readSetting("end_document_action") or "pop-up"
local top_widget = UIManager:getTopmostVisibleWidget() or {}
if (settings == "pop-up" or settings == nil) and top_widget.name ~= "end_document" then
if settings == "pop-up" and top_widget.name ~= "end_document" then
local button_dialog
local buttons = {
{
{
text_func = function()
return self.summary.status == "complete" and _("Mark as reading") or _("Mark as finished")
local status = self.ui.doc_settings:readSetting("summary").status
return status == "complete" and _("Mark as reading") or _("Mark as finished")
end,
callback = function()
UIManager:close(button_dialog)
self:onMarkBook()
self:markBook()
end,
},
{
@ -80,7 +86,7 @@ function ReaderStatus:onEndOfBook()
text = _("Go to beginning"),
callback = function()
UIManager:close(button_dialog)
self.ui:handleEvent(Event:new("GoToBeginning"))
self.ui.gotopage:onGoToBeginning()
end,
},
{
@ -112,7 +118,7 @@ function ReaderStatus:onEndOfBook()
},
},
}
button_dialog = ButtonDialogTitle:new{
button_dialog = ButtonDialog:new{
name = "end_document",
title = _("You've reached the end of the document.\nWhat would you like to do?"),
title_align = "center",
@ -132,18 +138,18 @@ function ReaderStatus:onEndOfBook()
self:onOpenNextDocumentInFolder()
else
UIManager:show(InfoMessage:new{
text = _("Could not open next file. Sort by last read date does not support this feature."),
text = _("Could not open next file. Sort by date does not support this feature."),
})
end
elseif settings == "goto_beginning" then
self.ui:handleEvent(Event:new("GoToBeginning"))
self.ui.gotopage:onGoToBeginning()
elseif settings == "file_browser" then
-- Ditto
UIManager:nextTick(function()
self:openFileBrowser()
end)
elseif settings == "mark_read" then
self:onMarkBook(true)
self:markBook(true)
UIManager:show(InfoMessage:new{
text = _("You've reached the end of the document.\nThe current book is marked as finished."),
timeout = 3
@ -164,7 +170,7 @@ end
function ReaderStatus:openFileBrowser()
local FileManager = require("apps/filemanager/filemanager")
local file = self.ui.document.file
local file = self.document.file
self.ui:onClose()
if not FileManager.instance then
self.ui:showFileManager(file)
@ -188,7 +194,7 @@ function ReaderStatus:onOpenNextDocumentInFolder()
end
function ReaderStatus:deleteFile()
self.settings:flush() -- enable additional warning text for newly opened file
self.ui.doc_settings:flush() -- enable additional warning text for newly opened file
local FileManager = require("apps/filemanager/filemanager")
local function pre_delete_callback()
self.ui:onClose()
@ -200,35 +206,14 @@ function ReaderStatus:deleteFile()
FileManager:showDeleteFileDialog(self.document.file, post_delete_callback, pre_delete_callback)
end
function ReaderStatus:onShowBookStatus(before_show_callback)
local status_page = BookStatusWidget:new {
thumbnail = FileManagerBookInfo:getCoverImage(self.document),
props = self.ui.doc_props,
document = self.document,
settings = self.settings,
ui = self.ui,
}
if before_show_callback then
before_show_callback()
end
status_page.dithered = true
UIManager:show(status_page, "full")
return true
end
-- If mark_read is true then we change status only from reading/abandoned to complete.
-- Otherwise we change status from reading/abandoned to complete or from complete to reading.
function ReaderStatus:onMarkBook(mark_read)
self.summary.status = (not mark_read and self.summary.status == "complete") and "reading" or "complete"
self.summary.modified = os.date("%Y-%m-%d", os.time())
-- If History is called over Reader, it will read the file to get the book status, so save and flush
self.settings:saveSetting("summary", self.summary)
self.settings:flush()
end
function ReaderStatus:onReadSettings(config)
self.settings = config
self.summary = config:readSetting("summary") or {}
function ReaderStatus:markBook(mark_read)
local summary = self.ui.doc_settings:readSetting("summary")
summary.status = (not mark_read and summary.status == "complete") and "reading" or "complete"
summary.modified = os.date("%Y-%m-%d", os.time())
-- If History is called over Reader, it will read the file to get the book status, so flush
self.ui.doc_settings:flush()
end
return ReaderStatus

View File

@ -400,7 +400,6 @@ function ReaderUI:init()
self:registerModule("status", ReaderStatus:new{
ui = self,
document = self.document,
view = self.view,
})
-- thumbnails service (book map, page browser)
self:registerModule("thumbnail", ReaderThumbnail:new{

View File

@ -463,7 +463,7 @@ function Screensaver:setup(event, event_message)
end
end
if self.screensaver_type == "bookstatus" then
if not ui or not lastfile or lfs.attributes(lastfile, "mode") ~= "file" or (ui.doc_settings and ui.doc_settings:isTrue("exclude_screensaver")) then
if not (ui and ui.doc_settings and ui.doc_settings:nilOrFalse("exclude_screensaver")) then
self.screensaver_type = "random_image"
end
end
@ -557,15 +557,8 @@ function Screensaver:show()
widget = ImageWidget:new(widget_settings)
elseif self.screensaver_type == "bookstatus" then
local ReaderUI = require("apps/reader/readerui")
local ui = ReaderUI.instance
local doc = ui.document
local doc_settings = ui.doc_settings
widget = BookStatusWidget:new{
thumbnail = FileManagerBookInfo:getCoverImage(doc),
props = ui.doc_props,
document = doc,
settings = doc_settings,
ui = ui,
ui = ReaderUI.instance,
readonly = true,
}
elseif self.screensaver_type == "readingprogress" then

View File

@ -2,6 +2,7 @@ local Blitbuffer = require("ffi/blitbuffer")
local Button = require("ui/widget/button")
local CenterContainer = require("ui/widget/container/centercontainer")
local Device = require("device")
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
local Font = require("ui/font")
local FocusManager = require("ui/widget/focusmanager")
local FrameContainer = require("ui/widget/container/framecontainer")
@ -42,41 +43,14 @@ local stats_book = {}
},]]
local BookStatusWidget = FocusManager:extend{
padding = Size.padding.fullscreen,
settings = nil,
thumbnail = nil,
props = nil,
star = nil, -- Button
summary = nil, -- hash
}
function BookStatusWidget:init()
self.updated = false
self.updated = nil
self.layout = {}
-- What a blank, full summary table should look like
local new_summary = {
rating = nil,
note = nil,
status = "",
modified = "",
}
if self.settings then
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
else
self.summary = new_summary
end
self.summary = self.ui.doc_settings:readSetting("summary")
self.total_pages = self.ui.document:getPageCount()
stats_book = self:getStats()
@ -84,17 +58,12 @@ function BookStatusWidget:init()
self.medium_font_face = Font:getFace("ffont")
self.large_font_face = Font:getFace("largeffont")
local button_enabled = true
if self.readonly then
button_enabled = false
end
self.star = Button:new{
icon = "star.empty",
bordersize = 0,
radius = 0,
margin = 0,
enabled = button_enabled,
enabled = not self.readonly,
show_parent = self,
readonly = self.readonly,
}
@ -299,13 +268,14 @@ function BookStatusWidget:genBookInfoGroup()
-- Get a chance to have title and authors rendered with alternate
-- glyphs for the book language
local lang = self.props.language
local props = self.ui.doc_props
local lang = props.language
-- title
local book_meta_info_group = VerticalGroup:new{
align = "center",
VerticalSpan:new{ width = height * 0.2 },
TextBoxWidget:new{
text = self.props.display_title,
text = props.display_title,
lang = lang,
width = width,
face = self.medium_font_face,
@ -315,7 +285,7 @@ function BookStatusWidget:genBookInfoGroup()
}
-- author
local text_author = TextBoxWidget:new{
text = self.props.authors,
text = props.authors,
lang = lang,
face = self.small_font_face,
width = width,
@ -344,8 +314,7 @@ function BookStatusWidget:genBookInfoGroup()
)
-- complete text
local text_complete = TextWidget:new{
text = T(_("%1% Completed"),
string.format("%1.f", read_percentage * 100)),
text = T(_("%1\xE2\x80\xAF% Completed"), string.format("%1.f", read_percentage * 100)),
face = self.small_font_face,
}
table.insert(book_meta_info_group,
@ -367,23 +336,21 @@ function BookStatusWidget:genBookInfoGroup()
HorizontalSpan:new{ width = split_span_width }
}
-- thumbnail
if self.thumbnail then
local thumbnail = FileManagerBookInfo:getCoverImage(self.ui.document)
if thumbnail then
-- Much like BookInfoManager, honor AR here
local cbb_w, cbb_h = self.thumbnail:getWidth(), self.thumbnail:getHeight()
local cbb_w, cbb_h = thumbnail:getWidth(), 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)
thumbnail = RenderImage:scaleBlitBuffer(thumbnail, cbb_w, cbb_h, true)
end
table.insert(book_info_group, ImageWidget:new{
image = self.thumbnail,
image = thumbnail,
width = cbb_w,
height = cbb_h,
})
-- dereference thumbnail since we let imagewidget manages its lifecycle
self.thumbnail = nil
end
table.insert(book_info_group, CenterContainer:new{
@ -508,28 +475,16 @@ function BookStatusWidget:generateSwitchGroup(width)
height = Screen:scaleBySize(105)
end
local args = { "reading", "abandoned", "complete", }
local position = 1
for k, v in ipairs(args) do
if v == self.summary.status then
position = k
break
end
end
local switch = ToggleSwitch:new{
width = math.floor(width * 0.6),
name = "book_status",
event = "ChangeBookStatus",
toggle = { _("Reading"), _("On hold"), _("Finished"), },
args = args,
alternate = false,
args = { "reading", "abandoned", "complete", },
values = { 1, 2, 3, },
enabled = not self.readonly,
config = self,
readonly = self.readonly,
}
local position = util.arrayContains(switch.args, self.summary.status) or 1
switch:setPosition(position)
self:mergeLayoutInVertical(switch)
@ -545,9 +500,7 @@ end
function BookStatusWidget:onConfigChoose(values, name, event, args, position)
UIManager:tickAfterNext(function()
if values then
self:onChangeBookStatus(args, position)
end
self:onChangeBookStatus(args, position)
UIManager:setDirty(nil, "ui", nil, true)
end)
end
@ -577,9 +530,8 @@ function BookStatusWidget:onMultiSwipe(arg, ges_ev)
end
function BookStatusWidget:onClose()
if self.updated and self.summary then
self.settings:saveSetting("summary", self.summary)
self.settings:flush()
if self.updated then
self.ui.doc_settings:flush()
end
-- NOTE: Flash on close to avoid ghosting, since we show an image.
UIManager:close(self, "flashpartial")
@ -590,8 +542,6 @@ function BookStatusWidget:onSwitchFocus(inputbox)
self.note_dialog = InputDialog:new{
title = _("Review"),
input = self.input_note:getText(),
input_hint = "",
input_type = "text",
scroll = true,
allow_newline = true,
text_height = Screen:scaleBySize(150),

View File

@ -389,10 +389,7 @@ function testBookStatus()
document = doc
}
local status_page = require("ui/widget/bookstatuswidget"):new {
thumbnail = doc:getCoverPageImage(),
props = reader.doc_props,
document = doc,
local status_page = require("ui/widget/bookstatuswidget"):new{
ui = reader,
}
UIManager:show(status_page)