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
reviewable/pr10285/r1
weijiuqiao 1 year ago committed by GitHub
parent 59a0139a60
commit 5648c942c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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 = {}

Loading…
Cancel
Save