diff --git a/db/migrate/20240321211120_add_in_reply_to_to_posts.rb b/db/migrate/20240321211120_add_in_reply_to_to_posts.rb new file mode 100644 index 0000000..a8ddcdf --- /dev/null +++ b/db/migrate/20240321211120_add_in_reply_to_to_posts.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + alter_table :posts do + add_column :in_reply_to, :text + end + end +end diff --git a/lib/adamantium/jobs/send_web_mentions.rb b/lib/adamantium/jobs/send_web_mentions.rb index 1ab7a38..cbbb054 100644 --- a/lib/adamantium/jobs/send_web_mentions.rb +++ b/lib/adamantium/jobs/send_web_mentions.rb @@ -4,7 +4,7 @@ require "que" module Adamantium module Jobs class SendWebMentions < Que::Job - def run(post_content:, post_url:) + def run(post_content:, post_url:, in_reply_to:) link_finder = Admin::Container["post_utilities.link_finder"] settings = Admin::Container["settings"] @@ -17,6 +17,15 @@ module Adamantium target: target }) end + + links = link_finder.call(in_reply_to) + links.each do |target| + HTTParty.post(settings.webmention_url, { + token: settings.webmention_token, + source: source, + target: target + }) + end end end end diff --git a/lib/adamantium/link_finder.rb b/lib/adamantium/link_finder.rb index 3203375..7b4d496 100644 --- a/lib/adamantium/link_finder.rb +++ b/lib/adamantium/link_finder.rb @@ -9,6 +9,7 @@ module Adamantium youtube.com bsky.app bsky.social + localhost github.com].freeze def call(content) diff --git a/slices/main/repos/post_repo.rb b/slices/main/repos/post_repo.rb index 72eab04..c59fc74 100644 --- a/slices/main/repos/post_repo.rb +++ b/slices/main/repos/post_repo.rb @@ -192,6 +192,17 @@ module Main .one! end + def fetch(slug) + posts + .published + .combine(:tags, :trips, :webmentions) + .node(:webmentions) { |webmention| + webmention.published.where(type: "reply") + } + .where(slug: slug) + .one + end + def find!(id) posts .by_pk(id) diff --git a/slices/main/templates/posts/show.html.slim b/slices/main/templates/posts/show.html.slim index f2ecbc1..fa55824 100644 --- a/slices/main/templates/posts/show.html.slim +++ b/slices/main/templates/posts/show.html.slim @@ -17,6 +17,13 @@ article class="h-entry" h1 class="p-name mb-2" a class="u-url" href=post.permalink = post.display_title + - if post.in_reply_to + div class="" + em = "In reply to: " + - if reply_in_context + a class="no-underline bg-pink-50 hover:bg-pink-100 dark:bg-pink-600 hover:dark:bg-pink-900 p-1 rounded" href=post.in_reply_to #{reply_in_context.display_title} + - else + a class="no-underline bg-pink-50 hover:bg-pink-100 dark:bg-pink-600 hover:dark:bg-pink-900 p-1 rounded" href=post.in_reply_to #{post.in_reply_to} nav class="space-x-1 text-sm md:text-sm md:block dark:text-gray-600" - if post.location || post.photos? || post.videos? span See more: diff --git a/slices/main/views/posts/show.rb b/slices/main/views/posts/show.rb index f9122ce..fade162 100644 --- a/slices/main/views/posts/show.rb +++ b/slices/main/views/posts/show.rb @@ -4,7 +4,7 @@ module Main module Views module Posts class Show < Main::View - include Deps["repos.post_repo", "repos.movie_repo"] + include Deps["repos.post_repo", "repos.movie_repo", "settings"] expose :post do |slug:| Decorators::Posts::Decorator.new(post_repo.fetch!(slug)) @@ -35,6 +35,13 @@ module Main expose :trip do |post| post.trips.first end + + expose :reply_in_context do |post| + if post.in_reply_to&.match settings.micropub_site_url + slug = post.in_reply_to.split("/").last + Decorators::Posts::Decorator.new(post_repo.fetch(slug)) + end + end end end end diff --git a/slices/micropub/commands/posts/create_post.rb b/slices/micropub/commands/posts/create_post.rb index 915e145..0211696 100644 --- a/slices/micropub/commands/posts/create_post.rb +++ b/slices/micropub/commands/posts/create_post.rb @@ -24,7 +24,7 @@ module Micropub decorated_post = Decorators::Posts::Decorator.new(created_post) - send_webmentions.call(post_content: created_post.content, post_url: decorated_post.permalink) + send_webmentions.call(post_content: created_post.content, post_url: decorated_post.permalink, in_reply_to: created_post.in_reply_to) Success(created_post) end diff --git a/slices/micropub/commands/posts/send_webmentions.rb b/slices/micropub/commands/posts/send_webmentions.rb index 2ab7579..bc6b3ba 100644 --- a/slices/micropub/commands/posts/send_webmentions.rb +++ b/slices/micropub/commands/posts/send_webmentions.rb @@ -7,10 +7,10 @@ module Micropub class SendWebmentions include Deps["settings", "post_utilities.link_finder"] - def call(post_content:, post_url:) + def call(post_content:, post_url:, in_reply_to:) Que.connection = Adamantium::Container["persistence.db"] - Adamantium::Jobs::SendWebMentions.enqueue(post_content: post_content, post_url: post_url) + Adamantium::Jobs::SendWebMentions.enqueue(post_content: post_content, post_url: post_url, in_reply_to: in_reply_to) end end end diff --git a/slices/micropub/entities/post_request.rb b/slices/micropub/entities/post_request.rb index 3cc1d4d..6c84117 100644 --- a/slices/micropub/entities/post_request.rb +++ b/slices/micropub/entities/post_request.rb @@ -10,6 +10,7 @@ module Micropub attribute :published_at, Types::Nominal::DateTime.optional attribute :post_type, Types::Coercible::String attribute :syndicate_to, Types::Array.of(Types::Coercible::String) + attribute :in_reply_to, Types::Coercible::String attribute :photos, Types::Array.of(Types::Hash) attribute :location, Types::Coercible::String.optional end diff --git a/slices/micropub/request_parser.rb b/slices/micropub/request_parser.rb index 1e98548..ff27228 100644 --- a/slices/micropub/request_parser.rb +++ b/slices/micropub/request_parser.rb @@ -97,6 +97,7 @@ module Micropub content: content, slug: params[:slug] || params[:"mp-slug"], syndicate_to: Array(params[:properties][:"mp-syndicate-to"]) || [], + in_reply_to: params[:properties][:"in-reply-to"] || nil, photos: photos, location: params[:properties][:location] }) @@ -119,6 +120,7 @@ module Micropub new_params.merge({ syndicate_to: Array(params[:"mp-syndicate-to"]) || [], + in_reply_to: params[:"in-reply-to"], name: params[:name], slug: params[:slug] || params[:"mp-slug"], published_at: (params[:"post-status"] == "draft") ? nil : publish_time, diff --git a/slices/micropub/validation/posts/post_contract.rb b/slices/micropub/validation/posts/post_contract.rb index f35afad..7cdcb0f 100644 --- a/slices/micropub/validation/posts/post_contract.rb +++ b/slices/micropub/validation/posts/post_contract.rb @@ -12,6 +12,7 @@ module Micropub required(:syndicate_to).array(:string) required(:photos).array(:hash) required(:location).maybe(:string) + required(:in_reply_to).maybe(:string) end end end diff --git a/spec/syndication/unit/mastodon_spec.rb b/spec/syndication/unit/mastodon_spec.rb index d2b10af..e882547 100644 --- a/spec/syndication/unit/mastodon_spec.rb +++ b/spec/syndication/unit/mastodon_spec.rb @@ -20,7 +20,8 @@ RSpec.describe Adamantium::Syndication::Mastodon do post_type: "post", syndicate_to: [], photos: [], - location: nil + location: nil, + in_reply_to: nil ) }