From 3ef6a7bfc4cec846aa7284cd5b1911c4762c6a28 Mon Sep 17 00:00:00 2001 From: Jared Turner Date: Mon, 1 Jun 2020 15:29:18 +0100 Subject: [PATCH] continue reading sorted by last read --- src/library.cr | 22 +++++++++++++++++----- src/routes/main.cr | 37 ++++++++++++++++++++++++++++++++++--- src/views/home.ecr | 14 +++++++------- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/library.cr b/src/library.cr index a7ef914..a5639c0 100644 --- a/src/library.cr +++ b/src/library.cr @@ -287,10 +287,7 @@ class Title else info.progress[username][entry] = page end - # should this be a separate method? - # eg. def save_last_read(username, entry) - # if so, we would need to open the json file twice every - # time we save. Does that matter? + # save last_read timestamp if info.last_read[username]?.nil? info.last_read[username] = {entry => Time.utc} else @@ -336,7 +333,6 @@ class Title last_read = info.last_read[username][entry] end end - return nil if last_read.nil? last_read end @@ -346,6 +342,12 @@ class Title @entries[idx + 1] end + def previous_entry(current_entry_obj) + idx = @entries.index current_entry_obj + return nil if idx.nil? || idx == 0 + @entries[idx - 1] + end + def get_continue_reading_entry(username) in_progress_entries = @entries.select do |e| load_progress(username, e.title) > 0 @@ -360,6 +362,16 @@ class Title latest_read_entry end end + + # TODO: More concise title? + def get_last_read_for_continue_reading(username, entry_obj) + last_read = load_last_read username, entry_obj.title + if last_read.nil? # grab from previous entry if current entry hasn't been started yet + previous_entry = previous_entry(entry_obj) + return load_last_read username, previous_entry.title if previous_entry + end + last_read + end end class TitleInfo diff --git a/src/routes/main.cr b/src/routes/main.cr index c57ead7..ed9df4d 100644 --- a/src/routes/main.cr +++ b/src/routes/main.cr @@ -75,10 +75,41 @@ class MainRouter < Router t.get_continue_reading_entry username }.select Entry - percentage = continue_reading_entries.map do |e| + percentage = continue_reading_entries.map { |e| e.book.load_percentage username, e.title - pp e.book.load_last_read username, e.title - end + } + + last_read = continue_reading_entries.map { |e| + e.book.get_last_read_for_continue_reading username, e + } + + # Group values in a NamedTuple for easier sorting + cr_entries = continue_reading_entries.map_with_index { |e, i| + { + entry: e, + percentage: percentage[i], + # if you're ok with the NamedTuple approach we could remove the + # percentage and last_read vars above and just call the methods + # here eg. + # perecentage: e.book.load_percentage username, e.title + last_read: last_read[i] + } + } + # I couldn't get the sort to work where last_read type is `Time | Nil` + # so I'm creating a new variable with just the entries that have last_read + # even still, I have to do another workaround within the sort below :/ + cr_entries_not_nil = cr_entries.select { |e| e[:last_read] } + cr_entries_not_nil.sort! { |a, b| + # 'if' ensures values aren't nil otherwise the compiler errors + # because it still thinks the NamedTuple `last_read` can be nil + # even though we only 'select'ed the objects which have last_read + # there's probably a better way to do this + if (a_time = a[:last_read]) && (b_time = b[:last_read]) + b_time <=> a_time + end + } + # add `last_read == nil` entries AFTER sorted entries + continue_reading = cr_entries_not_nil + cr_entries.select { |e| e[:last_read].nil? } layout "home" rescue e diff --git a/src/views/home.ecr b/src/views/home.ecr index a659fda..fd8c864 100644 --- a/src/views/home.ecr +++ b/src/views/home.ecr @@ -1,17 +1,17 @@ <%- unless continue_reading_entries.empty? -%>

Continue Reading

- <%- continue_reading_entries.each_with_index do |e, i| -%> -