mirror of https://github.com/usbharu/Hideout.git
feat: Mastodon 互換APIでカスタム絵文字を使用できるように
This commit is contained in:
parent
2d84ad073f
commit
8af489c93c
|
@ -21,5 +21,6 @@ data class Timeline(
|
|||
val sensitive: Boolean,
|
||||
val isLocal: Boolean,
|
||||
val isPureRepost: Boolean = false,
|
||||
val mediaIds: List<Long> = emptyList()
|
||||
val mediaIds: List<Long> = emptyList(),
|
||||
val emojiIds: List<Long> = emptyList()
|
||||
)
|
||||
|
|
|
@ -37,6 +37,7 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService
|
|||
it[isLocal] = timeline.isLocal
|
||||
it[isPureRepost] = timeline.isPureRepost
|
||||
it[mediaIds] = timeline.mediaIds.joinToString(",")
|
||||
it[emojiIds] = timeline.emojiIds.joinToString(",")
|
||||
}
|
||||
} else {
|
||||
Timelines.update({ Timelines.id eq timeline.id }) {
|
||||
|
@ -52,6 +53,7 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService
|
|||
it[isLocal] = timeline.isLocal
|
||||
it[isPureRepost] = timeline.isPureRepost
|
||||
it[mediaIds] = timeline.mediaIds.joinToString(",")
|
||||
it[emojiIds] = timeline.emojiIds.joinToString(",")
|
||||
}
|
||||
}
|
||||
return@query timeline
|
||||
|
@ -72,6 +74,7 @@ class ExposedTimelineRepository(private val idGenerateService: IdGenerateService
|
|||
this[Timelines.isLocal] = it.isLocal
|
||||
this[Timelines.isPureRepost] = it.isPureRepost
|
||||
this[Timelines.mediaIds] = it.mediaIds.joinToString(",")
|
||||
this[Timelines.emojiIds] = it.emojiIds.joinToString(",")
|
||||
}
|
||||
return@query timelines
|
||||
}
|
||||
|
@ -104,7 +107,8 @@ fun ResultRow.toTimeline(): Timeline {
|
|||
sensitive = this[Timelines.sensitive],
|
||||
isLocal = this[Timelines.isLocal],
|
||||
isPureRepost = this[Timelines.isPureRepost],
|
||||
mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() }
|
||||
mediaIds = this[Timelines.mediaIds].split(",").mapNotNull { it.toLongOrNull() },
|
||||
emojiIds = this[Timelines.emojiIds].split(",").mapNotNull { it.toLongOrNull() }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -122,6 +126,7 @@ object Timelines : Table("timelines") {
|
|||
val isLocal = bool("is_local")
|
||||
val isPureRepost = bool("is_pure_repost")
|
||||
val mediaIds = varchar("media_ids", 255)
|
||||
val emojiIds = varchar("emoji_ids", 255)
|
||||
|
||||
override val primaryKey: PrimaryKey = PrimaryKey(id)
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ class ExposedGenerateTimelineService(private val statusQueryService: StatusQuery
|
|||
it[Timelines.postId],
|
||||
it[Timelines.replyId],
|
||||
it[Timelines.repostId],
|
||||
it[Timelines.mediaIds].split(",").mapNotNull { s -> s.toLongOrNull() }
|
||||
it[Timelines.mediaIds].split(",").mapNotNull { s -> s.toLongOrNull() },
|
||||
it[Timelines.emojiIds].split(",").mapNotNull { s -> s.toLongOrNull() }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ class MongoGenerateTimelineService(
|
|||
it.postId,
|
||||
it.replyId,
|
||||
it.repostId,
|
||||
it.mediaIds
|
||||
it.mediaIds,
|
||||
it.emojiIds
|
||||
)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -37,7 +37,8 @@ class TimelineService(
|
|||
sensitive = post.sensitive,
|
||||
isLocal = isLocal,
|
||||
isPureRepost = post.repostId == null || (post.text.isBlank() && post.overview.isNullOrBlank()),
|
||||
mediaIds = post.mediaIds
|
||||
mediaIds = post.mediaIds,
|
||||
emojiIds = post.emojiIds
|
||||
)
|
||||
}.toMutableList()
|
||||
if (post.visibility == Visibility.PUBLIC) {
|
||||
|
@ -55,7 +56,8 @@ class TimelineService(
|
|||
sensitive = post.sensitive,
|
||||
isLocal = isLocal,
|
||||
isPureRepost = post.repostId == null || (post.text.isBlank() && post.overview.isNullOrBlank()),
|
||||
mediaIds = post.mediaIds
|
||||
mediaIds = post.mediaIds,
|
||||
emojiIds = post.emojiIds
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package dev.usbharu.hideout.mastodon.infrastructure.exposedquery
|
||||
|
||||
import dev.usbharu.hideout.core.domain.model.emoji.CustomEmoji
|
||||
import dev.usbharu.hideout.core.domain.model.media.toMediaAttachments
|
||||
import dev.usbharu.hideout.core.infrastructure.exposedrepository.*
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.Account
|
||||
|
@ -12,6 +13,7 @@ import org.jetbrains.exposed.sql.andWhere
|
|||
import org.jetbrains.exposed.sql.select
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.time.Instant
|
||||
import dev.usbharu.hideout.domain.mastodon.model.generated.CustomEmoji as MastodonEmoji
|
||||
|
||||
@Suppress("IncompleteDestructuring")
|
||||
@Repository
|
||||
|
@ -23,6 +25,10 @@ class StatusQueryServiceImpl : StatusQueryService {
|
|||
postIdSet.addAll(statusQueries.flatMap { listOfNotNull(it.postId, it.replyId, it.repostId) })
|
||||
val mediaIdSet = mutableSetOf<Long>()
|
||||
mediaIdSet.addAll(statusQueries.flatMap { it.mediaIds })
|
||||
|
||||
val emojiIdSet = mutableSetOf<Long>()
|
||||
emojiIdSet.addAll(statusQueries.flatMap { it.emojiIds })
|
||||
|
||||
val postMap = Posts
|
||||
.leftJoin(Actors)
|
||||
.select { Posts.id inList postIdSet }
|
||||
|
@ -32,12 +38,16 @@ class StatusQueryServiceImpl : StatusQueryService {
|
|||
it[Media.id] to it.toMedia().toMediaAttachments()
|
||||
}
|
||||
|
||||
val emojiMap = CustomEmojis.select { CustomEmojis.id inList emojiIdSet }.associate {
|
||||
it[CustomEmojis.id] to it.toCustomEmoji().toMastodonEmoji()
|
||||
}
|
||||
return statusQueries.mapNotNull { statusQuery ->
|
||||
postMap[statusQuery.postId]?.copy(
|
||||
inReplyToId = statusQuery.replyId?.toString(),
|
||||
inReplyToAccountId = postMap[statusQuery.replyId]?.account?.id,
|
||||
reblog = postMap[statusQuery.repostId],
|
||||
mediaAttachments = statusQuery.mediaIds.mapNotNull { mediaMap[it] }
|
||||
mediaAttachments = statusQuery.mediaIds.mapNotNull { mediaMap[it] },
|
||||
emojis = statusQuery.emojiIds.mapNotNull { emojiMap[it] }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +130,8 @@ class StatusQueryServiceImpl : StatusQueryService {
|
|||
private suspend fun findByPostIdsWithMedia(ids: List<Long>): List<Status> {
|
||||
val pairs = Posts
|
||||
.leftJoin(PostsMedia)
|
||||
.leftJoin(PostsEmojis)
|
||||
.leftJoin(CustomEmojis)
|
||||
.leftJoin(Actors)
|
||||
.leftJoin(Media)
|
||||
.select { Posts.id inList ids }
|
||||
|
@ -129,13 +141,22 @@ class StatusQueryServiceImpl : StatusQueryService {
|
|||
toStatus(it.first()).copy(
|
||||
mediaAttachments = it.mapNotNull { resultRow ->
|
||||
resultRow.toMediaOrNull()?.toMediaAttachments()
|
||||
}
|
||||
},
|
||||
emojis = it.mapNotNull { resultRow -> resultRow.toCustomEmoji()?.toMastodonEmoji() }
|
||||
) to it.first()[Posts.repostId]
|
||||
}
|
||||
return resolveReplyAndRepost(pairs)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CustomEmoji.toMastodonEmoji(): MastodonEmoji = MastodonEmoji(
|
||||
shortcode = this.name,
|
||||
url = this.url,
|
||||
staticUrl = this.url,
|
||||
visibleInPicker = true,
|
||||
category = this.category.orEmpty()
|
||||
)
|
||||
|
||||
private fun toStatus(it: ResultRow) = Status(
|
||||
id = it[Posts.id].toString(),
|
||||
uri = it[Posts.apId],
|
||||
|
|
|
@ -4,5 +4,6 @@ data class StatusQuery(
|
|||
val postId: Long,
|
||||
val replyId: Long?,
|
||||
val repostId: Long?,
|
||||
val mediaIds: List<Long>
|
||||
val mediaIds: List<Long>,
|
||||
val emojiIds: List<Long>
|
||||
)
|
||||
|
|
|
@ -98,7 +98,7 @@ create table if not exists posts
|
|||
reply_id bigint null,
|
||||
"sensitive" boolean default false not null,
|
||||
ap_id varchar(100) not null unique,
|
||||
deleted boolean default false not null
|
||||
deleted boolean default false not null
|
||||
);
|
||||
alter table posts
|
||||
add constraint fk_posts_actor_id__id foreign key (actor_id) references actors (id) on delete restrict on update restrict;
|
||||
|
@ -150,7 +150,7 @@ create table if not exists timelines
|
|||
user_id bigint not null,
|
||||
timeline_id bigint not null,
|
||||
post_id bigint not null,
|
||||
post_actor_id bigint not null,
|
||||
post_actor_id bigint not null,
|
||||
created_at bigint not null,
|
||||
reply_id bigint null,
|
||||
repost_id bigint null,
|
||||
|
@ -158,7 +158,8 @@ create table if not exists timelines
|
|||
"sensitive" boolean not null,
|
||||
is_local boolean not null,
|
||||
is_pure_repost boolean not null,
|
||||
media_ids varchar(255) not null
|
||||
media_ids varchar(255) not null,
|
||||
emoji_ids varchar(255) not null
|
||||
);
|
||||
|
||||
create table if not exists application_authorization
|
||||
|
|
Loading…
Reference in New Issue