Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions app/src/main/graphql/pub/hackers/android/operations.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ fragment PostFields on Post {
iri
viewerHasShared
viewerHasBookmarked
viewerCanQuote
quotePolicy
actor {
...ActorFields
}
Expand Down Expand Up @@ -104,6 +106,8 @@ fragment SharedPostFields on Post {
iri
viewerHasShared
viewerHasBookmarked
viewerCanQuote
quotePolicy
actor {
...ActorFields
}
Expand Down Expand Up @@ -592,8 +596,8 @@ query ViewerPasskeys {
}
}

mutation CreateNote($content: Markdown!, $language: Locale!, $visibility: PostVisibility!, $replyTargetId: ID, $quotedPostId: ID) {
createNote(input: { content: $content, language: $language, visibility: $visibility, replyTargetId: $replyTargetId, quotedPostId: $quotedPostId }) {
mutation CreateNote($content: Markdown!, $language: Locale!, $visibility: PostVisibility!, $quotePolicy: QuotePolicy, $replyTargetId: ID, $quotedPostId: ID) {
createNote(input: { content: $content, language: $language, visibility: $visibility, quotePolicy: $quotePolicy, replyTargetId: $replyTargetId, quotedPostId: $quotedPostId }) {
... on CreateNotePayload {
note {
...PostFields
Expand Down Expand Up @@ -932,8 +936,8 @@ query PostByUrl($url: String!) {
}
}

mutation PublishArticleDraft($id: ID!, $slug: String!, $language: Locale!, $allowLlmTranslation: Boolean) {
publishArticleDraft(input: { id: $id, slug: $slug, language: $language, allowLlmTranslation: $allowLlmTranslation }) {
mutation PublishArticleDraft($id: ID!, $slug: String!, $language: Locale!, $allowLlmTranslation: Boolean, $quotePolicy: QuotePolicy) {
publishArticleDraft(input: { id: $id, slug: $slug, language: $language, allowLlmTranslation: $allowLlmTranslation, quotePolicy: $quotePolicy }) {
... on PublishArticleDraftPayload {
article {
id
Expand Down
36 changes: 36 additions & 0 deletions app/src/main/graphql/pub/hackers/android/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,8 @@ type Article implements Node & Post & Reactable {

publishedYear: Int!

quotePolicy: QuotePolicy!

quotedPost: Post

quotes(after: String, before: String, first: Int, last: Int): PostQuotesConnection!
Expand Down Expand Up @@ -484,6 +486,10 @@ type Article implements Node & Post & Reactable {

uuid: UUID!

viewerCanQuote: Boolean!

viewerCanRevokeQuote: Boolean!

viewerHasBookmarked: Boolean!

viewerHasShared: Boolean!
Expand Down Expand Up @@ -586,6 +592,8 @@ input CreateNoteInput {

language: Locale!

quotePolicy: QuotePolicy

quotedPostId: ID

replyTargetId: ID
Expand Down Expand Up @@ -1011,6 +1019,8 @@ type Note implements Node & Post & Reactable {

published: DateTime!

quotePolicy: QuotePolicy!

quotedPost: Post

quotes(after: String, before: String, first: Int, last: Int): PostQuotesConnection!
Expand All @@ -1035,6 +1045,10 @@ type Note implements Node & Post & Reactable {

uuid: UUID!

viewerCanQuote: Boolean!

viewerCanRevokeQuote: Boolean!

viewerHasBookmarked: Boolean!

viewerHasShared: Boolean!
Expand Down Expand Up @@ -1209,6 +1223,8 @@ interface Post implements Node & Reactable {

published: DateTime!

quotePolicy: QuotePolicy!

quotedPost: Post

quotes(after: String, before: String, first: Int, last: Int): PostQuotesConnection!
Expand All @@ -1233,6 +1249,10 @@ interface Post implements Node & Reactable {

uuid: UUID!

viewerCanQuote: Boolean!

viewerCanRevokeQuote: Boolean!

viewerHasBookmarked: Boolean!

viewerHasShared: Boolean!
Expand Down Expand Up @@ -1372,6 +1392,14 @@ enum PostVisibility {
UNLISTED
}

enum QuotePolicy {
EVERYONE

FOLLOWERS

SELF
}

input PublishArticleDraftInput {
allowLlmTranslation: Boolean

Expand All @@ -1381,6 +1409,8 @@ input PublishArticleDraftInput {

language: Locale!

quotePolicy: QuotePolicy

slug: String!
}

Expand Down Expand Up @@ -1548,6 +1578,8 @@ type Question implements Node & Post & Reactable {

published: DateTime!

quotePolicy: QuotePolicy!

quotedPost: Post

quotes(after: String, before: String, first: Int, last: Int): PostQuotesConnection!
Expand All @@ -1572,6 +1604,10 @@ type Question implements Node & Post & Reactable {

uuid: UUID!

viewerCanQuote: Boolean!

viewerCanRevokeQuote: Boolean!

viewerHasBookmarked: Boolean!

viewerHasShared: Boolean!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import pub.hackers.android.graphql.fragment.MediaFields
import pub.hackers.android.graphql.fragment.PostFields
import pub.hackers.android.graphql.fragment.SharedPostFields
import pub.hackers.android.graphql.type.PostVisibility as GqlPostVisibility
import pub.hackers.android.graphql.type.QuotePolicy as GqlQuotePolicy
import java.time.Instant
import javax.inject.Inject
import javax.inject.Singleton
Expand Down Expand Up @@ -929,6 +930,7 @@ class HackersPubRepository @Inject constructor(
content: String,
language: String = "en",
visibility: PostVisibility = PostVisibility.PUBLIC,
quotePolicy: QuotePolicy = QuotePolicy.EVERYONE,
replyTargetId: String? = null,
quotedPostId: String? = null
): Result<Post> {
Expand All @@ -940,12 +942,18 @@ class HackersPubRepository @Inject constructor(
PostVisibility.DIRECT -> GqlPostVisibility.DIRECT
PostVisibility.NONE -> GqlPostVisibility.NONE
}
val gqlQuotePolicy = when (quotePolicy) {
QuotePolicy.EVERYONE -> GqlQuotePolicy.EVERYONE
QuotePolicy.FOLLOWERS -> GqlQuotePolicy.FOLLOWERS
QuotePolicy.SELF -> GqlQuotePolicy.SELF
}

val response = apolloClient.mutation(
CreateNoteMutation(
content = content,
language = language,
visibility = gqlVisibility,
quotePolicy = Optional.present(gqlQuotePolicy),
replyTargetId = Optional.presentIfNotNull(replyTargetId),
quotedPostId = Optional.presentIfNotNull(quotedPostId)
)
Expand Down Expand Up @@ -1400,15 +1408,22 @@ class HackersPubRepository @Inject constructor(
id: String,
slug: String,
language: String,
allowLlmTranslation: Boolean = true
allowLlmTranslation: Boolean = true,
quotePolicy: QuotePolicy = QuotePolicy.EVERYONE
): Result<PublishedArticle> {
return try {
val gqlQuotePolicy = when (quotePolicy) {
QuotePolicy.EVERYONE -> GqlQuotePolicy.EVERYONE
QuotePolicy.FOLLOWERS -> GqlQuotePolicy.FOLLOWERS
QuotePolicy.SELF -> GqlQuotePolicy.SELF
}
val response = apolloClient.mutation(
PublishArticleDraftMutation(
id = id,
slug = slug,
language = language,
allowLlmTranslation = Optional.present(allowLlmTranslation)
allowLlmTranslation = Optional.present(allowLlmTranslation),
quotePolicy = Optional.present(gqlQuotePolicy)
)
).execute()

Expand Down Expand Up @@ -1515,6 +1530,7 @@ class HackersPubRepository @Inject constructor(
iri = iri.toString(),
viewerHasShared = viewerHasShared,
viewerHasBookmarked = viewerHasBookmarked,
viewerCanQuote = viewerCanQuote,
actor = actor.actorFields.toActor(),
media = media.map { it.mediaFields.toMedia() },
link = link?.let { l ->
Expand Down Expand Up @@ -1543,6 +1559,7 @@ class HackersPubRepository @Inject constructor(
replyTarget = replyTarget,
quotedPost = quotedPost?.sharedPostFields?.toPost(),
visibility = visibility,
quotePolicy = quotePolicy.toQuotePolicy(),
reactionGroups = reactionGroups.mapNotNull { group ->
when {
group.onEmojiReactionGroup != null -> ReactionGroup(
Expand Down Expand Up @@ -1582,13 +1599,24 @@ class HackersPubRepository @Inject constructor(
iri = iri.toString(),
viewerHasShared = viewerHasShared,
viewerHasBookmarked = viewerHasBookmarked,
viewerCanQuote = viewerCanQuote,
actor = actor.actorFields.toActor(),
media = media.map { it.mediaFields.toMedia() },
engagementStats = engagementStats.engagementStatsFields.toEngagementStats(),
mentions = mentions.edges.map { it.node.handle }
mentions = mentions.edges.map { it.node.handle },
quotePolicy = quotePolicy.toQuotePolicy()
)
}

private fun GqlQuotePolicy.toQuotePolicy(): QuotePolicy {
return when (this) {
GqlQuotePolicy.EVERYONE -> QuotePolicy.EVERYONE
GqlQuotePolicy.FOLLOWERS -> QuotePolicy.FOLLOWERS
GqlQuotePolicy.SELF -> QuotePolicy.SELF
GqlQuotePolicy.UNKNOWN__ -> QuotePolicy.EVERYONE
}
}

private fun ActorFields.toActor(): Actor {
return Actor(
id = id,
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/pub/hackers/android/domain/model/Models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ data class Post(
val iri: String? = null,
val viewerHasShared: Boolean,
val viewerHasBookmarked: Boolean = false,
val viewerCanQuote: Boolean = true,
val actor: Actor,
val media: List<Media>,
val link: PostLink? = null,
Expand All @@ -90,13 +91,18 @@ data class Post(
val replyTarget: Post? = null,
val quotedPost: Post? = null,
val visibility: PostVisibility = PostVisibility.PUBLIC,
val quotePolicy: QuotePolicy = QuotePolicy.EVERYONE,
val reactionGroups: List<ReactionGroup> = emptyList()
)

enum class PostVisibility {
PUBLIC, UNLISTED, FOLLOWERS, DIRECT, NONE
}

enum class QuotePolicy {
EVERYONE, FOLLOWERS, SELF
}

@Immutable
data class NotificationPost(
val id: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ private fun EngagementBar(
isShared = isShared,
count = post.engagementStats.shares,
onShareClick = onShareClick,
onQuoteClick = onQuoteClick
onQuoteClick = if (post.viewerCanQuote) onQuoteClick else null
)

// Heart/React — tap to toggle ❤️, long-press for emoji picker
Expand Down
Loading
Loading