fix(reader): add KOReader file browser exit

Keep the reading view as the default exit while exposing KOReader's file browser as a separate action that closes the open book safely. Bypass the BookOrbit home preference for this explicit navigation.

Closes #2013
This commit is contained in:
neon
2026-10-31 01:56:36 +00:00
parent b8ba579336
commit 14caaa58b9
5 changed files with 31 additions and 4 deletions
@@ -438,6 +438,14 @@ function MainMenu:onMenuSheetAction(page, catalog, action)
after(function() if catalog and catalog.goDashboard then catalog:goDashboard() end end)
elseif kind == "exit" then
after(function() if catalog then catalog:onCloseAllMenus() end end)
elseif kind == "files" then
self.skip_return_home_once = true
after(function()
if catalog then catalog:onCloseAllMenus() end
UIManager:nextTick(function()
UIManager:sendEvent(require("ui/event"):new("Home"))
end)
end)
elseif kind == "search" then
after(function() if catalog then catalog:onSearchButtonTap() end end)
elseif kind == "link" then
@@ -200,6 +200,14 @@ function MenuSheet.body(d, w, o)
local third = d.book and tile(last_w, th, "book-open", _("Back to book"), d.book, { kind = "exit" }, true)
or tile(last_w, th, "folder-open", _("Files"), _("Close BookOrbit"), { kind = "exit" })
local tiles = hstack({ w = w, gap = gap }, { first, second, third })
local file_browser = d.book and MenuUI.group(w, {
MenuUI.row(MenuUI.rowsIn(w), {
icon = "folder-open",
label = _("File browser"),
sub = _("Close this book and open KOReader files"),
action = { kind = "files" },
}),
}) or nil
-- side_rows: a short screen sets the rows beside Go to, not under it.
local nav_w = o.side_rows and math.floor((w - px(20)) * 0.6) or w
@@ -251,6 +259,8 @@ function MenuSheet.body(d, w, o)
banner or false,
banner and space(nil, px(12)) or false,
tiles,
file_browser and space(nil, px(10)) or false,
file_browser or false,
space(nil, px(16)),
o.side_rows and hstack({ w = w, gap = px(20), valign = "top" }, {
MenuUI.section(nav_w, _("Go to"), navGrid(nav_w, d, 2)),
+1 -1
View File
@@ -1470,7 +1470,7 @@ function BookOrbit:registerEvents()
end
function BookOrbit:onCloseWidget()
if self.in_reader and self.settings.catalog_auto_open == "home" then
if self.in_reader and self.settings.catalog_auto_open == "home" and not self.skip_return_home_once then
PluginShare.bookorbit_return_home = os.time()
end
if self.periodic_push_task then
@@ -16,7 +16,9 @@ package.loaded["ffi/util"] = {
}
local ticks = {}
local sent_events = {}
package.loaded["device"] = { model = "test-device" }
package.loaded["ui/event"] = { new = function(_, name) return { name = name } end }
package.loaded["ui/widget/infomessage"] = { new = function(_, opts) return opts end }
package.loaded["ui/widget/inputdialog"] = {}
package.loaded["ui/network/manager"] = {
@@ -26,6 +28,7 @@ package.loaded["ui/widget/notification"] = {}
package.loaded["ui/uimanager"] = {
nextTick = function(_, callback) table.insert(ticks, callback) end,
tickAfterNext = function(_, callback) table.insert(ticks, callback) end,
sendEvent = function(_, event) table.insert(sent_events, event.name) end,
show = function() end,
}
package.loaded["ffi/sha2"] = { md5 = function(value) return value end }
@@ -166,15 +169,18 @@ local function run(action)
end
run({ kind = "home" })
run({ kind = "exit" })
run({ kind = "files" })
run({ kind = "search" })
run({ kind = "link", link = "authors" })
run({ kind = "list-options" })
assertEqual(table.concat(events, ","), "home,exit,search,link:authors,list-options", "catalog actions reach the catalog")
assertEqual(closes, 5, "every action closes the sheet first")
assertEqual(table.concat(events, ","), "home,exit,exit,search,link:authors,list-options", "catalog actions reach the catalog")
assertEqual(table.concat(sent_events, ","), "Home", "Files asks KOReader to open its file browser")
assertEqual(sheet_plugin.skip_return_home_once, true, "Files bypasses the BookOrbit home preference once")
assertEqual(closes, 6, "every action closes the sheet first")
-- Sync now keeps the sheet open: its tile shows the run, then the outcome.
run({ kind = "sync" })
assertEqual(closes, 5, "Sync now leaves the sheet open")
assertEqual(closes, 6, "Sync now leaves the sheet open")
assertEqual(sheet_calls[1][1], "startSweep", "Sync now starts a library sync")
local sweep = sheet_calls[1][2]
assertEqual(sweep.quiet, true, "the sync reports to the sheet, not a dialog")
@@ -36,4 +36,7 @@ plugin.settings.last_error = { event = "annotation_sync", at = 2 }
assert(Sheet.data(plugin, catalog).sync_error, "actual sync failure is shown")
plugin.settings.last_sync = { event = "connection_test", at = 3 }
assert(Sheet.data(plugin, catalog).sync_error, "legacy connection timestamp cannot suppress sync failure")
plugin.ui = { document = {} }
plugin.openBookTitle = function() return "Open book" end
assert(Sheet.data(plugin, catalog).book == "Open book", "an open reader book exposes both exit destinations")
print("bookorbit_menu_sheet_state_test.lua: ok")