From bc5d354225e904a2c260c9495b8f5e85dea47dee Mon Sep 17 00:00:00 2001 From: yparitcher Date: Wed, 29 Mar 2023 12:32:44 -0400 Subject: [PATCH] ReaderLink: allow a forward location stack (#10228) this allows going back and forth from links (think of undo / redo) when going back and no forward locations and when we are not on the same page as the last saved location, add the current location to the forward stack, helping if one goes back by mistake they can jump back to their current location when going back and no forward locations and when we are not on the same page as the last saved location, add the current location to the forward stack, helping if one goes back by mistake they can jump back to thier current location --- frontend/apps/reader/modules/readerlink.lua | 96 +++++++++++++++++++-- frontend/dispatcher.lua | 2 + frontend/ui/elements/reader_menu_order.lua | 1 + 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/frontend/apps/reader/modules/readerlink.lua b/frontend/apps/reader/modules/readerlink.lua index 6230abbff..ef3a78d87 100644 --- a/frontend/apps/reader/modules/readerlink.lua +++ b/frontend/apps/reader/modules/readerlink.lua @@ -64,6 +64,7 @@ end local ReaderLink = InputContainer:extend{ location_stack = nil, -- table, per-instance + forward_location_stack = nil, -- table, per-instance _external_link_buttons = nil, } @@ -250,7 +251,7 @@ ReaderLink.onPhysicalKeyboardConnected = ReaderLink.registerKeyEvents function ReaderLink:onReadSettings(config) -- called when loading new document - self.location_stack = {} + self:onClearLocationStack() end local function isTapToFollowLinksOn() @@ -306,6 +307,21 @@ function ReaderLink:addToMainMenu(menu_items) }) end, } + menu_items.go_to_next_location = { + text = _("Go Forward to next location"), + enabled_func = function() return self.forward_location_stack and #self.forward_location_stack > 0 end, + callback = function() self:onGoForwardLink() end, + hold_callback = function(touchmenu_instance) + UIManager:show(ConfirmBox:new{ + text = _("Clear Forward location history?"), + ok_text = _("Clear"), + ok_callback = function() + self:onClearForwardLocationStack() + touchmenu_instance:closeMenu() + end, + }) + end, + } if not Device:isTouchDevice() then -- Menu items below aren't needed. return @@ -662,19 +678,40 @@ function ReaderLink:onTap(_, ges) end end ---- Remember current location so we can go back to it -function ReaderLink:addCurrentLocationToStack() +function ReaderLink:getCurrentLocation() + local location if self.ui.document.info.has_pages then - table.insert(self.location_stack, self.ui.paging:getBookLocation()) + location = self.ui.paging:getBookLocation() else - table.insert(self.location_stack, { - xpointer = self.ui.rolling:getBookLocation(), - }) + location = {xpointer = self.ui.rolling:getBookLocation(),} end + return location +end + +-- Returns true, current_location if the current location is the same as the +-- saved_location on the top of the stack. +-- Otherwise returns false, current_location +function ReaderLink:compareLocationToCurrent(saved_location) + local current_location = self:getCurrentLocation() + if self.ui.rolling and saved_location.xpointer and saved_location.xpointer == current_location.xpointer then + return true, current_location + end + if self.ui.paging and saved_location[1] and current_location[1] and current_location[1].page == saved_location[1].page then + return true, current_location + end + return false, current_location +end + +-- Remember current location so we can go back to it +function ReaderLink:addCurrentLocationToStack(loc) + local location = loc and loc or self:getCurrentLocation() + self:onClearForwardLocationStack() + table.insert(self.location_stack, location) end function ReaderLink:onClearLocationStack(show_notification) self.location_stack = {} + self:onClearForwardLocationStack() if show_notification then UIManager:show(Notification:new{ text = _("Location history cleared."), @@ -683,6 +720,11 @@ function ReaderLink:onClearLocationStack(show_notification) return true end +function ReaderLink:onClearForwardLocationStack() + self.forward_location_stack = {} + return true +end + function ReaderLink:getPreviousLocationPages() local previous_locations = {} if #self.location_stack > 0 then @@ -751,7 +793,7 @@ function ReaderLink:onGotoLink(link, neglect_current_location, allow_footnote_po marker_xpointer = link.from_xpointer, } end - table.insert(self.location_stack, saved_location) + self:addCurrentLocationToStack(saved_location) else self:addCurrentLocationToStack() end @@ -827,6 +869,24 @@ end function ReaderLink:onGoBackLink(show_notification_if_empty) local saved_location = table.remove(self.location_stack) if saved_location then + local same_page, current_location = self:compareLocationToCurrent(saved_location) + -- If there are no forward items + if #self.forward_location_stack == 0 then + -- If we are not on the same page as the current item, + -- then add our current location to the forward stack + if not same_page then + table.insert(self.forward_location_stack, current_location) + end + end + if same_page then + -- If we are on the same page pass through to the next location + table.insert(self.forward_location_stack, saved_location) + saved_location = table.remove(self.location_stack) + end + end + + if saved_location then + table.insert(self.forward_location_stack, saved_location) logger.dbg("GoBack: restoring:", saved_location) self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location)) return true @@ -837,6 +897,26 @@ function ReaderLink:onGoBackLink(show_notification_if_empty) end end +--- Goes to next location. +function ReaderLink:onGoForwardLink() + local saved_location = table.remove(self.forward_location_stack) + if saved_location then + local same_page = self:compareLocationToCurrent(saved_location) + if same_page then + -- If we are on the same page pass through to the next location + table.insert(self.location_stack, saved_location) + saved_location = table.remove(self.forward_location_stack) + end + end + + if saved_location then + table.insert(self.location_stack, saved_location) + logger.dbg("GoForward: restoring:", saved_location) + self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location)) + return true + end +end + function ReaderLink:onSwipe(arg, ges) local direction = BD.flipDirectionIfMirroredUILayout(ges.direction) if direction == "east" then diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index 9449ff3e2..f58b3268d 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -123,6 +123,7 @@ local settingsList = { skim = {category="none", event="ShowSkimtoDialog", title=_("Skim document"), reader=true}, back = {category="none", event="Back", title=_("Back"), reader=true}, previous_location = {category="none", event="GoBackLink", arg=true, title=_("Back to previous location"), reader=true}, + next_location = {category="none", event="GoForwardLink", arg=true, title=_("Forward to next location"), reader=true}, latest_bookmark = {category="none", event="GoToLatestBookmark", title=_("Go to latest bookmark"), reader=true}, follow_nearest_link = {category="arg", event="GoToPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest link"), reader=true}, follow_nearest_internal_link = {category="arg", event="GoToInternalPageLink", arg={pos={x=0,y=0}}, title=_("Follow nearest internal link"), reader=true}, @@ -307,6 +308,7 @@ local dispatcher_menu_order = { "latest_bookmark", "back", "previous_location", + "next_location", "follow_nearest_link", "follow_nearest_internal_link", "clear_location_history", diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index b124d99d1..df057ee67 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -28,6 +28,7 @@ local order = { "autoturn", "----------------------------", "go_to_previous_location", + "go_to_next_location", }, navi_settings = { "toc_alt_toc",