@ -2,8 +2,9 @@ local InfoMessage = require("ui/widget/infomessage")
local TimeWidget = require ( " ui/widget/timewidget " )
local UIManager = require ( " ui/uimanager " )
local WidgetContainer = require ( " ui/widget/container/widgetcontainer " )
local logger = require ( " logger " )
local util = require ( " util " )
local _ = require ( " gettext " )
local N_ = _.ngettext
local T = require ( " ffi/util " ) . template
local ReadTimer = WidgetContainer : new {
@ -28,9 +29,9 @@ function ReadTimer:scheduled()
return self.time ~= 0
end
function ReadTimer : remaining Minutes ( )
function ReadTimer : remaining ( )
if self : scheduled ( ) then
local td = os.difftime ( self.time , os.time ( ) ) / 60
local td = os.difftime ( self.time , os.time ( ) )
if td > 0 then
return td
else
@ -43,10 +44,11 @@ end
function ReadTimer : remainingTime ( )
if self : scheduled ( ) then
local remain_time = self : remainingMinutes ( )
local remain_hours = math.floor ( remain_time / 60 )
local remain_minutes = math.floor ( remain_time - 60 * remain_hours )
return remain_hours , remain_minutes
local remainder = self : remaining ( )
local hours = math.floor ( remainder / 3600 )
local minutes = math.floor ( remainder % 3600 / 60 )
local seconds = math.floor ( remainder % 60 )
return hours , minutes , seconds
end
end
@ -57,12 +59,18 @@ function ReadTimer:unschedule()
end
end
function ReadTimer : rescheduleIn ( seconds )
self.time = os.time ( ) + seconds
UIManager : scheduleIn ( seconds , self.alarm_callback )
end
function ReadTimer : addToMainMenu ( menu_items )
menu_items.read_timer = {
text_func = function ( )
if self : scheduled ( ) then
return T ( _ ( " Read timer (%1m) " ) ,
string.format ( " %.2f " , self : remainingMinutes ( ) ) )
local user_duration_format = G_reader_settings : readSetting ( " duration_format " )
return T ( _ ( " Read timer (%1) " ) ,
util.secondsToClockDuration ( user_duration_format , self : remaining ( ) , false ) )
else
return _ ( " Read timer " )
end
@ -78,7 +86,6 @@ function ReadTimer:addToMainMenu(menu_items)
local now_t = os.date ( " *t " )
local curr_hour = now_t.hour
local curr_min = now_t.min
local curr_sec_from_midnight = curr_hour * 3600 + curr_min * 60
local time_widget = TimeWidget : new {
hour = curr_hour ,
min = curr_min ,
@ -87,38 +94,24 @@ function ReadTimer:addToMainMenu(menu_items)
callback = function ( time )
touchmenu_instance : closeMenu ( )
self : unschedule ( )
local timer_sec_from_mignight = time.hour * 3600 + time.min * 60
local seconds
if timer_sec_from_mignight > curr_sec_from_midnight then
seconds = timer_sec_from_mignight - curr_sec_from_midnight
else
seconds = 24 * 3600 - ( curr_sec_from_midnight - timer_sec_from_mignight )
end
if seconds > 0 and seconds < 18 * 3600 then
self.time = os.time ( ) + seconds
UIManager : scheduleIn ( seconds , self.alarm_callback )
local hr_str = " "
local min_str = " "
local hr = math.floor ( seconds / 3600 )
if hr > 0 then
hr_str = T ( N_ ( " 1 hour " , " %1 hours " , hr ) , hr )
end
local min = math.floor ( ( seconds % 3600 ) / 60 )
if min > 0 then
min_str = T ( N_ ( " 1 minute " , " %1 minutes " , min ) , min )
if hr_str ~= " " then
hr_str = hr_str .. " "
end
end
local then_t = now_t
then_t.hour = time.hour
then_t.min = time.min
then_t.sec = 0
local seconds = os.difftime ( os.time ( then_t ) , os.time ( ) )
if seconds > 0 then
self : rescheduleIn ( seconds )
local user_duration_format = G_reader_settings : readSetting ( " duration_format " )
UIManager : show ( InfoMessage : new {
text = T ( _ ( " Timer set to: %1:%2. \n \n That's %3%4 from now. " ) ,
-- @translators %1:%2 is a clock time (HH:MM), %3 is a duration
text = T ( _ ( " Timer set for %1:%2. \n \n That's %3 from now. " ) ,
string.format ( " %02d " , time.hour ) , string.format ( " %02d " , time.min ) ,
hr_str, min_str ) ,
util.secondsToClockDuration ( user_duration_format , seconds , false ) ) ,
timeout = 5 ,
} )
else if seconds <= 0 or seconds >= 18 * 3600 then
else
UIManager : show ( InfoMessage : new {
text = _ ( " Timer could not be set. The selected time is in the past or too far in the future ." ) ,
text = _ ( " Timer could not be set. The selected time is in the past. " ) ,
timeout = 5 ,
} )
end
@ -151,26 +144,15 @@ function ReadTimer:addToMainMenu(menu_items)
self : unschedule ( )
local seconds = time.hour * 3600 + time.min * 60
if seconds > 0 then
self.time = os.time ( ) + seconds
UIManager : scheduleIn ( seconds , self.alarm_callback )
local hr_str = " "
local min_str = " "
local hr = time.hour
if hr > 0 then
hr_str = T ( N_ ( " 1 hour " , " %1 hours " , hr ) , hr )
end
local min = time.min
if min > 0 then
min_str = T ( N_ ( " 1 minute " , " %1 minutes " , min ) , min )
if hr_str ~= " " then
hr_str = hr_str .. " "
end
end
self : rescheduleIn ( seconds )
local user_duration_format = G_reader_settings : readSetting ( " duration_format " )
UIManager : show ( InfoMessage : new {
text = T ( _ ( " Timer set for %1%2. " ) , hr_str , min_str ) ,
-- @translators This is a duration
text = T ( _ ( " Timer will expire in %1. " ) ,
util.secondsToClockDuration ( user_duration_format , seconds , true ) ) ,
timeout = 5 ,
} )
remain_time = { hr, min}
remain_time = { time.hour , time.min }
G_reader_settings : saveSetting ( " reader_timer_remain_time " , remain_time )
end
end
@ -193,12 +175,23 @@ function ReadTimer:addToMainMenu(menu_items)
}
end
-- The UI ticks on a monotonic time domain, while this plugin deals with real time.
-- Make sure we fire the alarm right away if it expired during suspend...
-- The UI ticks on a MONOTONIC time domain, while this plugin deals with REAL wall clock time.
function ReadTimer : onResume ( )
if self : remainingMinutes ( ) == 0 then
self : alarm_callback ( )
self : unschedule ( )
if self : scheduled ( ) then
logger.dbg ( " ReadTimer: onResume with an active timer " )
local remainder = self : remaining ( )
if remainder == 0 then
-- Make sure we fire the alarm right away if it expired during suspend...
self : alarm_callback ( )
self : unschedule ( )
else
-- ...and that we re-schedule the timer against the REAL time if it's still ticking.
logger.dbg ( " ReadTimer: Rescheduling in " , remainder , " seconds " )
self : unschedule ( )
self : rescheduleIn ( remainder )
end
end
end