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{ local ReaderLink = InputContainer:extend{
location_stack = nil, -- table, per-instance location_stack = nil, -- table, per-instance
forward_location_stack = nil, -- table, per-instance
_external_link_buttons = nil, _external_link_buttons = nil,
} }
@ -250,7 +251,7 @@ ReaderLink.onPhysicalKeyboardConnected = ReaderLink.registerKeyEvents
function ReaderLink:onReadSettings(config) function ReaderLink:onReadSettings(config)
-- called when loading new document -- called when loading new document
self.location_stack = {} self:onClearLocationStack()
end end
local function isTapToFollowLinksOn() local function isTapToFollowLinksOn()
@ -306,6 +307,21 @@ function ReaderLink:addToMainMenu(menu_items)
}) })
end, 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 if not Device:isTouchDevice() then
-- Menu items below aren't needed. -- Menu items below aren't needed.
return return
@ -662,19 +678,40 @@ function ReaderLink:onTap(_, ges)
end end
end end
--- Remember current location so we can go back to it function ReaderLink:getCurrentLocation()
function ReaderLink:addCurrentLocationToStack() local location
if self.ui.document.info.has_pages then if self.ui.document.info.has_pages then
table.insert(self.location_stack, self.ui.paging:getBookLocation()) location = self.ui.paging:getBookLocation()
else else
table.insert(self.location_stack, { location = {xpointer = self.ui.rolling:getBookLocation(),}
xpointer = self.ui.rolling:getBookLocation(),
})
end 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 end
function ReaderLink:onClearLocationStack(show_notification) function ReaderLink:onClearLocationStack(show_notification)
self.location_stack = {} self.location_stack = {}
self:onClearForwardLocationStack()
if show_notification then if show_notification then
UIManager:show(Notification:new{ UIManager:show(Notification:new{
text = _("Location history cleared."), text = _("Location history cleared."),
@ -683,6 +720,11 @@ function ReaderLink:onClearLocationStack(show_notification)
return true return true
end end
function ReaderLink:onClearForwardLocationStack()
self.forward_location_stack = {}
return true
end
function ReaderLink:getPreviousLocationPages() function ReaderLink:getPreviousLocationPages()
local previous_locations = {} local previous_locations = {}
if #self.location_stack > 0 then 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, marker_xpointer = link.from_xpointer,
} }
end end
table.insert(self.location_stack, saved_location) self:addCurrentLocationToStack(saved_location)
else else
self:addCurrentLocationToStack() self:addCurrentLocationToStack()
end end
@ -827,6 +869,24 @@ end
function ReaderLink:onGoBackLink(show_notification_if_empty) function ReaderLink:onGoBackLink(show_notification_if_empty)
local saved_location = table.remove(self.location_stack) local saved_location = table.remove(self.location_stack)
if saved_location then 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) logger.dbg("GoBack: restoring:", saved_location)
self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location)) self.ui:handleEvent(Event:new('RestoreBookLocation', saved_location))
return true return true
@ -837,6 +897,26 @@ function ReaderLink:onGoBackLink(show_notification_if_empty)
end end
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) function ReaderLink:onSwipe(arg, ges)
local direction = BD.flipDirectionIfMirroredUILayout(ges.direction) local direction = BD.flipDirectionIfMirroredUILayout(ges.direction)
if direction == "east" then if direction == "east" then

@ -123,6 +123,7 @@ local settingsList = {
skim = {category="none", event="ShowSkimtoDialog", title=_("Skim document"), reader=true}, skim = {category="none", event="ShowSkimtoDialog", title=_("Skim document"), reader=true},
back = {category="none", event="Back", title=_("Back"), 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}, 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}, 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_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}, 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", "latest_bookmark",
"back", "back",
"previous_location", "previous_location",
"next_location",
"follow_nearest_link", "follow_nearest_link",
"follow_nearest_internal_link", "follow_nearest_internal_link",
"clear_location_history", "clear_location_history",

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

Loading…
Cancel
Save