diff --git a/koreader-plugin/bookorbit.koplugin/bookorbit_main_menu.lua b/koreader-plugin/bookorbit.koplugin/bookorbit_main_menu.lua index 4c88e3bd4..aaee8012f 100644 --- a/koreader-plugin/bookorbit.koplugin/bookorbit_main_menu.lua +++ b/koreader-plugin/bookorbit.koplugin/bookorbit_main_menu.lua @@ -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 diff --git a/koreader-plugin/bookorbit.koplugin/bookorbit_menu_sheet.lua b/koreader-plugin/bookorbit.koplugin/bookorbit_menu_sheet.lua index 058ecf428..a2b81d758 100644 --- a/koreader-plugin/bookorbit.koplugin/bookorbit_menu_sheet.lua +++ b/koreader-plugin/bookorbit.koplugin/bookorbit_menu_sheet.lua @@ -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)), diff --git a/koreader-plugin/bookorbit.koplugin/main.lua b/koreader-plugin/bookorbit.koplugin/main.lua index c440ead3f..1f4fecfc8 100644 --- a/koreader-plugin/bookorbit.koplugin/main.lua +++ b/koreader-plugin/bookorbit.koplugin/main.lua @@ -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 diff --git a/koreader-plugin/spec/bookorbit_menu_context_test.lua b/koreader-plugin/spec/bookorbit_menu_context_test.lua index f41e82640..0b1ad7065 100644 --- a/koreader-plugin/spec/bookorbit_menu_context_test.lua +++ b/koreader-plugin/spec/bookorbit_menu_context_test.lua @@ -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") diff --git a/koreader-plugin/spec/bookorbit_menu_sheet_state_test.lua b/koreader-plugin/spec/bookorbit_menu_sheet_state_test.lua index 5faf2bd08..a0e7a3477 100644 --- a/koreader-plugin/spec/bookorbit_menu_sheet_state_test.lua +++ b/koreader-plugin/spec/bookorbit_menu_sheet_state_test.lua @@ -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")