diff --git a/Rakefile b/Rakefile index da30747..b5c0383 100644 --- a/Rakefile +++ b/Rakefile @@ -88,6 +88,14 @@ namespace :blog do Que.connection = Adamantium::Container["persistence.db"] Adamantium::Jobs::ArchiveDeletedWebmentions.enqueue end + + task gently_remind_me: ["blog:load_environment"] do + require "hanami/prepare" + require "que" + + command = Adamantium::GentlyRemindMe.new + command.call(limit: 5) + end end namespace :tailwind do diff --git a/db/migrate/20240222205406_add_read_status_to_bookmarks.rb b/db/migrate/20240222205406_add_read_status_to_bookmarks.rb new file mode 100644 index 0000000..e08d6e4 --- /dev/null +++ b/db/migrate/20240222205406_add_read_status_to_bookmarks.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + alter_table :posts do + add_column :is_read, :bool, default: false + end + end +end diff --git a/lib/adamantium/gently_remind_me.rb b/lib/adamantium/gently_remind_me.rb new file mode 100644 index 0000000..56bd093 --- /dev/null +++ b/lib/adamantium/gently_remind_me.rb @@ -0,0 +1,47 @@ +module Adamantium + class GentlyRemindMe + def call(limit:) + repo = Adamantium::Container["repos.post_repo"] + app_settings = Adamantium::Container["settings"] + + bookmarks = repo.for_reminders(limit: limit) + bookmarks_struct = bookmarks.map do |bookmark| + { + name: bookmark.name, + source_url: bookmark.url, + url: "#{app_settings.micropub_site_url}/bookmark/#{bookmark.slug}" + } + end + + body_content = "" + bookmarks_struct.each do |bm| + body_content += "#{bm[:name]} — #{bm[:source_url]} \n" + body_content += " #{bm[:url]}\n" + body_content += "\n" + end + + Mail.defaults do + delivery_method :smtp, { + address: app_settings.smtp_server, + port: 587, + authentication: "plain", + openssl_verify_mode: "peer", + enable_starttls_auto: true + } + end + + Mail.delivery_method.settings[:user_name] = app_settings.smtp_username + Mail.delivery_method.settings[:password] = app_settings.smtp_password + + mail = Mail.new do + subject "A gentle reminder" + body body_content + end + + mail[:to] = app_settings.from_email + mail[:from] = app_settings.from_email + + mail.deliver + end + end +end \ No newline at end of file diff --git a/slices/admin/actions/bookmarks/mark_read.rb b/slices/admin/actions/bookmarks/mark_read.rb new file mode 100644 index 0000000..4045dfa --- /dev/null +++ b/slices/admin/actions/bookmarks/mark_read.rb @@ -0,0 +1,15 @@ +module Admin + module Actions + module Bookmarks + class MarkRead < Action + include Deps["repos.bookmark_repo"] + + def handle(req, res) + bookmark_id = req.params[:id] + + bookmark_repo.mark_read(id: bookmark_id) + end + end + end + end +end diff --git a/slices/admin/actions/bookmarks/mark_unread.rb b/slices/admin/actions/bookmarks/mark_unread.rb new file mode 100644 index 0000000..4257913 --- /dev/null +++ b/slices/admin/actions/bookmarks/mark_unread.rb @@ -0,0 +1,15 @@ +module Admin + module Actions + module Bookmarks + class MarkUnread < Action + include Deps["repos.bookmark_repo"] + + def handle(req, res) + bookmark_id = req.params[:id] + + bookmark_repo.mark_unread(id: bookmark_id) + end + end + end + end +end diff --git a/slices/admin/config/routes.rb b/slices/admin/config/routes.rb index ce5ea7f..5e52174 100644 --- a/slices/admin/config/routes.rb +++ b/slices/admin/config/routes.rb @@ -42,6 +42,8 @@ module Admin post "/bookmarks/cache/:id", to: Auth.call(action: "bookmarks.cache") post "/bookmarks/:id/archive", to: Auth.call(action: "bookmarks.archive") post "/bookmarks/:id/publish", to: Auth.call(action: "bookmarks.publish") + post "/bookmarks/:id/mark_read", to: Auth.call(action: "bookmarks.mark_read") + post "/bookmarks/:id/mark_unread", to: Auth.call(action: "bookmarks.mark_unread") get "/posts", to: Auth.call(action: "posts.index") delete "/posts/:id", to: Auth.call(action: "posts.delete") diff --git a/slices/admin/repos/bookmark_repo.rb b/slices/admin/repos/bookmark_repo.rb index 49476e7..9472086 100644 --- a/slices/admin/repos/bookmark_repo.rb +++ b/slices/admin/repos/bookmark_repo.rb @@ -34,6 +34,14 @@ module Admin def update(id:, params:) posts.where(id: id).update(params) end + + def mark_read(id:) + posts.where(id: id).update(is_read: true) + end + + def mark_unread(id:) + posts.where(id: id).update(is_read: false) + end end end end diff --git a/slices/admin/templates/bookmarks/index.html.slim b/slices/admin/templates/bookmarks/index.html.slim index 6dcfdbb..95331e8 100644 --- a/slices/admin/templates/bookmarks/index.html.slim +++ b/slices/admin/templates/bookmarks/index.html.slim @@ -13,7 +13,7 @@ div class="max-w-prose mx-auto" x-data="{ activeTab: 0 }" thead th Details th Date - th colspan="2" Actions + th colspan="3" Actions tbody class="{ 'active': activeTab === 0 }" x-show.transition.in.opacity.duration.600="activeTab === 0" - published_bookmarks.each do |bookmark| tr id="bookmark-#{bookmark.id}" @@ -36,6 +36,11 @@ div class="max-w-prose mx-auto" x-data="{ activeTab: 0 }" button class="text-red-600" hx-delete="/admin/bookmarks/#{bookmark.id}" hx-target="#bookmark-#{bookmark.id}" delete td button hx-post="/admin/bookmarks/#{bookmark.id}/archive" archive + td + - if bookmark.is_read + button hx-post="/admin/bookmarks/#{bookmark.id}/mark_unread" mark unread + - else + button hx-post="/admin/bookmarks/#{bookmark.id}/mark_read" mark read tbody class="{ 'active': activeTab === 1 }" x-show.transition.in.opacity.duration.600="activeTab === 1" - unpublished_bookmarks.each do |bookmark| tr id="bookmark-#{bookmark.id}"