mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Calendar view: add options to change start time of days (#10254)
Can be set for example to 04:00 to see after-midnight readings with those of the previous evening in day timeline. Also fix possible shifts in day start when crossing DST changes with prev/next. Also fix sorting (by reverse reading duration) of books at top
This commit is contained in:
@@ -683,8 +683,12 @@ function CalendarDayView:setupView()
|
||||
self.is_current_day = now >= self.day_ts and now < self.day_ts + 86400
|
||||
if self.is_current_day then
|
||||
local date = os.date("*t", now)
|
||||
self.current_day_hour = date.hour
|
||||
self.current_hour_second = date.min * 60 + date.sec
|
||||
self.current_day_hour = date.hour - (self.reader_statistics.settings.calendar_day_start_hour or 0)
|
||||
self.current_hour_second = date.min * 60 + date.sec - (self.reader_statistics.settings.calendar_day_start_minute or 0) * 60
|
||||
if self.current_hour_second < 0 then
|
||||
self.current_day_hour = self.current_day_hour - 1
|
||||
self.current_hour_second = 3600 + self.current_hour_second
|
||||
end
|
||||
end
|
||||
|
||||
self.kv_pairs = self.reader_statistics:getBooksFromPeriod(self.day_ts, self.day_ts + 86400)
|
||||
@@ -695,7 +699,7 @@ function CalendarDayView:setupView()
|
||||
end
|
||||
kv.checked = true
|
||||
end
|
||||
table.sort(self.kv_pairs, function(a,b) return a[2] > b[2] end) --sort by value
|
||||
table.sort(self.kv_pairs, function(a,b) return a.duration > b.duration end) --sort by value
|
||||
self.title = self:title_callback()
|
||||
|
||||
self.show_page = 1
|
||||
@@ -761,19 +765,47 @@ function CalendarDayView:goToPage(page)
|
||||
end
|
||||
|
||||
function CalendarDayView:onNextPage()
|
||||
if not self:nextPage() and self.day_ts + 86400 < os.time() then
|
||||
-- go to next day
|
||||
self.day_ts = self.day_ts + 86400
|
||||
self:setupView()
|
||||
if not self:nextPage() and self.day_ts + 82800 < os.time() then
|
||||
local current_day_ts = self.day_ts - (self.reader_statistics.settings.calendar_day_start_hour or 0) * 3600
|
||||
- (self.reader_statistics.settings.calendar_day_start_minute or 0) * 60
|
||||
local next_day_ts = current_day_ts + 86400 + 10800 -- make sure it's the next day
|
||||
local next_day_date = os.date("*t", next_day_ts)
|
||||
next_day_ts = os.time({
|
||||
year = next_day_date.year,
|
||||
month = next_day_date.month,
|
||||
day = next_day_date.day,
|
||||
hour = 0,
|
||||
min = 0,
|
||||
})
|
||||
local current_day_length = next_day_ts - current_day_ts
|
||||
if self.day_ts + current_day_length < os.time() then
|
||||
-- go to next day
|
||||
self.day_ts = self.day_ts + current_day_length
|
||||
self:setupView()
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function CalendarDayView:onPrevPage()
|
||||
if not self:prevPage() and self.day_ts - 86400 >= self.min_ts then
|
||||
-- go to previous day
|
||||
self.day_ts = self.day_ts - 86400
|
||||
self:setupView()
|
||||
if not self:prevPage() and self.day_ts - 82800 >= self.min_ts then
|
||||
local current_day_ts = self.day_ts - (self.reader_statistics.settings.calendar_day_start_hour or 0) * 3600
|
||||
- (self.reader_statistics.settings.calendar_day_start_minute or 0) * 60
|
||||
local previous_day_ts = current_day_ts - 86400 + 10800 -- make sure it's the previous day
|
||||
local previous_day_date = os.date("*t", previous_day_ts)
|
||||
previous_day_ts = os.time({
|
||||
year = previous_day_date.year,
|
||||
month = previous_day_date.month,
|
||||
day = previous_day_date.day,
|
||||
hour = 0,
|
||||
min = 0,
|
||||
})
|
||||
local previous_day_length = current_day_ts - previous_day_ts
|
||||
if self.day_ts - previous_day_length >= self.min_ts then
|
||||
-- go to previous day
|
||||
self.day_ts = self.day_ts - previous_day_length
|
||||
self:setupView()
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
@@ -868,7 +900,10 @@ function CalendarDayView:refreshTimeline()
|
||||
CenterContainer:new{
|
||||
dimen = Geom:new{ w = self.time_text_width, h = self.hour_height},
|
||||
TextWidget:new{
|
||||
text = string.format("%02d:00", i),
|
||||
text = string.format("%02d:%02d",
|
||||
(i + (self.reader_statistics.settings.calendar_day_start_hour or 0)) % 24,
|
||||
self.reader_statistics.settings.calendar_day_start_minute or 0
|
||||
),
|
||||
face = self.time_text_face,
|
||||
padding = Size.padding.small
|
||||
}
|
||||
@@ -1358,7 +1393,8 @@ function CalendarView:_populateItems()
|
||||
show_parent = self,
|
||||
callback = not is_future and function()
|
||||
UIManager:show(CalendarDayView:new{
|
||||
day_ts = day_ts,
|
||||
day_ts = day_ts + (self.reader_statistics.settings.calendar_day_start_hour or 0) * 3600
|
||||
+ (self.reader_statistics.settings.calendar_day_start_minute or 0) * 60,
|
||||
reader_statistics = self.reader_statistics,
|
||||
title_callback = function(this)
|
||||
local day = os.date("%Y-%m-%d", this.day_ts + 10800) -- use 3:00 to determine date (summer time change)
|
||||
@@ -1397,7 +1433,7 @@ end
|
||||
function CalendarView:showCalendarDayView(reader_statistics, title_callback)
|
||||
local date = os.date("*t", os.time())
|
||||
UIManager:show(CalendarDayView:new{
|
||||
day_ts = os.time({ year = date.year, month = date.month, day = date.day, hour = 0 }),
|
||||
day_ts = os.time({ year = date.year, month = date.month, day = date.day, hour = reader_statistics.settings.calendar_day_start_hour or 0, min = reader_statistics.settings.calendar_day_start_minute or 0 }),
|
||||
reader_statistics = reader_statistics,
|
||||
title_callback = title_callback,
|
||||
min_month = self.min_month
|
||||
|
||||
@@ -1074,6 +1074,46 @@ The max value ensures a page you stay on for a long time (because you fell aslee
|
||||
end,
|
||||
separator = true,
|
||||
},
|
||||
{
|
||||
text_func = function()
|
||||
-- @translators %1 is the time in the format 00:00
|
||||
return T(_("Daily timeline starts at %1"),
|
||||
string.format("%02d:%02d", self.settings.calendar_day_start_hour or 0,
|
||||
self.settings.calendar_day_start_minute or 0)
|
||||
)
|
||||
end,
|
||||
callback = function(touchmenu_instance)
|
||||
local DateTimeWidget = require("ui/widget/datetimewidget")
|
||||
local start_of_day_widget = DateTimeWidget:new{
|
||||
hour = self.settings.calendar_day_start_hour or 0,
|
||||
min = self.settings.calendar_day_start_minute or 0,
|
||||
hour_max = 6,
|
||||
ok_text = _("Set time"),
|
||||
title_text = _("Daily timeline starts at"),
|
||||
info_text =_([[
|
||||
Set the time when the daily timeline should start.
|
||||
|
||||
If you read past midnight, and would like this reading session to be displayed on the same screen with your previous evening reading sessions, use a value such as 04:00.
|
||||
|
||||
Time is in hours and minutes.]]),
|
||||
callback = function(time)
|
||||
self.settings.calendar_day_start_hour = time.hour
|
||||
self.settings.calendar_day_start_minute = time.min
|
||||
touchmenu_instance:updateItems()
|
||||
end
|
||||
}
|
||||
UIManager:show(start_of_day_widget)
|
||||
end,
|
||||
keep_menu_open = true,
|
||||
},
|
||||
{
|
||||
text = _("Also use in calendar view"),
|
||||
checked_func = function() return self.settings.calendar_use_day_time_shift end,
|
||||
callback = function()
|
||||
self.settings.calendar_use_day_time_shift = not self.settings.calendar_use_day_time_shift
|
||||
end,
|
||||
separator = true,
|
||||
},
|
||||
{
|
||||
text = _("Cloud sync"),
|
||||
callback = function(touchmenu_instance)
|
||||
@@ -2004,6 +2044,7 @@ function ReaderStatistics:getBooksFromPeriod(period_begin, period_end, callback_
|
||||
table.insert(results, {
|
||||
result_book[1][i],
|
||||
T(N_("%1 (1 page)", "%1 (%2 pages)", tonumber(result_book[2][i])), datetime.secondsToClockDuration(user_duration_format, tonumber(result_book[3][i]), false), tonumber(result_book[2][i])),
|
||||
duration = tonumber(result_book[3][i]),
|
||||
book_id = tonumber(result_book[4][i]),
|
||||
callback = function()
|
||||
local kv = self.kv
|
||||
@@ -2699,14 +2740,20 @@ function ReaderStatistics:getReadingRatioPerHourByDay(month)
|
||||
-- We let SQLite compute these timestamp boundaries from the provided
|
||||
-- month; we need the start of the month to be a real date:
|
||||
month = month.."-01"
|
||||
local offset = not self.settings.calendar_use_day_time_shift and 0 or (self.settings.calendar_day_start_hour or 0) * 3600 + (self.settings.calendar_day_start_minute or 0) * 60
|
||||
local sql_stmt = [[
|
||||
SELECT
|
||||
strftime('%Y-%m-%d', start_time, 'unixepoch', 'localtime') day,
|
||||
strftime('%H', start_time, 'unixepoch', 'localtime') hour,
|
||||
sum(duration)/3600.0 ratio
|
||||
FROM page_stat
|
||||
WHERE start_time BETWEEN strftime('%s', ?, 'utc')
|
||||
AND strftime('%s', ?, 'utc', '+33 days', 'start of month', '-1 second')
|
||||
FROM (
|
||||
SELECT
|
||||
start_time-? as start_time,
|
||||
duration
|
||||
FROM page_stat
|
||||
WHERE start_time BETWEEN strftime('%s', ?, 'utc')
|
||||
AND strftime('%s', ?, 'utc', '+33 days', 'start of month', '-1 second')
|
||||
)
|
||||
GROUP BY
|
||||
strftime('%Y-%m-%d', start_time, 'unixepoch', 'localtime'),
|
||||
strftime('%H', start_time, 'unixepoch', 'localtime')
|
||||
@@ -2714,7 +2761,7 @@ function ReaderStatistics:getReadingRatioPerHourByDay(month)
|
||||
]]
|
||||
local conn = SQ3.open(db_location)
|
||||
local stmt = conn:prepare(sql_stmt)
|
||||
local res, nb = stmt:reset():bind(month, month):resultset("i")
|
||||
local res, nb = stmt:reset():bind(offset, month, month):resultset("i")
|
||||
stmt:close()
|
||||
conn:close()
|
||||
local per_day = {}
|
||||
@@ -2731,16 +2778,20 @@ end
|
||||
|
||||
function ReaderStatistics:getReadBookByDay(month)
|
||||
month = month.."-01"
|
||||
local offset = not self.settings.calendar_use_day_time_shift and 0 or (self.settings.calendar_day_start_hour or 0) * 3600 + (self.settings.calendar_day_start_minute or 0) * 60
|
||||
local sql_stmt = [[
|
||||
SELECT
|
||||
strftime('%Y-%m-%d', start_time, 'unixepoch', 'localtime') day,
|
||||
sum(duration) durations,
|
||||
id_book book_id,
|
||||
book.title book_title
|
||||
FROM page_stat
|
||||
JOIN book ON book.id = page_stat.id_book
|
||||
WHERE start_time BETWEEN strftime('%s', ?, 'utc')
|
||||
AND strftime('%s', ?, 'utc', '+33 days', 'start of month', '-1 second')
|
||||
title book_title
|
||||
FROM (
|
||||
SELECT start_time-? as start_time, duration, page_stat.id_book, book.title
|
||||
FROM page_stat
|
||||
JOIN book ON book.id = page_stat.id_book
|
||||
WHERE start_time BETWEEN strftime('%s', ?, 'utc')
|
||||
AND strftime('%s', ?, 'utc', '+33 days', 'start of month', '-1 second')
|
||||
)
|
||||
GROUP BY
|
||||
strftime('%Y-%m-%d', start_time, 'unixepoch', 'localtime'),
|
||||
id_book,
|
||||
@@ -2749,7 +2800,7 @@ function ReaderStatistics:getReadBookByDay(month)
|
||||
]]
|
||||
local conn = SQ3.open(db_location)
|
||||
local stmt = conn:prepare(sql_stmt)
|
||||
local res, nb = stmt:reset():bind(month, month):resultset("i")
|
||||
local res, nb = stmt:reset():bind(offset, month, month):resultset("i")
|
||||
stmt:close()
|
||||
conn:close()
|
||||
local per_day = {}
|
||||
|
||||
Reference in New Issue
Block a user