Upload most recent update of standard plugin prior to any personal tweaks
This commit is contained in:
8
pinpadlockscreen.koplugin/_meta.lua
Normal file
8
pinpadlockscreen.koplugin/_meta.lua
Normal file
@@ -0,0 +1,8 @@
|
||||
local _ = require("gettext")
|
||||
|
||||
return {
|
||||
name = "pinpadlock",
|
||||
fullname = _("PIN Pad Lock Screen"),
|
||||
description = _([[Lock the device with a PIN code]]),
|
||||
version = "v1.1.0"
|
||||
}
|
||||
165
pinpadlockscreen.koplugin/main.lua
Normal file
165
pinpadlockscreen.koplugin/main.lua
Normal file
@@ -0,0 +1,165 @@
|
||||
--[[
|
||||
Author: Lena2309 (better lock management, boot hooking, event listening, ...), yogi81 (original inspiration and main skeleton)
|
||||
Inspiration and original skeleton from `https://github.com/yogi81/screenlock_koreader_plugin/tree/main`
|
||||
Description: implements a screen lock mechanism for KOReader
|
||||
using a PIN pad interface. Also adds a menu entry in Settings -> Screen
|
||||
]]
|
||||
|
||||
local Dispatcher = require("dispatcher")
|
||||
local PinPadDialog = require("ui/pinpaddialog")
|
||||
local EventListener = require("ui/widget/eventlistener")
|
||||
local _ = require("gettext")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local MenuEntryItems = require("menu/menuentryitems")
|
||||
local logger = require("logger")
|
||||
|
||||
-- Default settings
|
||||
if G_reader_settings:hasNot("pinpadlock_pin_code") then
|
||||
G_reader_settings:saveSetting("pinpadlock_pin_code", "1234")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_activated") then
|
||||
G_reader_settings:makeFalse("pinpadlock_activated")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_correct_pin_message_activated") then
|
||||
G_reader_settings:makeTrue("pinpadlock_correct_pin_message_activated")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_timeout_time") then
|
||||
G_reader_settings:saveSetting("pinpadlock_timeout_time", "30")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_max_tries") then
|
||||
G_reader_settings:saveSetting("pinpadlock_max_tries", "3")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_show_message") then
|
||||
G_reader_settings:makeFalse("pinpadlock_show_message")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_message") then
|
||||
G_reader_settings:saveSetting("pinpadlock_message", "Locked")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_message_position") then
|
||||
G_reader_settings:saveSetting("pinpadlock_message_position", "top")
|
||||
end
|
||||
if G_reader_settings:hasNot("pinpadlock_message_alignment") then
|
||||
G_reader_settings:saveSetting("pinpadlock_message_alignment", "center")
|
||||
end
|
||||
if G_reader_settings:hasNot("suspended_device") then
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
local ScreenLock = EventListener:extend {
|
||||
pinPadDialog = nil,
|
||||
}
|
||||
|
||||
function ScreenLock:erasePinPadDialog()
|
||||
if self.pinPadDialog then
|
||||
self.pinPadDialog:close(function()
|
||||
self.pinPadDialog = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- DEVICE LISTENER OVERRIDE
|
||||
------------------------------------------------------------------------------
|
||||
local ref_self = nil
|
||||
local _original_PowerOff = UIManager.poweroff_action
|
||||
UIManager.poweroff_action = function()
|
||||
logger.warn("in suspend ref_self: " .. tostring(ref_self))
|
||||
if ref_self then
|
||||
logger.warn("before erase dialog: " .. tostring(ref_self))
|
||||
ref_self:erasePinPadDialog()
|
||||
logger.warn("after erase dialog: " .. tostring(ref_self))
|
||||
end
|
||||
UIManager:nextTick(function()
|
||||
_original_PowerOff()
|
||||
end)
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- REGISTER DISPATCHER ACTIONS
|
||||
------------------------------------------------------------------------------
|
||||
function ScreenLock:onDispatcherRegisterActions()
|
||||
Dispatcher:registerAction("screenlock_pin_pad_lock_screen", {
|
||||
category = "none",
|
||||
event = "LockScreenPinPad",
|
||||
title = _("Lock Screen (PinPad)"),
|
||||
filemanager = true,
|
||||
device = true,
|
||||
})
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- EVENT LISTENING
|
||||
------------------------------------------------------------------------------
|
||||
---KOReader exit and restart
|
||||
function ScreenLock:onExit()
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
function ScreenLock:onRestart()
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
--- Device suspension, reboot or power off
|
||||
function ScreenLock:onRequestSuspend()
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
function ScreenLock:onRequestReboot()
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
function ScreenLock:onRequestPowerOff()
|
||||
G_reader_settings:makeTrue("suspended_device")
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- INIT & WAKE-UP HANDLING
|
||||
------------------------------------------------------------------------------
|
||||
function ScreenLock:init()
|
||||
self:onDispatcherRegisterActions()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
|
||||
ref_self = self
|
||||
if G_reader_settings:isTrue("pinpadlock_activated") and G_reader_settings:isTrue("suspended_device") then
|
||||
ref_self:lockScreen()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ScreenLock:onResume()
|
||||
if G_reader_settings:isTrue("pinpadlock_activated") then
|
||||
self:lockScreen()
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- DISPATCHER HANDLER
|
||||
------------------------------------------------------------------------------
|
||||
function ScreenLock:onLockScreen()
|
||||
self:lockScreen()
|
||||
return true
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- LOCK SCREEN
|
||||
------------------------------------------------------------------------------
|
||||
function ScreenLock:lockScreen()
|
||||
ref_self = self
|
||||
UIManager:nextTick(function()
|
||||
if self.pinPadDialog then self.pinPadDialog:closeDialogs() end
|
||||
|
||||
self.pinPadDialog = PinPadDialog:init()
|
||||
self.pinPadDialog:showPinPad()
|
||||
end)
|
||||
ref_self = self
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
--- MAIN MENU ENTRY
|
||||
------------------------------------------------------------------------------
|
||||
function ScreenLock:addToMainMenu(menu_items)
|
||||
menu_items.pinpad = MenuEntryItems
|
||||
end
|
||||
|
||||
return ScreenLock
|
||||
135
pinpadlockscreen.koplugin/menu/menuentryitems.lua
Normal file
135
pinpadlockscreen.koplugin/menu/menuentryitems.lua
Normal file
@@ -0,0 +1,135 @@
|
||||
--[[
|
||||
Author: Lena2309
|
||||
Description: Displays items in the Screen Menu Entry to manage the plugin
|
||||
]]
|
||||
|
||||
local PinPadMenuEntry = require("menu/pinpadmenuentry")
|
||||
local _ = require("gettext")
|
||||
|
||||
return {
|
||||
text = _("PIN Pad Lock"),
|
||||
sorting_hint = "screen",
|
||||
sub_item_table = {
|
||||
{
|
||||
text = _("Activated"),
|
||||
checked_func = function()
|
||||
return PinPadMenuEntry:pinPadEnabled()
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:toggle("pinpadlock_activated")
|
||||
end,
|
||||
separator = true,
|
||||
},
|
||||
{
|
||||
text = _("Manage PIN Code"),
|
||||
keep_menu_open = true,
|
||||
sub_item_table = {
|
||||
{
|
||||
text = _("Change PIN Code"),
|
||||
callback = function()
|
||||
PinPadMenuEntry:changePinCode()
|
||||
end
|
||||
},
|
||||
{
|
||||
text = _("Reset PIN Code"),
|
||||
callback = function()
|
||||
PinPadMenuEntry:resetPinCode()
|
||||
end,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
text = _("PIN pad lock message"),
|
||||
separator = true,
|
||||
sub_item_table = {
|
||||
{
|
||||
text = _("Add custom message to lock"),
|
||||
checked_func = function()
|
||||
return PinPadMenuEntry:showMessageEnabled()
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:toggle("pinpadlock_show_message")
|
||||
end,
|
||||
separator = true,
|
||||
},
|
||||
{
|
||||
text = _("Edit PIN pad lock message"),
|
||||
enabled_func = function()
|
||||
return PinPadMenuEntry:showMessageEnabled()
|
||||
end,
|
||||
keep_menu_open = true,
|
||||
callback = function()
|
||||
PinPadMenuEntry:setMessage()
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Message position"),
|
||||
enabled_func = function()
|
||||
return PinPadMenuEntry:showMessageEnabled()
|
||||
end,
|
||||
sub_item_table = {
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Top"), "pinpadlock_message_position", "top"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Middle"), "pinpadlock_message_position", "middle"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Bottom"), "pinpadlock_message_position", "bottom"),
|
||||
},
|
||||
},
|
||||
{
|
||||
text = _("Message alignment"),
|
||||
enabled_func = function()
|
||||
return PinPadMenuEntry:showMessageEnabled()
|
||||
end,
|
||||
sub_item_table = {
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Left"), "pinpadlock_message_alignment", "left"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Center"), "pinpadlock_message_alignment", "center"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("Right"), "pinpadlock_message_alignment", "right"),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
text = _("Advanced Settings"),
|
||||
sub_item_table = {
|
||||
{
|
||||
text = _("Activate correct PIN pop-up"),
|
||||
checked_func = function()
|
||||
return PinPadMenuEntry:correctPinMessageEnabled()
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:toggle("pinpadlock_correct_pin_message_activated")
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Display entered digit before hiding it"),
|
||||
checked_func = function()
|
||||
return PinPadMenuEntry:displayDigitEnabled()
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:toggle("pinpadlock_display_digit_activated")
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Set Timeout time"),
|
||||
sub_item_table = {
|
||||
PinPadMenuEntry:genRadioMenuItem(_("10 seconds"), "pinpadlock_timeout_time", "10"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("30 seconds"), "pinpadlock_timeout_time", "30"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("60 seconds"), "pinpadlock_timeout_time", "60"),
|
||||
},
|
||||
},
|
||||
{
|
||||
text = _("Set max tries before timeout"),
|
||||
sub_item_table = {
|
||||
PinPadMenuEntry:genRadioMenuItem(_("1"), "pinpadlock_max_tries", "1"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("3"), "pinpadlock_max_tries", "3"),
|
||||
PinPadMenuEntry:genRadioMenuItem(_("6"), "pinpadlock_max_tries", "6"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
text = _("Check for updates"),
|
||||
callback = function()
|
||||
PinPadMenuEntry:checkForUpdates()
|
||||
end,
|
||||
}
|
||||
}
|
||||
}
|
||||
187
pinpadlockscreen.koplugin/menu/pinpadmenuentry.lua
Normal file
187
pinpadlockscreen.koplugin/menu/pinpadmenuentry.lua
Normal file
@@ -0,0 +1,187 @@
|
||||
--[[
|
||||
Author: Lena2309
|
||||
Description: Execute actions when tapping on a menu entry item
|
||||
]]
|
||||
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local PinPadDialog = require("ui/pinpaddialog")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local _ = require("gettext")
|
||||
local http = require("socket.http")
|
||||
local ltn12 = require("ltn12")
|
||||
local json = require("dkjson")
|
||||
|
||||
local PinPadMenuEntry = {}
|
||||
|
||||
function PinPadMenuEntry:setMessage()
|
||||
local lock_message = G_reader_settings:readSetting("pinpadlock_message")
|
||||
local input_dialog
|
||||
input_dialog = InputDialog:new {
|
||||
title = _("PIN pad lock message"),
|
||||
description = _("Enter a custom message to be displayed on the PIN pad lock."),
|
||||
input = lock_message,
|
||||
buttons = {
|
||||
{
|
||||
{
|
||||
text = _("Cancel"),
|
||||
id = "close",
|
||||
callback = function()
|
||||
UIManager:close(input_dialog)
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Set message"),
|
||||
is_enter_default = true,
|
||||
callback = function()
|
||||
G_reader_settings:saveSetting("pinpadlock_message", input_dialog:getInputText())
|
||||
UIManager:close(input_dialog)
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
UIManager:show(input_dialog)
|
||||
input_dialog:onShowKeyboard()
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:showMessageEnabled()
|
||||
return G_reader_settings:isTrue("pinpadlock_show_message")
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:pinPadEnabled()
|
||||
return G_reader_settings:isTrue("pinpadlock_activated")
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:correctPinMessageEnabled()
|
||||
return G_reader_settings:isTrue("pinpadlock_correct_pin_message_activated")
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:displayDigitEnabled()
|
||||
return G_reader_settings:isTrue("pinpadlock_display_digit_activated")
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:genRadioMenuItem(text, setting, value)
|
||||
return {
|
||||
text = text,
|
||||
checked_func = function()
|
||||
return G_reader_settings:readSetting(setting) == value
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:saveSetting(setting, value)
|
||||
end,
|
||||
radio = true,
|
||||
}
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:changePinCode()
|
||||
local confirmCurrentCode = PinPadDialog:new { stage = "confirm_current_code" }
|
||||
confirmCurrentCode:showPinPad()
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:resetPinCode()
|
||||
local confirmBox
|
||||
confirmBox = ConfirmBox:new {
|
||||
text = _("Do you really want to reset the PIN code to \"1234\" ?"),
|
||||
ok_text = _("Yes"),
|
||||
ok_callback = function()
|
||||
G_reader_settings:saveSetting("pinpadlock_pin_code", "1234")
|
||||
UIManager:close(confirmBox)
|
||||
UIManager:show(InfoMessage:new { text = _("PIN Code resetted successfully."), timeout = 1 })
|
||||
end,
|
||||
cancel_callback = function()
|
||||
UIManager:close(confirmBox)
|
||||
end
|
||||
}
|
||||
UIManager:show(confirmBox)
|
||||
end
|
||||
|
||||
-- Parse a version string like "v1.2.3"
|
||||
local function parseVersion(version)
|
||||
local major, minor, patch = version:match("^v(%d+)%.(%d+)%.(%d+)$")
|
||||
return {
|
||||
major = tonumber(major) or 0,
|
||||
minor = tonumber(minor) or 0,
|
||||
patch = tonumber(patch) or 0
|
||||
}
|
||||
end
|
||||
|
||||
-- Returns -1 if a < b, 0 if equal, 1 if a > b
|
||||
local function compareVersions(local_version, remote_version)
|
||||
if local_version.major ~= remote_version.major then
|
||||
if local_version.major > remote_version.major then
|
||||
return 1
|
||||
else
|
||||
return -1
|
||||
end
|
||||
elseif local_version.minor ~= remote_version.minor then
|
||||
if local_version.minor > remote_version.minor then
|
||||
return 1
|
||||
else
|
||||
return -1
|
||||
end
|
||||
elseif local_version.patch ~= remote_version.patch then
|
||||
if local_version.patch > remote_version.patch then
|
||||
return 1
|
||||
else
|
||||
return -1
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function PinPadMenuEntry:checkForUpdates()
|
||||
local meta = dofile("plugins/pinpadlockscreen.koplugin/_meta.lua")
|
||||
local local_version = meta.version or "unknown"
|
||||
|
||||
local response_body = {}
|
||||
local ok, status = http.request {
|
||||
url = "https://api.github.com/repos/Lena2309/pinpad_screenlock_plugin/releases/latest",
|
||||
sink = ltn12.sink.table(response_body),
|
||||
redirect = true
|
||||
}
|
||||
|
||||
if not ok or status ~= 200 then
|
||||
UIManager:show(InfoMessage:new {
|
||||
text = _("Unable to check for updates. Make sure your device is connected to the Internet."),
|
||||
timeout = 3,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
local body = table.concat(response_body)
|
||||
local data, pos, err = json.decode(body, 1, nil)
|
||||
|
||||
if not data or not data.tag_name then
|
||||
UIManager:show(InfoMessage:new {
|
||||
text = _("Error parsing GitHub release info."),
|
||||
timeout = 3,
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
local remote_version = data.tag_name
|
||||
local cmp = compareVersions(parseVersion(local_version), parseVersion(remote_version))
|
||||
if cmp < 0 then
|
||||
UIManager:show(InfoMessage:new {
|
||||
text = _("New version available: ") .. remote_version ..
|
||||
_("\nYou are running: ") .. local_version,
|
||||
timeout = 5,
|
||||
})
|
||||
else
|
||||
if cmp > 0 then
|
||||
UIManager:show(InfoMessage:new {
|
||||
text = _("You’re ahead of the official release.\nLatest official version: " .. remote_version),
|
||||
timeout = 5,
|
||||
})
|
||||
else
|
||||
UIManager:show(InfoMessage:new {
|
||||
text = _("You are up to date!"),
|
||||
timeout = 3,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return PinPadMenuEntry
|
||||
18
pinpadlockscreen.koplugin/ui/icons/lock.svg
Normal file
18
pinpadlockscreen.koplugin/ui/icons/lock.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<g transform="translate(0, 512) scale(0.1, -0.1)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2390 5110 c-157 -22 -329 -75 -461 -140 -95 -48 -234 -147 -319
|
||||
-227 -203 -191 -334 -415 -407 -697 -27 -101 -27 -102 -30 -573 l-4 -473 -123
|
||||
0 c-201 0 -285 -41 -348 -167 l-33 -68 0 -1260 c0 -1052 2 -1267 14 -1300 32
|
||||
-93 104 -163 197 -191 73 -22 3296 -21 3371 1 78 23 136 74 175 152 l33 68 0
|
||||
1265 0 1265 -33 68 c-63 127 -147 167 -349 167 l-123 0 0 428 c0 461 -5 523
|
||||
-55 697 -86 295 -296 581 -557 756 -162 107 -310 170 -496 209 -111 24 -350
|
||||
34 -452 20z m405 -519 c317 -91 554 -334 637 -653 20 -77 21 -113 25 -510 l5
|
||||
-428 -902 0 -902 0 5 428 c4 397 5 433 25 510 87 335 351 591 687 666 99 22
|
||||
324 15 420 -13z m-114 -2497 c151 -48 252 -192 253 -361 0 -74 -4 -88 -37
|
||||
-157 -25 -50 -53 -89 -86 -118 l-49 -43 54 -250 c29 -137 53 -258 54 -267 0
|
||||
-17 -21 -18 -310 -18 -289 0 -310 1 -309 18 0 9 24 130 53 267 l53 250 -48 43
|
||||
c-94 83 -143 229 -119 349 47 228 269 357 491 287z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
235
pinpadlockscreen.koplugin/ui/pinpadbuttondialog.lua
Normal file
235
pinpadlockscreen.koplugin/ui/pinpadbuttondialog.lua
Normal file
@@ -0,0 +1,235 @@
|
||||
--[[
|
||||
Author: Lena2309
|
||||
Description: customizes KOReader's existing ButtonDialog class solely
|
||||
for aesthetic purposes (icon widget, vertical layout...),
|
||||
with the primary modification in the `init` function.
|
||||
]]
|
||||
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local ButtonTable = require("ui/widget/buttontable")
|
||||
local CenterContainer = require("ui/widget/container/centercontainer")
|
||||
local Device = require("device")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local Geom = require("ui/geometry")
|
||||
local GestureRange = require("ui/gesturerange")
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
local LineWidget = require("ui/widget/linewidget")
|
||||
local MovableContainer = require("ui/widget/container/movablecontainer")
|
||||
local ScrollTextWidget = require("ui/widget/scrolltextwidget")
|
||||
local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local Screen = Device.screen
|
||||
local util = require("util")
|
||||
|
||||
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
|
||||
|
||||
local PinpadButtonDialog = ButtonDialog:extend {
|
||||
override_show_message = false, -- will prevent showing custom lock message even if enabled (specific for changing PIN Code)
|
||||
}
|
||||
|
||||
function PinpadButtonDialog:init()
|
||||
if not self.width_factor then
|
||||
self.width_factor = 2 / 3
|
||||
end
|
||||
self.width = math.floor(math.min(Screen:getWidth(), Screen:getHeight()) * self.width_factor)
|
||||
|
||||
if self.dismissable then
|
||||
if Device:hasKeys() then
|
||||
local back_group = util.tableDeepCopy(Device.input.group.Back)
|
||||
if Device:hasFewKeys() then
|
||||
table.insert(back_group, "Left")
|
||||
self.key_events.Close = { { back_group } }
|
||||
else
|
||||
table.insert(back_group, "Menu")
|
||||
self.key_events.Close = { { back_group } }
|
||||
end
|
||||
end
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
GestureRange:new {
|
||||
ges = "tap",
|
||||
range = Geom:new {
|
||||
x = 0, y = 0,
|
||||
w = Screen:getWidth(),
|
||||
h = Screen:getHeight(),
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local title_face
|
||||
if self.use_info_style then
|
||||
title_face = self.info_face
|
||||
else
|
||||
title_face = self.title_face
|
||||
end
|
||||
|
||||
local currentFileSource = debug.getinfo(1, "S").source
|
||||
local plugin_dir
|
||||
if currentFileSource:find("^@") then
|
||||
plugin_dir = currentFileSource:gsub("^@(.*)/[^/]*", "%1")
|
||||
end
|
||||
|
||||
self.title_widget = TextBoxWidget:new {
|
||||
text = self.title,
|
||||
face = title_face,
|
||||
width = self.width,
|
||||
alignment = self.title_align,
|
||||
}
|
||||
|
||||
local aesthetic_space = VerticalSpan:new { width = Size.margin.default + Size.padding.default }
|
||||
local text_pin_content = VerticalGroup:new {
|
||||
align = "center",
|
||||
ImageWidget:new {
|
||||
file = plugin_dir .. "/icons/lock.svg",
|
||||
alpha = true,
|
||||
width = Screen:scaleBySize(DGENERIC_ICON_SIZE) * 1.25,
|
||||
height = Screen:scaleBySize(DGENERIC_ICON_SIZE) * 1.25,
|
||||
scale_factor = 0,
|
||||
original_in_nightmode = false,
|
||||
},
|
||||
aesthetic_space,
|
||||
VerticalGroup:new {
|
||||
align = "center",
|
||||
self.title_widget
|
||||
},
|
||||
}
|
||||
|
||||
self.buttontable = ButtonTable:new {
|
||||
buttons = self.buttons,
|
||||
width = text_pin_content:getSize().w,
|
||||
shrink_unneeded_width = self.shrink_unneeded_width,
|
||||
shrink_min_width = self.shrink_min_width,
|
||||
show_parent = self,
|
||||
}
|
||||
|
||||
local separator = LineWidget:new {
|
||||
background = Blitbuffer.COLOR_GRAY,
|
||||
dimen = Geom:new {
|
||||
w = text_pin_content:getSize().w,
|
||||
h = Size.line.medium,
|
||||
},
|
||||
}
|
||||
|
||||
local content
|
||||
if G_reader_settings:isTrue("pinpadlock_show_message") and not self.override_show_message then
|
||||
local lock_message = G_reader_settings:readSetting("pinpadlock_message")
|
||||
lock_message = lock_message:gsub("\\n", "\n") -- enabling jumping lines in the message
|
||||
|
||||
local lock_message_alignment = G_reader_settings:readSetting("pinpadlock_message_alignment")
|
||||
local lock_message_position = G_reader_settings:readSetting("pinpadlock_message_position")
|
||||
|
||||
local lock_message_widget = TextBoxWidget:new {
|
||||
text = lock_message,
|
||||
face = title_face,
|
||||
width = self.width,
|
||||
alignment = lock_message_alignment,
|
||||
}
|
||||
|
||||
-- If the custom message ends up being too tall and makes the Pin Pad taller than the screen,
|
||||
-- wrap it inside a ScrollableContainer
|
||||
local max_height = self.buttontable:getSize().h + 3 * text_pin_content:getSize().h + Size.line.medium
|
||||
local height = self.buttontable:getSize().h + text_pin_content:getSize().h + Size.line.medium +
|
||||
lock_message_widget:getSize().h
|
||||
if height > max_height then
|
||||
local scroll_height = 3 * text_pin_content:getSize().h
|
||||
|
||||
lock_message_widget = ScrollTextWidget:new {
|
||||
text = lock_message,
|
||||
face = title_face,
|
||||
width = self.width,
|
||||
alignment = lock_message_alignment,
|
||||
dialog = self,
|
||||
height = scroll_height,
|
||||
}
|
||||
end
|
||||
|
||||
if lock_message_position == "top" then
|
||||
content = VerticalGroup:new {
|
||||
align = "center",
|
||||
aesthetic_space,
|
||||
lock_message_widget,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
aesthetic_space,
|
||||
text_pin_content,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
self.buttontable,
|
||||
}
|
||||
elseif lock_message_position == "middle" then
|
||||
content = VerticalGroup:new {
|
||||
align = "center",
|
||||
aesthetic_space,
|
||||
text_pin_content,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
aesthetic_space,
|
||||
lock_message_widget,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
self.buttontable,
|
||||
}
|
||||
else
|
||||
content = VerticalGroup:new {
|
||||
align = "center",
|
||||
aesthetic_space,
|
||||
text_pin_content,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
self.buttontable,
|
||||
separator,
|
||||
aesthetic_space,
|
||||
lock_message_widget,
|
||||
aesthetic_space,
|
||||
}
|
||||
end
|
||||
else
|
||||
content = VerticalGroup:new {
|
||||
align = "center",
|
||||
aesthetic_space,
|
||||
text_pin_content,
|
||||
aesthetic_space,
|
||||
separator,
|
||||
self.buttontable,
|
||||
}
|
||||
end
|
||||
|
||||
self.movable = MovableContainer:new {
|
||||
alpha = self.alpha,
|
||||
anchor = self.anchor,
|
||||
FrameContainer:new {
|
||||
background = Blitbuffer.COLOR_WHITE,
|
||||
bordersize = Size.border.window,
|
||||
radius = Size.radius.window,
|
||||
padding = Size.padding.default,
|
||||
padding_top = 0,
|
||||
padding_bottom = 0,
|
||||
content,
|
||||
},
|
||||
unmovable = true,
|
||||
}
|
||||
|
||||
self.layout = self.buttontable.layout
|
||||
self.buttontable.layout = nil
|
||||
|
||||
self[1] = CenterContainer:new {
|
||||
dimen = Screen:getSize(),
|
||||
self.movable,
|
||||
}
|
||||
end
|
||||
|
||||
function PinpadButtonDialog:updateTitle(text)
|
||||
if self.title_widget then
|
||||
self.title = text
|
||||
self.title_widget:setText(text)
|
||||
UIManager:setDirty(self, "ui")
|
||||
end
|
||||
end
|
||||
|
||||
return PinpadButtonDialog
|
||||
484
pinpadlockscreen.koplugin/ui/pinpaddialog.lua
Normal file
484
pinpadlockscreen.koplugin/ui/pinpaddialog.lua
Normal file
@@ -0,0 +1,484 @@
|
||||
--[[
|
||||
Author: Lena2309
|
||||
Description: represents a PIN pad interface and its behavior within KOReader.
|
||||
It handles user input, PIN validation, and UI interactions.
|
||||
]]
|
||||
|
||||
local Blitbuffer = require("ffi/blitbuffer")
|
||||
local BookStatusWidget = require("ui/widget/bookstatuswidget")
|
||||
local Button = require("ui/widget/button")
|
||||
local Device = require("device")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local ImageWidget = require("ui/widget/imagewidget")
|
||||
local PinPadButtonDialog = require("ui/pinpadbuttondialog")
|
||||
local RenderImage = require("ui/renderimage")
|
||||
local Screensaver = require("ui/screensaver")
|
||||
local ScreenSaverWidget = require("ui/widget/screensaverwidget")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local ffiUtil = require("ffi/util")
|
||||
local util = require("util")
|
||||
local _ = require("gettext")
|
||||
local Screen = Device.screen
|
||||
|
||||
local ScreensaverUtil = require("util/screensaverutil")
|
||||
|
||||
local DGENERIC_ICON_SIZE = G_defaults:readSetting("DGENERIC_ICON_SIZE")
|
||||
|
||||
local LOCKED_TEXT = _("Enter your PIN")
|
||||
local CONFIRM_CURRENT_CODE_TEXT = _("Enter the current PIN Code")
|
||||
local NEW_CODE_TEXT = _("Enter the new PIN Code")
|
||||
|
||||
local MAX_TRIES_LIMIT = tonumber(G_reader_settings:readSetting("pinpadlock_max_tries"))
|
||||
local TIMEOUT_TIME = tonumber(G_reader_settings:readSetting("pinpadlock_timeout_time"))
|
||||
|
||||
if G_reader_settings:hasNot("current_tries_number") then
|
||||
G_reader_settings:saveSetting("current_tries_number", 0)
|
||||
end
|
||||
if G_reader_settings:hasNot("block_start_time") then
|
||||
G_reader_settings:saveSetting("block_start_time", 0)
|
||||
end
|
||||
|
||||
local PinPadDialog = FrameContainer:extend {
|
||||
stage = "locked", -- "confirm_current_code" or "enter_new_code"
|
||||
icon_size = Screen:scaleBySize(DGENERIC_ICON_SIZE) * 1.25,
|
||||
}
|
||||
|
||||
function PinPadDialog:init()
|
||||
self:setDialogText()
|
||||
self.pin = ""
|
||||
self.buttons = self:initializeButtons()
|
||||
return self
|
||||
end
|
||||
|
||||
function PinPadDialog:setDialogText()
|
||||
if self.stage == "locked" then
|
||||
self.dialog_text = LOCKED_TEXT
|
||||
elseif self.stage == "confirm_current_code" then
|
||||
self.dialog_text = CONFIRM_CURRENT_CODE_TEXT
|
||||
else
|
||||
self.dialog_text = NEW_CODE_TEXT
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:createButton(text, callback, hold_callback)
|
||||
local button = Button:new {
|
||||
text = text,
|
||||
callback = callback,
|
||||
hold_callback = hold_callback,
|
||||
}
|
||||
return button
|
||||
end
|
||||
|
||||
function PinPadDialog:initializeButtons()
|
||||
local ref_self = self
|
||||
local buttons = {
|
||||
{
|
||||
self:createButton("1", function() ref_self:onAppendToPin("1") end),
|
||||
self:createButton("2", function() ref_self:onAppendToPin("2") end),
|
||||
self:createButton("3", function() ref_self:onAppendToPin("3") end),
|
||||
},
|
||||
{
|
||||
self:createButton("4", function() ref_self:onAppendToPin("4") end),
|
||||
self:createButton("5", function() ref_self:onAppendToPin("5") end),
|
||||
self:createButton("6", function() ref_self:onAppendToPin("6") end),
|
||||
},
|
||||
{
|
||||
self:createButton("7", function() ref_self:onAppendToPin("7") end),
|
||||
self:createButton("8", function() ref_self:onAppendToPin("8") end),
|
||||
self:createButton("9", function() ref_self:onAppendToPin("9") end),
|
||||
},
|
||||
{
|
||||
self:createButton("Cancel", function() ref_self:onDelete() end, function() ref_self:onCancel() end),
|
||||
self:createButton("0", function() ref_self:onAppendToPin("0") end),
|
||||
self:createButton("OK", function() ref_self:onOk() end),
|
||||
}
|
||||
}
|
||||
return buttons
|
||||
end
|
||||
|
||||
function PinPadDialog:initializeScreensaverBackground()
|
||||
if Screensaver.screensaver_type == "disable" and not Screensaver.show_message and not Screensaver.overlay_message then
|
||||
return
|
||||
end
|
||||
|
||||
local rotation_mode = Screen:getRotationMode()
|
||||
|
||||
if Screensaver:modeExpectsPortrait() then
|
||||
Device.orig_rotation_mode = rotation_mode
|
||||
if bit.band(Device.orig_rotation_mode, 1) == 1 then
|
||||
Screen:setRotationMode(Screen.DEVICE_ROTATED_UPRIGHT)
|
||||
else
|
||||
Device.orig_rotation_mode = nil
|
||||
end
|
||||
|
||||
if Device:hasEinkScreen() and Screensaver:modeIsImage() then
|
||||
if Screensaver:withBackground() then
|
||||
Screen:clear()
|
||||
end
|
||||
Screen:refreshFull(0, 0, Screen:getWidth(), Screen:getHeight())
|
||||
|
||||
if Device:isKobo() and Device:isSunxi() then
|
||||
ffiUtil.usleep(150 * 1000)
|
||||
end
|
||||
end
|
||||
else
|
||||
Device.orig_rotation_mode = nil
|
||||
end
|
||||
|
||||
local widget = nil
|
||||
if Screensaver.screensaver_type == "cover" or Screensaver.screensaver_type == "random_image" then
|
||||
local widget_settings = {
|
||||
width = Screen:getWidth(),
|
||||
height = Screen:getHeight(),
|
||||
scale_factor = G_reader_settings:isFalse("screensaver_stretch_images") and 0 or nil,
|
||||
stretch_limit_percentage = G_reader_settings:readSetting("screensaver_stretch_limit_percentage"),
|
||||
}
|
||||
if Screensaver.image then
|
||||
widget_settings.image = Screensaver.image
|
||||
widget_settings.image_disposable = true
|
||||
elseif Screensaver.image_file then
|
||||
if G_reader_settings:isTrue("screensaver_rotate_auto_for_best_fit") then
|
||||
if util.getFileNameSuffix(Screensaver.image_file) == "svg" then
|
||||
widget_settings.image = RenderImage:renderSVGImageFile(Screensaver.image_file, nil, nil, 1)
|
||||
else
|
||||
widget_settings.image = RenderImage:renderImageFile(Screensaver.image_file, false, nil, nil)
|
||||
end
|
||||
if not widget_settings.image then
|
||||
widget_settings.image = RenderImage:renderCheckerboard(Screen:getWidth(), Screen:getHeight(),
|
||||
Screen.bb:getType())
|
||||
end
|
||||
widget_settings.image_disposable = true
|
||||
else
|
||||
widget_settings.file = Screensaver.image_file
|
||||
widget_settings.file_do_cache = false
|
||||
end
|
||||
widget_settings.alpha = true
|
||||
end
|
||||
if G_reader_settings:isTrue("screensaver_rotate_auto_for_best_fit") then
|
||||
local angle = rotation_mode == 3 and 180 or 0
|
||||
if (widget_settings.image:getWidth() < widget_settings.image:getHeight()) ~= (widget_settings.width < widget_settings.height) then
|
||||
angle = angle + (G_reader_settings:isTrue("imageviewer_rotation_landscape_invert") and -90 or 90)
|
||||
end
|
||||
widget_settings.rotation_angle = angle
|
||||
end
|
||||
widget = ImageWidget:new(widget_settings)
|
||||
elseif Screensaver.screensaver_type == "bookstatus" then
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
widget = BookStatusWidget:new {
|
||||
ui = ReaderUI.instance,
|
||||
readonly = true,
|
||||
}
|
||||
elseif Screensaver.screensaver_type == "readingprogress" then
|
||||
widget = Screensaver.getReaderProgress()
|
||||
end
|
||||
|
||||
local covers_fullscreen = true
|
||||
local background
|
||||
if Screensaver.screensaver_background == "white" then
|
||||
background = Blitbuffer.COLOR_WHITE
|
||||
elseif Screensaver.screensaver_background == "none" then
|
||||
background = nil
|
||||
else
|
||||
background = Blitbuffer.COLOR_BLACK
|
||||
end
|
||||
|
||||
UIManager:setIgnoreTouchInput(false)
|
||||
|
||||
if widget then
|
||||
self.screensaver_widget = ScreenSaverWidget:new {
|
||||
widget = widget,
|
||||
background = background,
|
||||
covers_fullscreen = covers_fullscreen,
|
||||
}
|
||||
self.screensaver_widget.dithered = true
|
||||
else
|
||||
local currentFileSource = debug.getinfo(1, "S").source
|
||||
local plugin_dir
|
||||
if currentFileSource:find("^@") then
|
||||
plugin_dir = currentFileSource:gsub("^@(.*)/[^/]*", "%1")
|
||||
end
|
||||
-- dummy widget
|
||||
widget = ImageWidget:new {
|
||||
file = plugin_dir .. "/icons/lock.svg",
|
||||
alpha = true,
|
||||
width = self.icon_size,
|
||||
height = self.icon_size,
|
||||
scale_factor = 0,
|
||||
original_in_nightmode = false,
|
||||
}
|
||||
self.screensaver_widget = ScreenSaverWidget:new {
|
||||
widget = widget,
|
||||
background = Blitbuffer.COLOR_BLACK,
|
||||
covers_fullscreen = covers_fullscreen,
|
||||
}
|
||||
self.screensaver_widget.dithered = true
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:isBlocked()
|
||||
local block_start = G_reader_settings:readSetting("block_start_time") or 0
|
||||
if block_start == 0 then
|
||||
if self.blocking_dialog then
|
||||
UIManager:close(self.blocking_dialog, "ui")
|
||||
self.blocking_dialog = nil
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local elapsed = os.time() - block_start
|
||||
|
||||
if elapsed < 0 then
|
||||
G_reader_settings:saveSetting("block_start_time", 0)
|
||||
G_reader_settings:saveSetting("current_tries_number", 0)
|
||||
if self.blocking_dialog then
|
||||
UIManager:close(self.blocking_dialog, "ui")
|
||||
self.blocking_dialog = nil
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
if elapsed >= TIMEOUT_TIME then
|
||||
if self.blocking_dialog then
|
||||
UIManager:close(self.blocking_dialog, "ui")
|
||||
self.blocking_dialog = nil
|
||||
end
|
||||
return false
|
||||
else
|
||||
self.remaining_block_time = TIMEOUT_TIME - elapsed
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:showPinPad()
|
||||
local screensaver_visible = UIManager:isWidgetShown(Screensaver.screensaver_widget)
|
||||
|
||||
if screensaver_visible then
|
||||
ScreensaverUtil.freeze()
|
||||
self.reused_screensaver = true
|
||||
else
|
||||
Screensaver:setup()
|
||||
self:initializeScreensaverBackground()
|
||||
if self.screensaver_widget then
|
||||
UIManager:show(self.screensaver_widget)
|
||||
end
|
||||
self.reused_screensaver = false
|
||||
end
|
||||
|
||||
|
||||
local currentFileSource = debug.getinfo(1, "S").source
|
||||
local plugin_dir
|
||||
if currentFileSource:find("^@") then
|
||||
plugin_dir = currentFileSource:gsub("^@(.*)/[^/]*", "%1")
|
||||
end
|
||||
|
||||
if self.stage == "locked" then
|
||||
self.dialog = PinPadButtonDialog:new {
|
||||
title = self.dialog_text,
|
||||
title_align = "center",
|
||||
use_info_style = false,
|
||||
buttons = self.buttons,
|
||||
dismissable = false,
|
||||
ImageWidget:new {
|
||||
file = plugin_dir .. "/icons/lock.svg",
|
||||
alpha = true,
|
||||
width = self.icon_size,
|
||||
height = self.icon_size,
|
||||
scale_factor = 0,
|
||||
original_in_nightmode = false,
|
||||
}
|
||||
}
|
||||
else
|
||||
self.dialog = PinPadButtonDialog:new {
|
||||
title = self.dialog_text,
|
||||
title_align = "center",
|
||||
use_info_style = false,
|
||||
buttons = self.buttons,
|
||||
dismissable = true,
|
||||
override_show_message = true,
|
||||
ImageWidget:new {
|
||||
file = plugin_dir .. "/icons/lock.svg",
|
||||
alpha = true,
|
||||
width = self.icon_size,
|
||||
height = self.icon_size,
|
||||
scale_factor = 0,
|
||||
original_in_nightmode = false,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
UIManager:show(self.dialog, "ui")
|
||||
UIManager:nextTick(function()
|
||||
for i = 1, #UIManager._window_stack do
|
||||
if UIManager._window_stack[i].widget == self.dialog then
|
||||
local dialog_entry = table.remove(UIManager._window_stack, i)
|
||||
table.insert(UIManager._window_stack, dialog_entry)
|
||||
UIManager:setDirty(self.dialog, "ui")
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if self.stage == "locked" and self:isBlocked() then
|
||||
self:showBlockingDialog(self.remaining_block_time)
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:showBlockingDialog(remaining_time)
|
||||
self.blocking_dialog = InfoMessage:new {
|
||||
text = _("Too many failed attempts. Wait " .. remaining_time .. " seconds."),
|
||||
timeout = remaining_time,
|
||||
dismissable = false,
|
||||
}
|
||||
|
||||
UIManager:show(self.blocking_dialog, "ui")
|
||||
UIManager:nextTick(function()
|
||||
if not self.blocking_dialog then return end
|
||||
for i = 1, #UIManager._window_stack do
|
||||
if UIManager._window_stack[i].widget == self.blocking_dialog then
|
||||
local blocking_entry = table.remove(UIManager._window_stack, i)
|
||||
table.insert(UIManager._window_stack, blocking_entry)
|
||||
UIManager:setDirty(self.blocking_dialog, "ui")
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function PinPadDialog:reset()
|
||||
self.pin = ""
|
||||
self:setDialogText()
|
||||
end
|
||||
|
||||
function PinPadDialog:closeDialogs()
|
||||
if self.digit_display_timer then
|
||||
self.digit_display_timer:stop()
|
||||
self.digit_display_timer = nil
|
||||
end
|
||||
if self.blocking_dialog then
|
||||
UIManager:close(self.blocking_dialog, "ui")
|
||||
end
|
||||
if self.dialog then
|
||||
UIManager:close(self.dialog, "ui")
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:close(callback_function)
|
||||
self:reset()
|
||||
if not callback_function then
|
||||
self:closeDialogs()
|
||||
end
|
||||
if self.reused_screensaver then
|
||||
ScreensaverUtil.forceClose(function()
|
||||
if callback_function then
|
||||
self:closeDialogs()
|
||||
callback_function()
|
||||
end
|
||||
end)
|
||||
else
|
||||
if self.screensaver_widget then
|
||||
ScreensaverUtil.forceClose(function()
|
||||
if callback_function then
|
||||
self:closeDialogs()
|
||||
callback_function()
|
||||
end
|
||||
end)
|
||||
UIManager:close(self.screensaver_widget)
|
||||
self.screensaver_widget = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:onAppendToPin(digit)
|
||||
if self.digit_display_timer then
|
||||
self.digit_display_timer:stop()
|
||||
self.digit_display_timer = nil
|
||||
end
|
||||
if self.dialog_text == LOCKED_TEXT or self.dialog_text == CONFIRM_CURRENT_CODE_TEXT or self.dialog_text == NEW_CODE_TEXT then
|
||||
self.dialog_text = ""
|
||||
end
|
||||
self.pin = self.pin .. digit
|
||||
|
||||
if G_reader_settings:isTrue("pinpadlock_display_digit_activated") then
|
||||
local temp_display_text = self.dialog_text .. digit
|
||||
self.dialog:updateTitle(temp_display_text)
|
||||
|
||||
self.dialog_text = self.dialog_text .. "*"
|
||||
|
||||
self.digit_display_timer = UIManager:scheduleIn(1, function()
|
||||
self.dialog:updateTitle(self.dialog_text)
|
||||
self.digit_display_timer = nil
|
||||
end)
|
||||
else
|
||||
self.dialog_text = self.dialog_text .. "*"
|
||||
self.dialog:updateTitle(self.dialog_text)
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:onOk()
|
||||
if self.stage == "locked" then
|
||||
if self.pin == G_reader_settings:readSetting("pinpadlock_pin_code") then
|
||||
self:close()
|
||||
if G_reader_settings:isTrue("pinpadlock_correct_pin_message_activated") then
|
||||
UIManager:show(InfoMessage:new { text = _("Correct PIN, have fun !"), timeout = 2 })
|
||||
end
|
||||
G_reader_settings:saveSetting("current_tries_number", 0)
|
||||
G_reader_settings:saveSetting("block_start_time", 0)
|
||||
G_reader_settings:makeFalse("suspended_device")
|
||||
else
|
||||
if self.pin == "" then
|
||||
return
|
||||
end
|
||||
local current_tries = G_reader_settings:readSetting("current_tries_number")
|
||||
if (current_tries + 1) >= MAX_TRIES_LIMIT then
|
||||
G_reader_settings:saveSetting("block_start_time", os.time())
|
||||
self:showBlockingDialog(TIMEOUT_TIME)
|
||||
else
|
||||
G_reader_settings:saveSetting("current_tries_number", current_tries + 1)
|
||||
UIManager:show(InfoMessage:new { text = _("Wrong PIN, try again."), timeout = 2 })
|
||||
end
|
||||
self:onCancel()
|
||||
end
|
||||
elseif self.stage == "confirm_current_code" then
|
||||
if self.pin == G_reader_settings:readSetting("pinpadlock_pin_code") then
|
||||
self:close()
|
||||
UIManager:show(InfoMessage:new { text = _("Correct PIN, you may change your PIN Code !"), timeout = 2 })
|
||||
local enterNewCode = PinPadDialog:new { stage = "enter_new_code" }
|
||||
enterNewCode:showPinPad()
|
||||
else
|
||||
UIManager:show(InfoMessage:new { text = _("Wrong PIN, try again."), timeout = 2 })
|
||||
self:onCancel()
|
||||
end
|
||||
else
|
||||
G_reader_settings:saveSetting("pinpadlock_pin_code", self.pin)
|
||||
self:close()
|
||||
UIManager:show(InfoMessage:new { text = _("PIN Code changed successfully !"), timeout = 2 })
|
||||
end
|
||||
end
|
||||
|
||||
function PinPadDialog:onDelete()
|
||||
if self.pin == "" then
|
||||
return
|
||||
elseif #self.pin == 1 then
|
||||
self.pin = ""
|
||||
else
|
||||
self.pin = self.pin:sub(1, #self.pin - 1)
|
||||
end
|
||||
|
||||
if #self.dialog_text == 1 then
|
||||
self:setDialogText()
|
||||
elseif not (self.dialog_text == LOCKED_TEXT or self.dialog_text == CONFIRM_CURRENT_CODE_TEXT or self.dialog_text == NEW_CODE_TEXT) then
|
||||
self.dialog_text = self.dialog_text:sub(1, #self.dialog_text - 1)
|
||||
end
|
||||
self.dialog:updateTitle(self.dialog_text)
|
||||
end
|
||||
|
||||
function PinPadDialog:onCancel()
|
||||
if self.pin == "" then
|
||||
return
|
||||
end
|
||||
self:reset()
|
||||
self.dialog:updateTitle(self.dialog_text)
|
||||
end
|
||||
|
||||
return PinPadDialog
|
||||
53
pinpadlockscreen.koplugin/util/screensaverutil.lua
Normal file
53
pinpadlockscreen.koplugin/util/screensaverutil.lua
Normal file
@@ -0,0 +1,53 @@
|
||||
--[[
|
||||
Author: Lena2309, oleasteo (original inspiration)
|
||||
Inspiration and original skeleton from `https://github.com/oleasteo/koreader-screenlockpin`
|
||||
Description: Utility to prevent screensaver from closing and manage z-order
|
||||
]]
|
||||
|
||||
local Device = require("device")
|
||||
local Screensaver = require("ui/screensaver")
|
||||
|
||||
local ScreensaverUtil = {}
|
||||
|
||||
local _original_setup = nil
|
||||
local _original_close = nil
|
||||
local _frozen = false
|
||||
|
||||
-- Prevent screensaver from closing
|
||||
function ScreensaverUtil.freeze()
|
||||
if _frozen then return end
|
||||
Device.screen_saver_lock = false
|
||||
Device.screen_saver_mode = false
|
||||
if not _original_setup then
|
||||
_original_setup = Screensaver.setup
|
||||
end
|
||||
_original_close = Screensaver.close
|
||||
Screensaver.setup = function() end
|
||||
Screensaver.close = function() end
|
||||
_frozen = true
|
||||
end
|
||||
|
||||
-- Restore screensaver normal behavior
|
||||
function ScreensaverUtil.unfreeze(callback)
|
||||
if callback and _original_setup then
|
||||
Screensaver.setup = function()
|
||||
callback()
|
||||
_original_setup(Screensaver)
|
||||
end
|
||||
elseif _original_setup then
|
||||
Screensaver.setup = _original_setup
|
||||
_original_setup = nil
|
||||
end
|
||||
if _original_close then
|
||||
Screensaver.close = _original_close
|
||||
_original_close = nil
|
||||
end
|
||||
_frozen = false
|
||||
end
|
||||
|
||||
function ScreensaverUtil.forceClose(callback)
|
||||
ScreensaverUtil.unfreeze(callback)
|
||||
Screensaver:close_widget()
|
||||
end
|
||||
|
||||
return ScreensaverUtil
|
||||
Reference in New Issue
Block a user