KOSync: Clarify settings, plus refactor & fixes to make "auto-sync" more reliable (#10605)

Fix: #10539, and for context #6489, #6733, #6534

Reorganize and reword most of the settings to make it clear what actually ties into auto sync, and what doesn't. (Specifically, what happens when a pull attempts to sync forward or backward has nothing to do with auto sync, it applies in all cases; while the periodic sync *does* require auto sync).

The main point of contention, though, is that auto sync will now *always* attempt to setup network connectivity (i.e., on resume/suspend/close). Periodic sync will *not* though (the intent being that, if you use periodic sync, you're relying on the activity check to actually keep wifi on at all times)).

Since this may lead to a large amount of nagging about wifi toggles on devices w/ NetworkManager support, it is now *disabled* by default on those devices. (And given that it wouldn't have worked because of the lack of connectivity, that doesn't really make any practical difference ;p).

Additionally, given the fact that there's no way to make this behavior viable if the "before wifi" action is left at its default of "prompt", this feature now *requires* that to be set to "turn_on" (on devices where it can, of course); attempting to toggle it on will warn about that if necessary.
This change is retroactive (OTM).

Includes an assortment of fixes and cleanups, including migrating to the new LuaSettings API, which is why there's no longer a smattering of superfluous flushes.
reviewable/pr10627/r1^2
NiLuJe 11 months ago committed by GitHub
parent 7fddb1dedf
commit 08dd97384c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -84,10 +84,7 @@ end
function ReaderCoptListener:onCharging()
self:headerRefresh()
end
function ReaderCoptListener:onNotCharging()
self:headerRefresh()
end
ReaderCoptListener.onNotCharging = ReaderCoptListener.onCharging
function ReaderCoptListener:onTimeFormatChanged()
self.ui.document._document:setIntProperty("window.status.clock.12hours", G_reader_settings:isTrue("twelve_hour_clock") and 1 or 0)

@ -275,7 +275,7 @@ function ReaderDictionary:addToMainMenu(menu_items)
{
text = _("Enable fuzzy search"),
checked_func = function()
return not self.disable_fuzzy_search == true
return self.disable_fuzzy_search ~= true
end,
callback = function()
self.disable_fuzzy_search = not self.disable_fuzzy_search

@ -2485,35 +2485,24 @@ function ReaderFooter:maybeUpdateFooter()
self:onUpdateFooter(self:shouldBeRepainted())
end
-- is the same as maybeUpdateFooter
function ReaderFooter:onFrontlightStateChanged()
self:onUpdateFooter(self:shouldBeRepainted())
self:maybeUpdateFooter()
end
ReaderFooter.onCharging = ReaderFooter.onFrontlightStateChanged
ReaderFooter.onNotCharging = ReaderFooter.onFrontlightStateChanged
function ReaderFooter:onNetworkConnected()
if self.settings.wifi_status then
self:maybeUpdateFooter()
end
end
function ReaderFooter:onNetworkDisconnected()
if self.settings.wifi_status then
self:onUpdateFooter(self.view.footer_visible)
end
end
function ReaderFooter:onCharging()
self:maybeUpdateFooter()
end
function ReaderFooter:onNotCharging()
self:maybeUpdateFooter()
end
ReaderFooter.onNetworkDisconnected = ReaderFooter.onNetworkConnected
function ReaderFooter:onSetRotationMode()
self:updateFooterContainer()
self:resetLayout(true)
end
ReaderFooter.onScreenResize = ReaderFooter.onSetRotationMode
function ReaderFooter:onSetPageHorizMargins(h_margins)
self.book_margins_footer_width = math.floor((h_margins[1] + h_margins[2])/2)
@ -2523,11 +2512,6 @@ function ReaderFooter:onSetPageHorizMargins(h_margins)
end
end
function ReaderFooter:onScreenResize()
self:updateFooterContainer()
self:resetLayout(true)
end
function ReaderFooter:onTimeFormatChanged()
self:refreshFooter(true, true)
end

@ -244,7 +244,7 @@ function ReaderWikipedia:addToMainMenu(menu_items)
-- home_dir/Wikipedia/
if not G_reader_settings:readSetting("wikipedia_save_dir") then
local home_dir = G_reader_settings:readSetting("home_dir")
if not home_dir or not lfs.attributes(home_dir, "mode") == "directory" then
if not home_dir or lfs.attributes(home_dir, "mode") ~= "directory" then
home_dir = require("apps/filemanager/filemanagerutil").getDefaultDir()
end
home_dir = home_dir:gsub("^(.-)/*$", "%1") -- remove trailing slash

@ -312,7 +312,7 @@ function Device:onPowerEvent(ev)
if self:hasWifiToggle() then
local network_manager = require("ui/network/manager")
if network_manager:isWifiOn() then
network_manager:releaseIP()
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
network_manager:turnOffWifi()
end
end
@ -346,7 +346,7 @@ function Device:onPowerEvent(ev)
-- because suspend will at best fail, and at worst deadlock the system if Wi-Fi is on,
-- regardless of who enabled it!
if network_manager:isWifiOn() then
network_manager:releaseIP()
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
network_manager:turnOffWifi()
end
end

@ -436,7 +436,7 @@ function GestureDetector:probeClockSource(timev)
-- Finally, BOOTTIME
local boottime = time.boottime()
-- NOTE: It was implemented in Linux 2.6.39, so, reject 0, which would mean it's unsupported...
if not boottime == 0 and timev >= boottime - threshold and timev <= boottime + threshold then
if boottime ~= 0 and timev >= boottime - threshold and timev <= boottime + threshold then
self.clock_id = C.CLOCK_BOOTTIME
logger.dbg("GestureDetector:probeClockSource: Touch event timestamps appear to use CLOCK_BOOTTIME")
return

@ -7,7 +7,7 @@ local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
-- Date at which the last migration snippet was added
local CURRENT_MIGRATION_DATE = 20230531
local CURRENT_MIGRATION_DATE = 20230627
-- Retrieve the date of the previous migration, if any
local last_migration_date = G_reader_settings:readSetting("last_migration_date", 0)
@ -145,14 +145,16 @@ if last_migration_date < 20210330 then
if not ok or not ReaderStatistics then
logger.warn("Error when loading plugins/statistics.koplugin/main.lua:", ReaderStatistics)
else
local settings = G_reader_settings:readSetting("statistics", ReaderStatistics.default_settings)
-- Handle a snafu in 2021.03 that could lead to an empty settings table on fresh installs.
for k, v in pairs(ReaderStatistics.default_settings) do
if settings[k] == nil then
settings[k] = v
local settings = G_reader_settings:readSetting("statistics")
if settings then
-- Handle a snafu in 2021.03 that could lead to an empty settings table on fresh installs.
for k, v in pairs(ReaderStatistics.default_settings) do
if settings[k] == nil then
settings[k] = v
end
end
G_reader_settings:saveSetting("statistics", settings)
end
G_reader_settings:saveSetting("statistics", settings)
end
end
@ -514,5 +516,46 @@ if last_migration_date < 20230531 then
end
end
-- 20230627, Migrate to a full settings table, and disable KOSync's auto sync mode if wifi_enable_action is not turn_on
if last_migration_date < 20230627 then
logger.info("Performing one-time migration for 20230627")
-- c.f., PluginLoader
local package_path = package.path
package.path = string.format("%s/?.lua;%s", "plugins/kosync.koplugin", package_path)
local ok, KOSync = pcall(dofile, "plugins/kosync.koplugin/main.lua")
package.path = package_path
if not ok or not KOSync then
logger.warn("Error when loading plugins/kosync.koplugin/main.lua:", KOSync)
else
local settings = G_reader_settings:readSetting("kosync")
if settings then
-- Make sure the table is complete
for k, v in pairs(KOSync.default_settings) do
if settings[k] == nil then
settings[k] = v
end
end
-- Migrate the whisper_* keys
settings.sync_forward = settings.whisper_forward or KOSync.default_settings.sync_forward
settings.whisper_forward = nil
settings.sync_backward = settings.whisper_backward or KOSync.default_settings.sync_backward
settings.whisper_backward = nil
G_reader_settings:saveSetting("kosync", settings)
end
end
local Device = require("device")
if Device:hasWifiManager() and G_reader_settings:readSetting("wifi_enable_action") ~= "turn_on" then
local kosync = G_reader_settings:readSetting("kosync")
if kosync and kosync.auto_sync then
kosync.auto_sync = false
G_reader_settings:saveSetting("kosync", kosync)
end
end
end
-- We're done, store the current migration date
G_reader_settings:saveSetting("last_migration_date", CURRENT_MIGRATION_DATE)

@ -32,14 +32,15 @@ end
-- as quite a few things rely on it (KOSync, c.f. #5109; the network activity check, c.f., #6424).
function NetworkMgr:connectivityCheck(iter, callback, widget)
-- Give up after a while (restoreWifiAsync can take over 45s, so, try to cover that)...
if iter > 25 then
logger.info("Failed to restore Wi-Fi (after", iter, "iterations)!")
if iter > 180 then
logger.info("Failed to restore Wi-Fi (after", iter * 0.25, "seconds)!")
self.wifi_was_on = false
G_reader_settings:makeFalse("wifi_was_on")
-- If we abort, murder Wi-Fi and the async script first...
if Device:hasWifiManager() then
os.execute("pkill -TERM restore-wifi-async.sh 2>/dev/null")
end
-- We were never connected to begin with, so, no disconnecting broadcast required
self:turnOffWifi()
-- Handle the UI warning if it's from a beforeWifiAction...
@ -54,8 +55,8 @@ function NetworkMgr:connectivityCheck(iter, callback, widget)
if self.is_wifi_on and self.is_connected then
self.wifi_was_on = true
G_reader_settings:makeTrue("wifi_was_on")
logger.info("Wi-Fi successfully restored (after", iter * 0.25, "seconds)!")
UIManager:broadcastEvent(Event:new("NetworkConnected"))
logger.info("Wi-Fi successfully restored (after", iter, "iterations)!")
-- Handle the UI & callback if it's from a beforeWifiAction...
if widget then
@ -74,12 +75,12 @@ function NetworkMgr:connectivityCheck(iter, callback, widget)
end
end
else
UIManager:scheduleIn(2, self.connectivityCheck, self, iter + 1, callback, widget)
UIManager:scheduleIn(0.25, self.connectivityCheck, self, iter + 1, callback, widget)
end
end
function NetworkMgr:scheduleConnectivityCheck(callback, widget)
UIManager:scheduleIn(2, self.connectivityCheck, self, 1, callback, widget)
UIManager:scheduleIn(0.5, self.connectivityCheck, self, 1, callback, widget)
end
function NetworkMgr:init()
@ -298,6 +299,8 @@ function NetworkMgr:turnOnWifiAndWaitForConnection(callback)
-- This will handle sending the proper Event, manage wifi_was_on, as well as tearing down Wi-Fi in case of failures,
-- (i.e., much like getWifiToggleMenuTable).
self:scheduleConnectivityCheck(callback, info)
return info
end
--- This quirky internal flag is used for the rare beforeWifiAction -> afterWifiAction brackets.
@ -322,9 +325,9 @@ function NetworkMgr:beforeWifiAction(callback)
local wifi_enable_action = G_reader_settings:readSetting("wifi_enable_action")
if wifi_enable_action == "turn_on" then
self:turnOnWifiAndWaitForConnection(callback)
return self:turnOnWifiAndWaitForConnection(callback)
else
self:promptWifiOn(callback)
return self:promptWifiOn(callback)
end
end
@ -344,6 +347,7 @@ function NetworkMgr:afterWifiAction(callback)
callback()
end
elseif wifi_disable_action == "turn_off" then
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
self:turnOffWifi(callback)
else
self:promptWifiOff(callback)
@ -461,6 +465,53 @@ function NetworkMgr:willRerunWhenConnected(callback)
return false
end
-- And this one is for when you absolutely *need* to block until we're online to run something (e.g., because it runs in a finalizer).
function NetworkMgr:goOnlineToRun(callback)
if self:isOnline() then
callback()
return true
end
-- In case we abort before the beforeWifiAction, we won't pass it the callback, but run it ourselves,
-- to avoid it firing too late (or at the very least being pinned for too long).
local info = self:beforeWifiAction()
-- We'll basically do the same but in a blocking manner...
UIManager:unschedule(self.connectivityCheck)
local iter = 0
while not self.is_connected do
iter = iter + 1
if iter >= 120 then
logger.info("Failed to connect to Wi-Fi after 30s, giving up!")
self.wifi_was_on = false
G_reader_settings:makeFalse("wifi_was_on")
if info then
UIManager:close(info)
end
UIManager:show(InfoMessage:new{ text = _("Error connecting to the network") })
self:turnOffWifi()
return false
end
ffiutil.usleep(250000)
self:queryNetworkState()
end
-- Close the initial "Connecting..." InfoMessage from turnOnWifiAndWaitForConnection via beforeWifiAction
if info then
UIManager:close(info)
end
-- We're finally connected!
self.wifi_was_on = true
G_reader_settings:makeTrue("wifi_was_on")
callback()
-- Delay this so it won't fire for dead/dying instances in case we're called by a finalizer...
UIManager:scheduleIn(2, function()
UIManager:broadcastEvent(Event:new("NetworkConnected"))
end)
return true
end
function NetworkMgr:getWifiMenuTable()
if Device:isAndroid() then
@ -701,89 +752,90 @@ end
function NetworkMgr:reconnectOrShowNetworkMenu(complete_callback)
local info = InfoMessage:new{text = _("Scanning for networks…")}
UIManager:show(info)
UIManager:nextTick(function()
local network_list, err = self:getNetworkList()
UIManager:close(info)
UIManager:forceRePaint()
local network_list, err = self:getNetworkList()
UIManager:close(info)
if network_list == nil then
UIManager:show(InfoMessage:new{text = err})
return
end
-- NOTE: Fairly hackish workaround for #4387,
-- rescan if the first scan appeared to yield an empty list.
--- @fixme This *might* be an issue better handled in lj-wpaclient...
if #network_list == 0 then
logger.warn("Initial Wi-Fi scan yielded no results, rescanning")
network_list, err = self:getNetworkList()
if network_list == nil then
UIManager:show(InfoMessage:new{text = err})
return
end
-- NOTE: Fairly hackish workaround for #4387,
-- rescan if the first scan appeared to yield an empty list.
--- @fixme This *might* be an issue better handled in lj-wpaclient...
if #network_list == 0 then
logger.warn("Initial Wi-Fi scan yielded no results, rescanning")
network_list, err = self:getNetworkList()
if network_list == nil then
UIManager:show(InfoMessage:new{text = err})
return
end
end
end
table.sort(network_list,
function(l, r) return l.signal_quality > r.signal_quality end)
table.sort(network_list,
function(l, r) return l.signal_quality > r.signal_quality end)
local success = false
if self.wifi_toggle_long_press then
self.wifi_toggle_long_press = nil
else
local ssid
-- We need to do two passes, as we may have *both* an already connected network (from the global wpa config),
-- *and* preferred networks, and if the prferred networks have a better signal quality,
-- they'll be sorted *earlier*, which would cause us to try to associate to a different AP than
-- what wpa_supplicant is already trying to do...
for dummy, network in ipairs(network_list) do
if network.connected then
-- On platforms where we use wpa_supplicant (if we're calling this, we are),
-- the invocation will check its global config, and if an AP configured there is reachable,
-- it'll already have connected to it on its own.
success = true
ssid = network.ssid
break
end
local success = false
if self.wifi_toggle_long_press then
self.wifi_toggle_long_press = nil
else
local ssid
-- We need to do two passes, as we may have *both* an already connected network (from the global wpa config),
-- *and* preferred networks, and if the prferred networks have a better signal quality,
-- they'll be sorted *earlier*, which would cause us to try to associate to a different AP than
-- what wpa_supplicant is already trying to do...
for dummy, network in ipairs(network_list) do
if network.connected then
-- On platforms where we use wpa_supplicant (if we're calling this, we are),
-- the invocation will check its global config, and if an AP configured there is reachable,
-- it'll already have connected to it on its own.
success = true
ssid = network.ssid
break
end
end
-- Next, look for our own prferred networks...
local err_msg = _("Connection failed")
if not success then
for dummy, network in ipairs(network_list) do
if network.password then
-- If we hit a preferred network and we're not already connected,
-- attempt to connect to said preferred network....
success, err_msg = self:authenticateNetwork(network)
if success then
ssid = network.ssid
break
end
-- Next, look for our own prferred networks...
local err_msg = _("Connection failed")
if not success then
for dummy, network in ipairs(network_list) do
if network.password then
-- If we hit a preferred network and we're not already connected,
-- attempt to connect to said preferred network....
success, err_msg = self:authenticateNetwork(network)
if success then
ssid = network.ssid
break
end
end
end
end
if success then
self:obtainIP()
if complete_callback then
complete_callback()
end
UIManager:show(InfoMessage:new{
text = T(_("Connected to network %1"), BD.wrap(ssid)),
timeout = 3,
})
else
UIManager:show(InfoMessage:new{
text = err_msg,
timeout = 3,
})
if success then
self:obtainIP()
if complete_callback then
complete_callback()
end
end
if not success then
-- NOTE: Also supports a disconnect_callback, should we use it for something?
-- Tearing down Wi-Fi completely when tapping "disconnect" would feel a bit harsh, though...
UIManager:show(require("ui/widget/networksetting"):new{
network_list = network_list,
connect_callback = complete_callback,
UIManager:show(InfoMessage:new{
tag = "NetworkMgr", -- for crazy KOSync purposes
text = T(_("Connected to network %1"), BD.wrap(ssid)),
timeout = 3,
})
else
UIManager:show(InfoMessage:new{
text = err_msg,
timeout = 3,
})
end
end)
end
if not success then
-- NOTE: Also supports a disconnect_callback, should we use it for something?
-- Tearing down Wi-Fi completely when tapping "disconnect" would feel a bit harsh, though...
UIManager:show(require("ui/widget/networksetting"):new{
network_list = network_list,
connect_callback = complete_callback,
})
end
end
function NetworkMgr:saveNetwork(setting)

@ -39,6 +39,7 @@ function NetworkListener:onToggleWifi()
UIManager:show(toggle_im)
UIManager:forceRePaint()
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
NetworkMgr:turnOffWifi(complete_callback)
UIManager:close(toggle_im)
@ -60,6 +61,7 @@ function NetworkListener:onInfoWifiOff()
UIManager:show(toggle_im)
UIManager:forceRePaint()
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
NetworkMgr:turnOffWifi(complete_callback)
UIManager:close(toggle_im)
@ -166,6 +168,7 @@ function NetworkListener:_scheduleActivityCheck()
local complete_callback = function()
UIManager:broadcastEvent(Event:new("NetworkDisconnected"))
end
UIManager:broadcastEvent(Event:new("NetworkDisconnecting"))
NetworkMgr:turnOffWifi(complete_callback)
-- NOTE: We leave wifi_was_on as-is on purpose, we wouldn't want to break auto_restore_wifi workflows on the next start...
else

@ -240,8 +240,7 @@ function InfoMessage:onShow()
-- schedule us to close ourself if timeout provided
if self.timeout then
UIManager:scheduleIn(self.timeout, function()
-- In case we're provided with dismiss_callback, also call it
-- on timeout
-- In case we're provided with dismiss_callback, also call it on timeout
if self.dismiss_callback then
self.dismiss_callback()
self.dismiss_callback = nil

@ -11,6 +11,7 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer")
local logger = require("logger")
local md5 = require("ffi/sha2").md5
local random = require("random")
local time = require("ui/time")
local util = require("util")
local T = require("ffi/util").template
local _ = require("gettext")
@ -24,20 +25,21 @@ local KOSync = WidgetContainer:extend{
is_doc_only = true,
title = _("Register/login to KOReader server"),
page_update_times = 0,
last_page = -1,
last_page_turn_ticks = 0,
push_timestamp = nil,
pull_timestamp = nil,
page_update_counter = nil,
last_page = nil,
last_page_turn_timestamp = nil,
periodic_push_task = nil,
periodic_push_scheduled = nil,
settings = nil,
}
local SYNC_STRATEGY = {
-- Forward and backward whisper sync settings are using different
-- default value, so none of following opinions should be zero.
PROMPT = 1,
WHISPER = 2,
PROMPT = 1,
SILENT = 2,
DISABLE = 3,
DEFAULT_FORWARD = 1,
DEFAULT_BACKWARD = 3,
}
local CHECKSUM_METHOD = {
@ -45,6 +47,64 @@ local CHECKSUM_METHOD = {
FILENAME = 1
}
-- Debounce push/pull attempts
local API_CALL_DEBOUNCE_DELAY = time.s(25)
-- NOTE: This is used in a migration script by ui/data/onetime_migration,
-- which is why it's public.
KOSync.default_settings = {
custom_server = nil,
username = nil,
userkey = nil,
-- Do *not* default to auto-sync on devices w/ NetworkManager support, as wifi is unlikely to be on at all times there, and the nagging enabling this may cause requires careful consideration.
auto_sync = not Device:hasWifiManager(),
pages_before_update = nil,
sync_forward = SYNC_STRATEGY.PROMPT,
sync_backward = SYNC_STRATEGY.DISABLE,
checksum_method = CHECKSUM_METHOD.BINARY,
}
function KOSync:init()
self.push_timestamp = 0
self.pull_timestamp = 0
self.page_update_counter = 0
self.last_page = -1
self.last_page_turn_timestamp = 0
self.periodic_push_scheduled = false
-- Like AutoSuspend, we need an instance-specific task for scheduling/resource management reasons.
self.periodic_push_task = function()
self.periodic_push_scheduled = false
self.page_update_counter = 0
-- We do *NOT* want to make sure networking is up here, as the nagging would be extremely annoying; we're leaving that to the network activity check...
self:updateProgress(false, false)
end
self.settings = G_reader_settings:readSetting("kosync", self.default_settings)
self.device_id = G_reader_settings:readSetting("device_id")
-- Disable auto-sync if beforeWifiAction was reset to "prompt" behind our back...
if self.settings.auto_sync and Device:hasWifiManager() and G_reader_settings:readSetting("wifi_enable_action") ~= "turn_on" then
self.settings.auto_sync = false
logger.warn("KOSync: Automatic sync has been disabled because wifi_enable_action is *not* turn_on")
end
self.ui.menu:registerToMainMenu(self)
end
function KOSync:getSyncPeriod()
if not self.settings.auto_sync then
return _("Unavailable")
end
local period = self.settings.pages_before_update
if period and period > 0 then
return period
else
return _("Never")
end
end
local function getNameStrategy(type)
if type == 1 then
return _("Prompt")
@ -109,218 +169,224 @@ function KOSync:onDispatcherRegisterActions()
end
function KOSync:onReaderReady()
--- @todo: Viable candidate for a port to the new readSetting API
local settings = G_reader_settings:readSetting("kosync") or {}
self.kosync_custom_server = settings.custom_server
self.kosync_username = settings.username
self.kosync_userkey = settings.userkey
self.kosync_auto_sync = settings.auto_sync ~= false
self.kosync_pages_before_update = settings.pages_before_update
self.kosync_whisper_forward = settings.whisper_forward or SYNC_STRATEGY.DEFAULT_FORWARD
self.kosync_whisper_backward = settings.whisper_backward or SYNC_STRATEGY.DEFAULT_BACKWARD
self.kosync_checksum_method = settings.checksum_method or CHECKSUM_METHOD.BINARY
self.kosync_device_id = G_reader_settings:readSetting("device_id")
--assert(self.kosync_device_id)
if self.kosync_auto_sync then
self:_onResume()
-- Make sure checksum has been calculated before we ever query it,
-- to prevent document saving features from affecting the checksum,
-- and eventually affecting the document identity for the progress sync feature.
self.view.document:fastDigest(self.ui.doc_settings)
if self.settings.auto_sync then
UIManager:nextTick(function()
self:getProgress(true, false)
end)
end
self:registerEvents()
self:onDispatcherRegisterActions()
self.ui.menu:registerToMainMenu(self)
-- Make sure checksum has been calculated at the very first time a document has been opened, to
-- avoid document saving feature to impact the checksum, and eventually impact the document
-- identity in the progress sync feature.
self.view.document:fastDigest(self.ui.doc_settings)
self.last_page = self.ui:getCurrentPage()
end
function KOSync:addToMainMenu(menu_items)
menu_items.progress_sync = {
text = _("Progress sync"),
sub_item_table = {
{
text = _("Custom sync server"),
keep_menu_open = true,
tap_input_func = function()
return {
-- @translators Server address defined by user for progress sync.
title = _("Custom progress sync server address"),
input = self.settings.custom_server or "https://",
type = "text",
callback = function(input)
self:setCustomServer(input)
end,
}
end,
},
{
text_func = function()
return self.kosync_userkey and (_("Logout"))
return self.settings.userkey and (_("Logout"))
or _("Register") .. " / " .. _("Login")
end,
keep_menu_open = true,
callback_func = function()
if self.kosync_userkey then
if self.settings.userkey then
return function(menu)
self._menu_to_update = menu
self:logout()
self:logout(menu)
end
else
return function(menu)
self._menu_to_update = menu
self:login()
self:login(menu)
end
end
end,
separator = true,
},
{
text = _("Auto sync now and future"),
checked_func = function() return self.kosync_auto_sync end,
text = _("Automatically keep documents in sync"),
checked_func = function() return self.settings.auto_sync end,
help_text = _([[This may lead to nagging about toggling WiFi on document close and suspend/resume, depending on the device's connectivity.]]),
callback = function()
self.kosync_auto_sync = not self.kosync_auto_sync
-- Actively recommend switching the before wifi action to "turn_on" instead of prompt, as prompt will just not be practical (or even plain usable) here.
if Device:hasWifiManager() and G_reader_settings:readSetting("wifi_enable_action") ~= "turn_on" then
UIManager:show(InfoMessage:new{ text = _("You will have to switch the 'Action when Wi-Fi is off' Network setting to 'turn on' to be able to enable this feature!") })
return
end
self.settings.auto_sync = not self.settings.auto_sync
self:registerEvents()
if self.kosync_auto_sync then
-- since we will update the progress when closing document, we should pull
-- current progress now to avoid to overwrite it silently.
self:getProgress(true)
if self.settings.auto_sync then
-- Since we will update the progress when closing the document,
-- pull the current progress now so as not to silently overwrite it.
self:getProgress(true, true)
else
-- since we won't update the progress when closing document, we should push
-- current progress now to avoid to lose it silently.
self:updateProgress(true)
-- Since we won't update the progress when closing the document,
-- push the current progress now so as not to lose it.
self:updateProgress(true, true)
end
self:saveSettings()
end,
},
{
text = _("Whisper sync"),
enabled_func = function() return self.kosync_auto_sync end,
text_func = function()
return T(_("Periodically sync every # pages (%1)"), self:getSyncPeriod())
end,
enabled_func = function() return self.settings.auto_sync end,
-- This is the condition that allows enabling auto_disable_wifi in NetworkManager ;).
help_text = NetworkMgr:getNetworkInterfaceName() and _([[Unlike the automatic sync above, this will *not* attempt to setup a network connection, but instead relies on it being already up, and may trigger enough network activity to passively keep WiFi enabled!]]),
keep_menu_open = true,
callback = function(touchmenu_instance)
local SpinWidget = require("ui/widget/spinwidget")
local items = SpinWidget:new{
text = _([[This value determines how many page turns it takes to update book progress.
If set to 0, updating progress based on page turns will be disabled.]]),
value = self.settings.pages_before_update or 0,
value_min = 0,
value_max = 999,
value_step = 1,
value_hold_step = 10,
ok_text = _("Set"),
title_text = _("Number of pages before update"),
default_value = 0,
callback = function(spin)
self:setPagesBeforeUpdate(spin.value)
if touchmenu_instance then touchmenu_instance:updateItems() end
end
}
UIManager:show(items)
end,
separator = true,
},
{
text = _("Sync behavior"),
sub_item_table = {
{
text_func = function()
return T(_("Sync to latest record (%1)"), getNameStrategy(self.kosync_whisper_forward))
-- NOTE: With an up-to-date Sync server, "forward" means *newer*, not necessarily ahead in the document.
return T(_("Sync to a newer state (%1)"), getNameStrategy(self.settings.sync_forward))
end,
sub_item_table = {
{
text = _("Auto"),
text = _("Silently"),
checked_func = function()
return self.kosync_whisper_forward == SYNC_STRATEGY.WHISPER
return self.settings.sync_forward == SYNC_STRATEGY.SILENT
end,
callback = function()
self:setWhisperForward(SYNC_STRATEGY.WHISPER)
self:setSyncForward(SYNC_STRATEGY.SILENT)
end,
},
{
text = _("Prompt"),
checked_func = function()
return self.kosync_whisper_forward == SYNC_STRATEGY.PROMPT
return self.settings.sync_forward == SYNC_STRATEGY.PROMPT
end,
callback = function()
self:setWhisperForward(SYNC_STRATEGY.PROMPT)
self:setSyncForward(SYNC_STRATEGY.PROMPT)
end,
},
{
text = _("Disable"),
text = _("Never"),
checked_func = function()
return self.kosync_whisper_forward == SYNC_STRATEGY.DISABLE
return self.settings.sync_forward == SYNC_STRATEGY.DISABLE
end,
callback = function()
self:setWhisperForward(SYNC_STRATEGY.DISABLE)
self:setSyncForward(SYNC_STRATEGY.DISABLE)
end,
},
}
},
{
text_func = function()
return T(_("Sync to a previous record (%1)"), getNameStrategy(self.kosync_whisper_backward))
return T(_("Sync to an older state (%1)"), getNameStrategy(self.settings.sync_backward))
end,
sub_item_table = {
{
text = _("Auto"),
text = _("Silently"),
checked_func = function()
return self.kosync_whisper_backward == SYNC_STRATEGY.WHISPER
return self.settings.sync_backward == SYNC_STRATEGY.SILENT
end,
callback = function()
self:setWhisperBackward(SYNC_STRATEGY.WHISPER)
self:setSyncBackward(SYNC_STRATEGY.SILENT)
end,
},
{
text = _("Prompt"),
checked_func = function()
return self.kosync_whisper_backward == SYNC_STRATEGY.PROMPT
return self.settings.sync_backward == SYNC_STRATEGY.PROMPT
end,
callback = function()
self:setWhisperBackward(SYNC_STRATEGY.PROMPT)
self:setSyncBackward(SYNC_STRATEGY.PROMPT)
end,
},
{
text = _("Disable"),
text = _("Never"),
checked_func = function()
return self.kosync_whisper_backward == SYNC_STRATEGY.DISABLE
return self.settings.sync_backward == SYNC_STRATEGY.DISABLE
end,
callback = function()
self:setWhisperBackward(SYNC_STRATEGY.DISABLE)
self:setSyncBackward(SYNC_STRATEGY.DISABLE)
end,
},
}
},
},
separator = true,
},
{
text = _("Push progress from this device"),
text = _("Push progress from this device now"),
enabled_func = function()
return self.kosync_userkey ~= nil
return self.settings.userkey ~= nil
end,
callback = function()
self:updateProgress(true)
self:updateProgress(true, true)
end,
},
{
text = _("Pull progress from other devices"),
text = _("Pull progress from other devices now"),
enabled_func = function()
return self.kosync_userkey ~= nil
return self.settings.userkey ~= nil
end,
callback = function()
self:getProgress(true)
end,
},
{
text = _("Custom sync server"),
keep_menu_open = true,
tap_input_func = function()
return {
-- @translators Server address defined by user for progress sync.
title = _("Custom progress sync server address"),
input = self.kosync_custom_server or "https://",
type = "text",
callback = function(input)
self:setCustomServer(input)
end,
}
end,
},
{
text = _("Sync every # pages"),
keep_menu_open = true,
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local items = SpinWidget:new{
text = _([[This value determines how many page turns it takes to update book progress.
If set to 0, updating progress based on page turns will be disabled.]]),
value = self.kosync_pages_before_update or 0,
value_min = 0,
value_max = 999,
value_step = 1,
value_hold_step = 10,
ok_text = _("Set"),
title_text = _("Number of pages before update"),
default_value = 0,
callback = function(spin)
self:setPagesBeforeUpdate(spin.value)
end
}
UIManager:show(items)
self:getProgress(true, true)
end,
separator = true,
},
{
text = _("Document matching method"),
sub_item_table = {
{
text = _("Binary. Only identical files will sync progress."),
text = _("Binary. Only identical files will be kept in sync."),
checked_func = function()
return self.kosync_checksum_method == CHECKSUM_METHOD.BINARY
return self.settings.checksum_method == CHECKSUM_METHOD.BINARY
end,
callback = function()
self:setChecksumMethod(CHECKSUM_METHOD.BINARY)
end,
},
{
text = _("Filename. Files with the same name will sync progress."),
text = _("Filename. Files with matching names will be kept in sync."),
checked_func = function()
return self.kosync_checksum_method == CHECKSUM_METHOD.FILENAME
return self.settings.checksum_method == CHECKSUM_METHOD.FILENAME
end,
callback = function()
self:setChecksumMethod(CHECKSUM_METHOD.FILENAME)
@ -333,33 +399,28 @@ If set to 0, updating progress based on page turns will be disabled.]]),
end
function KOSync:setPagesBeforeUpdate(pages_before_update)
self.kosync_pages_before_update = pages_before_update > 0 and pages_before_update or nil
self:saveSettings()
self.settings.pages_before_update = pages_before_update > 0 and pages_before_update or nil
end
function KOSync:setCustomServer(server)
logger.dbg("set custom server", server)
self.kosync_custom_server = server ~= "" and server or nil
self:saveSettings()
logger.dbg("KOSync: Setting custom server to:", server)
self.settings.custom_server = server ~= "" and server or nil
end
function KOSync:setWhisperForward(strategy)
self.kosync_whisper_forward = strategy
self:saveSettings()
function KOSync:setSyncForward(strategy)
self.settings.sync_forward = strategy
end
function KOSync:setWhisperBackward(strategy)
self.kosync_whisper_backward = strategy
self:saveSettings()
function KOSync:setSyncBackward(strategy)
self.settings.sync_backward = strategy
end
function KOSync:setChecksumMethod(method)
self.kosync_checksum_method = method
self:saveSettings()
self.settings.checksum_method = method
end
function KOSync:login()
if NetworkMgr:willRerunWhenOnline(function() self:login() end) then
function KOSync:login(menu)
if NetworkMgr:willRerunWhenOnline(function() self:login(menu) end) then
return
end
@ -368,7 +429,7 @@ function KOSync:login()
title = self.title,
fields = {
{
text = self.kosync_username,
text = self.settings.username,
hint = "username",
},
{
@ -398,7 +459,7 @@ function KOSync:login()
else
UIManager:close(dialog)
UIManager:scheduleIn(0.5, function()
self:doLogin(username, password)
self:doLogin(username, password, menu)
end)
UIManager:show(InfoMessage:new{
text = _("Logging in. Please wait…"),
@ -420,7 +481,7 @@ function KOSync:login()
else
UIManager:close(dialog)
UIManager:scheduleIn(0.5, function()
self:doRegister(username, password)
self:doRegister(username, password, menu)
end)
UIManager:show(InfoMessage:new{
text = _("Registering. Please wait…"),
@ -436,10 +497,10 @@ function KOSync:login()
dialog:onShowKeyboard()
end
function KOSync:doRegister(username, password)
function KOSync:doRegister(username, password, menu)
local KOSyncClient = require("KOSyncClient")
local client = KOSyncClient:new{
custom_url = self.kosync_custom_server,
custom_url = self.settings.custom_server,
service_spec = self.path .. "/api.json"
}
-- on Android to avoid ANR (no-op on other platforms)
@ -458,9 +519,11 @@ function KOSync:doRegister(username, password)
})
end
elseif status then
self.kosync_username = username
self.kosync_userkey = userkey
self._menu_to_update:updateItems()
self.settings.username = username
self.settings.userkey = userkey
if menu then
menu:updateItems()
end
UIManager:show(InfoMessage:new{
text = _("Registered to KOReader server."),
})
@ -470,13 +533,12 @@ function KOSync:doRegister(username, password)
})
end
Device:setIgnoreInput(false)
self:saveSettings()
end
function KOSync:doLogin(username, password)
function KOSync:doLogin(username, password, menu)
local KOSyncClient = require("KOSyncClient")
local client = KOSyncClient:new{
custom_url = self.kosync_custom_server,
custom_url = self.settings.custom_server,
service_spec = self.path .. "/api.json"
}
Device:setIgnoreInput(true)
@ -496,9 +558,11 @@ function KOSync:doLogin(username, password)
Device:setIgnoreInput(false)
return
elseif status then
self.kosync_username = username
self.kosync_userkey = userkey
self._menu_to_update:updateItems()
self.settings.username = username
self.settings.userkey = userkey
if menu then
menu:updateItems()
end
UIManager:show(InfoMessage:new{
text = _("Logged in to KOReader server."),
})
@ -508,14 +572,14 @@ function KOSync:doLogin(username, password)
})
end
Device:setIgnoreInput(false)
self:saveSettings()
end
function KOSync:logout()
self.kosync_userkey = nil
self.kosync_auto_sync = true
self._menu_to_update:updateItems()
self:saveSettings()
function KOSync:logout(menu)
self.settings.userkey = nil
self.settings.auto_sync = true
if menu then
menu:updateItems()
end
end
function KOSync:getLastPercent()
@ -535,7 +599,7 @@ function KOSync:getLastProgress()
end
function KOSync:getDocumentDigest()
if self.kosync_checksum_method == CHECKSUM_METHOD.FILENAME then
if self.settings.checksum_method == CHECKSUM_METHOD.FILENAME then
return self:getFileNameDigest()
else
return self:getFileDigest()
@ -543,7 +607,7 @@ function KOSync:getDocumentDigest()
end
function KOSync:getFileDigest()
return self.view.document:fastDigest()
return self.ui.doc_settings:readSetting("partial_md5_checksum")
end
function KOSync:getFileNameDigest()
@ -557,7 +621,7 @@ function KOSync:getFileNameDigest()
end
function KOSync:syncToProgress(progress)
logger.dbg("sync to", progress)
logger.dbg("KOSync: [Sync] progress to", progress)
if self.ui.document.info.has_pages then
self.ui:handleEvent(Event:new("GotoPage", tonumber(progress)))
else
@ -565,21 +629,27 @@ function KOSync:syncToProgress(progress)
end
end
function KOSync:updateProgress(manual)
if not self.kosync_username or not self.kosync_userkey then
if manual then
function KOSync:updateProgress(ensure_networking, interactive, refresh_on_success)
if not self.settings.username or not self.settings.userkey then
if interactive then
promptLogin()
end
return
end
if manual and NetworkMgr:willRerunWhenOnline(function() self:updateProgress(manual) end) then
local now = UIManager:getElapsedTimeSinceBoot()
if not interactive and now - self.push_timestamp <= API_CALL_DEBOUNCE_DELAY then
logger.dbg("KOSync: We've already pushed progress less than 25s ago!")
return
end
if ensure_networking and NetworkMgr:willRerunWhenOnline(function() self:updateProgress(ensure_networking, interactive, refresh_on_success) end) then
return
end
local KOSyncClient = require("KOSyncClient")
local client = KOSyncClient:new{
custom_url = self.kosync_custom_server,
custom_url = self.settings.custom_server,
service_spec = self.path .. "/api.json"
}
local doc_digest = self:getDocumentDigest()
@ -587,16 +657,17 @@ function KOSync:updateProgress(manual)
local percentage = self:getLastPercent()
local ok, err = pcall(client.update_progress,
client,
self.kosync_username,
self.kosync_userkey,
self.settings.username,
self.settings.userkey,
doc_digest,
progress,
percentage,
Device.model,
self.kosync_device_id,
self.device_id,
function(ok, body)
logger.dbg("update progress for", self.view.document.file, ok)
if manual then
logger.dbg("KOSync: [Push] progress to", percentage * 100, "% =>", progress, "for", self.view.document.file)
logger.dbg("KOSync: ok:", ok, "body:", body)
if interactive then
if ok then
UIManager:show(InfoMessage:new{
text = _("Progress has been pushed."),
@ -608,45 +679,67 @@ function KOSync:updateProgress(manual)
end
end)
if not ok then
if manual then showSyncError() end
if interactive then showSyncError() end
if err then logger.dbg("err:", err) end
else
-- This is solely for onSuspend's sake, to clear the ghosting left by the the "Connected" InfoMessage
if refresh_on_success then
-- Our top-level widget should be the "Connected to network" InfoMessage from NetworkMgr's reconnectOrShowNetworkMenu
local widget = UIManager:getTopmostVisibleWidget()
if widget and widget.modal and widget.tag == "NetworkMgr" and not widget.dismiss_callback then
-- We want a full-screen flash on dismiss
widget.dismiss_callback = function()
-- Enqueued, because we run before the InfoMessage's close
UIManager:setDirty(nil, "full")
end
end
end
end
self.push_timestamp = now
end
function KOSync:getProgress(manual)
if not self.kosync_username or not self.kosync_userkey then
if manual then
function KOSync:getProgress(ensure_networking, interactive)
if not self.settings.username or not self.settings.userkey then
if interactive then
promptLogin()
end
return
end
if manual and NetworkMgr:willRerunWhenOnline(function() self:getProgress(manual) end) then
local now = UIManager:getElapsedTimeSinceBoot()
if not interactive and now - self.pull_timestamp <= API_CALL_DEBOUNCE_DELAY then
logger.dbg("KOSync: We've already pulled progress less than 25s ago!")
return
end
if ensure_networking and NetworkMgr:willRerunWhenOnline(function() self:getProgress(ensure_networking, interactive) end) then
return
end
local KOSyncClient = require("KOSyncClient")
local client = KOSyncClient:new{
custom_url = self.kosync_custom_server,
custom_url = self.settings.custom_server,
service_spec = self.path .. "/api.json"
}
local doc_digest = self:getDocumentDigest()
local ok, err = pcall(client.get_progress,
client,
self.kosync_username,
self.kosync_userkey,
self.settings.username,
self.settings.userkey,
doc_digest,
function(ok, body)
logger.dbg("get progress for", self.view.document.file, ok, body)
logger.dbg("KOSync: [Pull] progress for", self.view.document.file)
logger.dbg("KOSync: ok:", ok, "body:", body)
if not ok or not body then
if manual then
if interactive then
showSyncError()
end
return
end
if not body.percentage then
if manual then
if interactive then
UIManager:show(InfoMessage:new{
text = _("No progress found for this document."),
timeout = 3,
@ -656,8 +749,8 @@ function KOSync:getProgress(manual)
end
if body.device == Device.model
and body.device_id == self.kosync_device_id then
if manual then
and body.device_id == self.device_id then
if interactive then
UIManager:show(InfoMessage:new{
text = _("Latest progress is coming from this device."),
timeout = 3,
@ -669,11 +762,11 @@ function KOSync:getProgress(manual)
body.percentage = Math.roundPercent(body.percentage)
local progress = self:getLastProgress()
local percentage = self:getLastPercent()
logger.dbg("current progress", percentage)
logger.dbg("KOSync: Current progress:", percentage * 100, "% =>", progress)
if percentage == body.percentage
or body.progress == progress then
if manual then
if interactive then
UIManager:show(InfoMessage:new{
text = _("The progress has already been synchronized."),
timeout = 3,
@ -683,9 +776,9 @@ function KOSync:getProgress(manual)
end
-- The progress needs to be updated.
if manual then
-- If user actively pulls progress from other devices, we always update the
-- progress without further confirmation.
if interactive then
-- If user actively pulls progress from other devices,
-- we always update the progress without further confirmation.
self:syncToProgress(body.progress)
showSyncedMessage()
return
@ -693,17 +786,16 @@ function KOSync:getProgress(manual)
local self_older
if body.timestamp ~= nil then
self_older = (body.timestamp > self.last_page_turn_ticks)
self_older = (body.timestamp > self.last_page_turn_timestamp)
else
-- If we are working with old sync server, we can only use
-- percentage field.
-- If we are working with an old sync server, we can only use the percentage field.
self_older = (body.percentage > percentage)
end
if self_older then
if self.kosync_whisper_forward == SYNC_STRATEGY.WHISPER then
if self.settings.sync_forward == SYNC_STRATEGY.SILENT then
self:syncToProgress(body.progress)
showSyncedMessage()
elseif self.kosync_whisper_forward == SYNC_STRATEGY.PROMPT then
elseif self.settings.sync_forward == SYNC_STRATEGY.PROMPT then
UIManager:show(ConfirmBox:new{
text = T(_("Sync to latest location %1% from device '%2'?"),
Math.round(body.percentage * 100),
@ -714,10 +806,10 @@ function KOSync:getProgress(manual)
})
end
else -- if not self_older then
if self.kosync_whisper_backward == SYNC_STRATEGY.WHISPER then
if self.settings.sync_backward == SYNC_STRATEGY.SILENT then
self:syncToProgress(body.progress)
showSyncedMessage()
elseif self.kosync_whisper_backward == SYNC_STRATEGY.PROMPT then
elseif self.settings.sync_backward == SYNC_STRATEGY.PROMPT then
UIManager:show(ConfirmBox:new{
text = T(_("Sync to previous location %1% from device '%2'?"),
Math.round(body.percentage * 100),
@ -730,36 +822,30 @@ function KOSync:getProgress(manual)
end
end)
if not ok then
if manual then showSyncError() end
if interactive then showSyncError() end
if err then logger.dbg("err:", err) end
end
self.pull_timestamp = now
end
function KOSync:saveSettings()
local settings = {
custom_server = self.kosync_custom_server,
username = self.kosync_username,
userkey = self.kosync_userkey,
auto_sync = self.kosync_auto_sync,
pages_before_update = self.kosync_pages_before_update,
whisper_forward =
(self.kosync_whisper_forward ~= SYNC_STRATEGY.DEFAULT_FORWARD
and self.kosync_whisper_forward
or nil),
whisper_backward =
(self.kosync_whisper_backward ~= SYNC_STRATEGY.DEFAULT_BACKWARD
and self.kosync_whisper_backward
or nil),
checksum_method = self.kosync_checksum_method,
}
G_reader_settings:saveSetting("kosync", settings)
function KOSync:_onCloseDocument()
logger.dbg("KOSync: onCloseDocument")
-- NOTE: Because we'll lose the document instance on return, we need to *block* until the connection is actually up here,
-- we cannot rely on willRerunWhenOnline, because if we're not currently online,
-- it *will* return early, and that means the actual callback *will* run *after* teardown of the document instance
-- (and quite likely ours, too).
NetworkMgr:goOnlineToRun(function()
-- Drop the inner willRerunWhenOnline ;).
self:updateProgress(false, false)
end)
end
function KOSync:onCloseDocument()
logger.dbg("on close document")
if self.kosync_auto_sync then
self:updateProgress()
end
function KOSync:schedulePeriodicPush()
UIManager:unschedule(self.periodic_push_task)
-- Use a sizable delay to make debouncing this on skim feasible...
UIManager:scheduleIn(10, self.periodic_push_task)
self.periodic_push_scheduled = true
end
function KOSync:_onPageUpdate(page)
@ -767,54 +853,81 @@ function KOSync:_onPageUpdate(page)
return
end
if self.last_page == -1 then
self.last_page = page
elseif self.last_page ~= page then
if self.last_page ~= page then
self.last_page = page
self.last_page_turn_ticks = os.time()
self.page_update_times = self.page_update_times + 1
if self.kosync_pages_before_update and self.page_update_times == self.kosync_pages_before_update then
self.page_update_times = 0
UIManager:scheduleIn(1, function() self:updateProgress() end)
self.last_page_turn_timestamp = os.time()
self.page_update_counter = self.page_update_counter + 1
-- If we've already scheduled a push, regardless of the counter's state, delay it until we're *actually* idle
if self.periodic_push_scheduled or self.settings.pages_before_update and self.page_update_counter >= self.settings.pages_before_update then
self:schedulePeriodicPush()
end
end
end
function KOSync:_onResume()
UIManager:scheduleIn(1, function() self:getProgress() end)
logger.dbg("KOSync: onResume")
-- If we have auto_restore_wifi enabled, skip this to prevent both the "Connecting..." UI to pop-up,
-- *and* a duplicate NetworkConnected event from firing...
if Device:hasWifiManager() and NetworkMgr.wifi_was_on and G_reader_settings:isTrue("auto_restore_wifi") then
return
end
-- And if we don't, this *will* (attempt to) trigger a connection and as such a NetworkConnected event,
-- but only a single pull will happen, since getProgress debounces itself.
UIManager:scheduleIn(1, function()
self:getProgress(true, false)
end)
end
function KOSync:_onFlushSettings()
if self.ui == nil or self.ui.document == nil then return end
self:updateProgress()
function KOSync:_onSuspend()
logger.dbg("KOSync: onSuspend")
-- We request an extra flashing refresh on success, to deal with potential ghosting left by the NetworkMgr UI
self:updateProgress(true, false, true)
end
function KOSync:_onNetworkConnected()
self:_onResume()
logger.dbg("KOSync: onNetworkConnected")
UIManager:scheduleIn(0.5, function()
-- Network is supposed to be on already, don't wrap this in willRerunWhenOnline
self:getProgress(false, false)
end)
end
function KOSync:_onNetworkDisconnecting()
logger.dbg("KOSync: onNetworkDisconnecting")
-- Network is supposed to be on already, don't wrap this in willRerunWhenOnline
self:updateProgress(false, false)
end
function KOSync:onKOSyncPushProgress()
if not self.kosync_userkey then return end
self:updateProgress(true)
self:updateProgress(true, true)
end
function KOSync:onKOSyncPullProgress()
if not self.kosync_userkey then return end
self:getProgress(true)
self:getProgress(true, true)
end
function KOSync:registerEvents()
if self.kosync_auto_sync then
if self.settings.auto_sync then
self.onCloseDocument = self._onCloseDocument
self.onPageUpdate = self._onPageUpdate
self.onResume = self._onResume
self.onFlushSettings = self._onFlushSettings
self.onSuspend = self._onSuspend
self.onNetworkConnected = self._onNetworkConnected
self.onNetworkDisconnecting = self._onNetworkDisconnecting
else
self.onCloseDocument = nil
self.onPageUpdate = nil
self.onResume = nil
self.onFlushSettings = nil
self.onSuspend = nil
self.onNetworkConnected = nil
self.onNetworkDisconnecting = nil
end
end
function KOSync:onCloseWidget()
UIManager:unschedule(self.periodic_push_task)
self.periodic_push_task = nil
end
return KOSync

Loading…
Cancel
Save