From fcfe6c877b03763c3faad63ac3508a3f978f266a Mon Sep 17 00:00:00 2001
From: naskya <m@naskya.net>
Date: Sun, 4 Aug 2024 21:52:22 +0900
Subject: [PATCH] refactor (backend): port renderHashtag to backend-rs

---
 packages/backend-rs/index.d.ts                |  9 +++++++
 packages/backend-rs/index.js                  |  1 +
 .../federation/activitypub/object/hashtag.rs  | 27 +++++++++++++++++++
 .../src/federation/activitypub/object/mod.rs  |  2 ++
 .../remote/activitypub/renderer/hashtag.ts    |  7 -----
 .../src/remote/activitypub/renderer/note.ts   |  3 +--
 .../src/remote/activitypub/renderer/person.ts |  3 +--
 7 files changed, 41 insertions(+), 11 deletions(-)
 create mode 100644 packages/backend-rs/src/federation/activitypub/object/hashtag.rs
 delete mode 100644 packages/backend/src/remote/activitypub/renderer/hashtag.ts

diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts
index 72fba66bc5..f2fdb66bd0 100644
--- a/packages/backend-rs/index.d.ts
+++ b/packages/backend-rs/index.d.ts
@@ -133,6 +133,12 @@ export interface ApFollow {
   object: string
 }
 
+export interface ApHashtag {
+  id: string
+  type: ApObject
+  name: string
+}
+
 export interface ApMention {
   type: ApObject
   href: string
@@ -143,6 +149,7 @@ export type ApObject =  'Accept'|
 'Emoji'|
 'Flag'|
 'Follow'|
+'Hashtag'|
 'Mention'|
 'Image'|
 'Read'|
@@ -1329,6 +1336,8 @@ export declare function renderFollow(follower: UserLike, followee: UserLike, req
 
 export declare function renderFollowRelay(relayId: string): Promise<ApFollow>
 
+export declare function renderHashtag(tagName: string): ApHashtag
+
 export declare function renderMention(user: UserLike): ApMention
 
 export declare function renderRead(userId: string, messageUri: string): ApRead
diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js
index 2df080fb4a..0ef803af9e 100644
--- a/packages/backend-rs/index.js
+++ b/packages/backend-rs/index.js
@@ -443,6 +443,7 @@ module.exports.renderEmoji = nativeBinding.renderEmoji
 module.exports.renderFlag = nativeBinding.renderFlag
 module.exports.renderFollow = nativeBinding.renderFollow
 module.exports.renderFollowRelay = nativeBinding.renderFollowRelay
+module.exports.renderHashtag = nativeBinding.renderHashtag
 module.exports.renderMention = nativeBinding.renderMention
 module.exports.renderRead = nativeBinding.renderRead
 module.exports.renderTombstone = nativeBinding.renderTombstone
diff --git a/packages/backend-rs/src/federation/activitypub/object/hashtag.rs b/packages/backend-rs/src/federation/activitypub/object/hashtag.rs
new file mode 100644
index 0000000000..5c1fa12e53
--- /dev/null
+++ b/packages/backend-rs/src/federation/activitypub/object/hashtag.rs
@@ -0,0 +1,27 @@
+use super::*;
+use crate::config::CONFIG;
+
+#[macros::export(object)]
+pub struct ApHashtag {
+    pub id: String,
+    pub r#type: ApObject,
+    pub name: String,
+}
+
+impl ActivityPubObject for ApHashtag {}
+
+impl ApHashtag {
+    #[allow(dead_code)] // TODO: remove this line
+    fn new(tag_name: &str) -> Self {
+        Self {
+            id: format!("{}/tags/{}", CONFIG.url, urlencoding::encode(tag_name)),
+            r#type: ApObject::Hashtag,
+            name: format!("#{}", tag_name),
+        }
+    }
+}
+
+#[macros::ts_export]
+pub fn render_hashtag(tag_name: &str) -> ApHashtag {
+    ApHashtag::new(tag_name)
+}
diff --git a/packages/backend-rs/src/federation/activitypub/object/mod.rs b/packages/backend-rs/src/federation/activitypub/object/mod.rs
index 6f8688da9d..7745031907 100644
--- a/packages/backend-rs/src/federation/activitypub/object/mod.rs
+++ b/packages/backend-rs/src/federation/activitypub/object/mod.rs
@@ -2,6 +2,7 @@ pub mod accept;
 pub mod emoji;
 pub mod flag;
 pub mod follow;
+pub mod hashtag;
 pub mod mention;
 pub mod read;
 pub mod tombstone;
@@ -14,6 +15,7 @@ pub enum ApObject {
     Emoji,
     Flag,
     Follow,
+    Hashtag,
     Mention,
     Image,
     Read,
diff --git a/packages/backend/src/remote/activitypub/renderer/hashtag.ts b/packages/backend/src/remote/activitypub/renderer/hashtag.ts
deleted file mode 100644
index ab6651f55d..0000000000
--- a/packages/backend/src/remote/activitypub/renderer/hashtag.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { config } from "@/config.js";
-
-export default (tag: string) => ({
-	type: "Hashtag",
-	href: `${config.url}/tags/${encodeURIComponent(tag)}`,
-	name: `#${tag}`,
-});
diff --git a/packages/backend/src/remote/activitypub/renderer/note.ts b/packages/backend/src/remote/activitypub/renderer/note.ts
index eff9be0047..fd099cb659 100644
--- a/packages/backend/src/remote/activitypub/renderer/note.ts
+++ b/packages/backend/src/remote/activitypub/renderer/note.ts
@@ -6,8 +6,7 @@ import { DriveFiles, Notes, Users, Emojis, Polls } from "@/models/index.js";
 import type { Emoji } from "@/models/entities/emoji.js";
 import type { Poll } from "@/models/entities/poll.js";
 import toHtml from "@/remote/activitypub/misc/get-note-html.js";
-import { renderEmoji, renderMention } from "backend-rs";
-import renderHashtag from "./hashtag.js";
+import { renderEmoji, renderHashtag, renderMention } from "backend-rs";
 import renderDocument from "./document.js";
 
 export default async function renderNote(
diff --git a/packages/backend/src/remote/activitypub/renderer/person.ts b/packages/backend/src/remote/activitypub/renderer/person.ts
index 30e067b2ac..39642c1ef7 100644
--- a/packages/backend/src/remote/activitypub/renderer/person.ts
+++ b/packages/backend/src/remote/activitypub/renderer/person.ts
@@ -8,8 +8,7 @@ import { toHtml } from "@/mfm/to-html.js";
 import renderImage from "./image.js";
 import renderKey from "./key.js";
 import { getEmojis } from "./note.js";
-import { renderEmoji } from "backend-rs";
-import renderHashtag from "./hashtag.js";
+import { renderEmoji, renderHashtag } from "backend-rs";
 import type { IIdentifier } from "../models/identifier.js";
 
 export async function renderPerson(user: ILocalUser) {