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
reviewable/pr10269/r1
yparitcher 1 year ago committed by GitHub
parent 3a894f954c
commit bc5d354225
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -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",

@ -28,6 +28,7 @@ local order = {
"autoturn",
"----------------------------",
"go_to_previous_location",
"go_to_next_location",
},
navi_settings = {
"toc_alt_toc",

Loading…
Cancel
Save