Add comments under events to activities
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
58ee8e679b
commit
1f926902aa
|
@ -35,7 +35,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { usernameWithDomain } from "@/types/actor";
|
import { usernameWithDomain } from "@/types/actor";
|
||||||
import { ActivityEventSubject } from "@/types/enums";
|
import {
|
||||||
|
ActivityEventCommentSubject,
|
||||||
|
ActivityEventSubject,
|
||||||
|
} from "@/types/enums";
|
||||||
import { mixins } from "vue-class-component";
|
import { mixins } from "vue-class-component";
|
||||||
import { Component } from "vue-property-decorator";
|
import { Component } from "vue-property-decorator";
|
||||||
import RouteName from "../../router/name";
|
import RouteName from "../../router/name";
|
||||||
|
@ -69,6 +72,17 @@ export default class EventActivityItem extends mixins(ActivityMixin) {
|
||||||
return "You deleted the event {event}.";
|
return "You deleted the event {event}.";
|
||||||
}
|
}
|
||||||
return "The event {event} was deleted by {profile}.";
|
return "The event {event} was deleted by {profile}.";
|
||||||
|
case ActivityEventCommentSubject.COMMENT_POSTED:
|
||||||
|
if (this.subjectParams.comment_reply_to) {
|
||||||
|
if (this.isAuthorCurrentActor) {
|
||||||
|
return "You replied to a comment on the event {event}.";
|
||||||
|
}
|
||||||
|
return "{profile} replied to a comment on the event {event}.";
|
||||||
|
}
|
||||||
|
if (this.isAuthorCurrentActor) {
|
||||||
|
return "You posted a comment on the event {event}.";
|
||||||
|
}
|
||||||
|
return "{profile} posted a comment on the event {event}.";
|
||||||
default:
|
default:
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +91,7 @@ export default class EventActivityItem extends mixins(ActivityMixin) {
|
||||||
get iconColor(): string | undefined {
|
get iconColor(): string | undefined {
|
||||||
switch (this.activity.subject) {
|
switch (this.activity.subject) {
|
||||||
case ActivityEventSubject.EVENT_CREATED:
|
case ActivityEventSubject.EVENT_CREATED:
|
||||||
|
case ActivityEventCommentSubject.COMMENT_POSTED:
|
||||||
return "is-success";
|
return "is-success";
|
||||||
case ActivityEventSubject.EVENT_UPDATED:
|
case ActivityEventSubject.EVENT_UPDATED:
|
||||||
return "is-grey";
|
return "is-grey";
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
<span
|
<span
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
class="level-item reply-btn"
|
class="level-item reply-btn"
|
||||||
@click="createReplyToComment(comment)"
|
@click="createReplyToComment()"
|
||||||
>
|
>
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<b-icon icon="reply" />
|
<b-icon icon="reply" />
|
||||||
|
@ -235,17 +235,13 @@ export default class Comment extends Vue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async createReplyToComment(comment: IComment): Promise<void> {
|
async createReplyToComment(): Promise<void> {
|
||||||
if (this.replyTo) {
|
if (this.replyTo) {
|
||||||
this.replyTo = false;
|
this.replyTo = false;
|
||||||
this.newComment = new CommentModel();
|
this.newComment = new CommentModel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.replyTo = true;
|
this.replyTo = true;
|
||||||
// this.newComment.inReplyToComment = comment;
|
|
||||||
await this.$nextTick();
|
|
||||||
await this.$nextTick(); // For some reason commenteditor needs two $nextTick() to fully render
|
|
||||||
this.commentEditor.replyToComment(comment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
replyToComment(): void {
|
replyToComment(): void {
|
||||||
|
@ -303,7 +299,7 @@ export default class Comment extends Vue {
|
||||||
|
|
||||||
get commentId(): string {
|
get commentId(): string {
|
||||||
if (this.comment.originComment)
|
if (this.comment.originComment)
|
||||||
return `#comment-${this.comment.originComment.uuid}:${this.comment.uuid}`;
|
return `#comment-${this.comment.originComment.uuid}-${this.comment.uuid}`;
|
||||||
return `#comment-${this.comment.uuid}`;
|
return `#comment-${this.comment.uuid}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,9 @@ export const GROUP_TIMELINE = gql`
|
||||||
title
|
title
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
|
... on Comment {
|
||||||
|
id
|
||||||
|
}
|
||||||
... on Group {
|
... on Group {
|
||||||
id
|
id
|
||||||
preferredUsername
|
preferredUsername
|
||||||
|
|
|
@ -963,5 +963,9 @@
|
||||||
"Delete discussion": "Delete discussion",
|
"Delete discussion": "Delete discussion",
|
||||||
"All activities": "All activities",
|
"All activities": "All activities",
|
||||||
"From yourself": "From yourself",
|
"From yourself": "From yourself",
|
||||||
"By others": "By others"
|
"By others": "By others",
|
||||||
|
"You posted a comment on the event {event}.": "You posted a comment on the event {event}.",
|
||||||
|
"{profile} posted a comment on the event {event}.": "{profile} posted a comment on the event {event}.",
|
||||||
|
"You replied to a comment on the event {event}.": "You replied to a comment on the event {event}.",
|
||||||
|
"{profile} replied to a comment on the event {event}.": "{profile} replied to a comment on the event {event}."
|
||||||
}
|
}
|
||||||
|
|
|
@ -1057,5 +1057,9 @@
|
||||||
"Delete discussion": "Supprimer la discussion",
|
"Delete discussion": "Supprimer la discussion",
|
||||||
"All activities": "Toutes les activités",
|
"All activities": "Toutes les activités",
|
||||||
"From yourself": "De vous",
|
"From yourself": "De vous",
|
||||||
"By others": "Des autres"
|
"By others": "Des autres",
|
||||||
|
"You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.",
|
||||||
|
"{profile} posted a comment on the event {event}.": "{profile} a posté un commentaire sur l'événement {event}.",
|
||||||
|
"You replied to a comment on the event {event}.": "Vous avez répondu à un commentaire sur l'événement {event}.",
|
||||||
|
"{profile} replied to a comment on the event {event}.": "{profile} a répondu à un commentaire sur l'événement {event}."
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { IActor, IGroup } from "./actor";
|
||||||
import { IMember } from "./actor/member.model";
|
import { IMember } from "./actor/member.model";
|
||||||
import {
|
import {
|
||||||
ActivityDiscussionSubject,
|
ActivityDiscussionSubject,
|
||||||
|
ActivityEventCommentSubject,
|
||||||
ActivityEventSubject,
|
ActivityEventSubject,
|
||||||
ActivityGroupSubject,
|
ActivityGroupSubject,
|
||||||
ActivityMemberSubject,
|
ActivityMemberSubject,
|
||||||
|
@ -19,7 +20,8 @@ export type ActivitySubject =
|
||||||
| ActivityMemberSubject
|
| ActivityMemberSubject
|
||||||
| ActivityResourceSubject
|
| ActivityResourceSubject
|
||||||
| ActivityDiscussionSubject
|
| ActivityDiscussionSubject
|
||||||
| ActivityGroupSubject;
|
| ActivityGroupSubject
|
||||||
|
| ActivityEventCommentSubject;
|
||||||
|
|
||||||
export interface IActivity {
|
export interface IActivity {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -197,6 +197,10 @@ export enum ActivityEventSubject {
|
||||||
EVENT_DELETED = "event_deleted",
|
EVENT_DELETED = "event_deleted",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ActivityEventCommentSubject {
|
||||||
|
COMMENT_POSTED = "comment_posted",
|
||||||
|
}
|
||||||
|
|
||||||
export enum ActivityPostSubject {
|
export enum ActivityPostSubject {
|
||||||
POST_CREATED = "post_created",
|
POST_CREATED = "post_created",
|
||||||
POST_UPDATED = "post_updated",
|
POST_UPDATED = "post_updated",
|
||||||
|
|
|
@ -168,7 +168,6 @@ import { IActivity } from "../../types/activity.model";
|
||||||
import Observer from "../../components/Utils/Observer.vue";
|
import Observer from "../../components/Utils/Observer.vue";
|
||||||
import SkeletonActivityItem from "../../components/Activity/SkeletonActivityItem.vue";
|
import SkeletonActivityItem from "../../components/Activity/SkeletonActivityItem.vue";
|
||||||
import RouteName from "../../router/name";
|
import RouteName from "../../router/name";
|
||||||
import { Location } from "vue-router";
|
|
||||||
|
|
||||||
const PAGINATION_LIMIT = 25;
|
const PAGINATION_LIMIT = 25;
|
||||||
const SKELETON_DAY_ITEMS = 2;
|
const SKELETON_DAY_ITEMS = 2;
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
||||||
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
|
alias Mobilizon.Federation.ActivityStream.Converter.Utils, as: ConverterUtils
|
||||||
alias Mobilizon.Federation.ActivityStream.Convertible
|
alias Mobilizon.Federation.ActivityStream.Convertible
|
||||||
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
|
alias Mobilizon.GraphQL.API.Utils, as: APIUtils
|
||||||
|
alias Mobilizon.Service.Activity.Comment, as: CommentActivity
|
||||||
alias Mobilizon.Share
|
alias Mobilizon.Share
|
||||||
alias Mobilizon.Tombstone
|
alias Mobilizon.Tombstone
|
||||||
alias Mobilizon.Web.Endpoint
|
alias Mobilizon.Web.Endpoint
|
||||||
|
@ -24,6 +25,10 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Comments do
|
||||||
:ok <- make_sure_event_allows_commenting(args),
|
:ok <- make_sure_event_allows_commenting(args),
|
||||||
{:ok, %Comment{discussion_id: discussion_id} = comment} <-
|
{:ok, %Comment{discussion_id: discussion_id} = comment} <-
|
||||||
Discussions.create_comment(args),
|
Discussions.create_comment(args),
|
||||||
|
{:ok, _} <-
|
||||||
|
CommentActivity.insert_activity(comment,
|
||||||
|
subject: "comment_posted"
|
||||||
|
),
|
||||||
:ok <- maybe_publish_graphql_subscription(discussion_id),
|
:ok <- maybe_publish_graphql_subscription(discussion_id),
|
||||||
comment_as_data <- Convertible.model_to_as(comment),
|
comment_as_data <- Convertible.model_to_as(comment),
|
||||||
audience <-
|
audience <-
|
||||||
|
|
|
@ -78,6 +78,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Activity do
|
||||||
Actors.get_actor(group_id)
|
Actors.get_actor(group_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp get_object(:comment, comment_id) do
|
||||||
|
Discussions.get_comment(comment_id)
|
||||||
|
end
|
||||||
|
|
||||||
@spec transform_params(map()) :: list()
|
@spec transform_params(map()) :: list()
|
||||||
defp transform_params(params) do
|
defp transform_params(params) do
|
||||||
Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
|
Enum.map(params, fn {key, value} -> %{key: key, value: transform_value(value)} end)
|
||||||
|
|
|
@ -5,7 +5,7 @@ defmodule Mobilizon.GraphQL.Schema.ActivityType do
|
||||||
use Absinthe.Schema.Notation
|
use Absinthe.Schema.Notation
|
||||||
|
|
||||||
alias Mobilizon.Actors.{Actor, Member}
|
alias Mobilizon.Actors.{Actor, Member}
|
||||||
alias Mobilizon.Discussions.Discussion
|
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||||
alias Mobilizon.Events.Event
|
alias Mobilizon.Events.Event
|
||||||
alias Mobilizon.Posts.Post
|
alias Mobilizon.Posts.Post
|
||||||
alias Mobilizon.Resources.Resource
|
alias Mobilizon.Resources.Resource
|
||||||
|
@ -51,6 +51,9 @@ defmodule Mobilizon.GraphQL.Schema.ActivityType do
|
||||||
%Discussion{}, _ ->
|
%Discussion{}, _ ->
|
||||||
:discussion
|
:discussion
|
||||||
|
|
||||||
|
%Comment{}, _ ->
|
||||||
|
:comment
|
||||||
|
|
||||||
%Actor{type: :Group}, _ ->
|
%Actor{type: :Group}, _ ->
|
||||||
:group
|
:group
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
|
||||||
|
|
||||||
@desc "A comment"
|
@desc "A comment"
|
||||||
object :comment do
|
object :comment do
|
||||||
interfaces([:action_log_object])
|
interfaces([:action_log_object, :activity_object])
|
||||||
field(:id, :id, description: "Internal ID for this comment")
|
field(:id, :id, description: "Internal ID for this comment")
|
||||||
field(:uuid, :uuid, description: "An UUID for this comment")
|
field(:uuid, :uuid, description: "An UUID for this comment")
|
||||||
field(:url, :string, description: "Comment URL")
|
field(:url, :string, description: "Comment URL")
|
||||||
|
|
|
@ -53,7 +53,7 @@ defmodule Mobilizon.Activities do
|
||||||
@resource_activity_subjects ++
|
@resource_activity_subjects ++
|
||||||
@member_activity_subjects ++ @settings_activity_subjects
|
@member_activity_subjects ++ @settings_activity_subjects
|
||||||
|
|
||||||
@object_type ["event", "actor", "post", "discussion", "resource", "member", "group"]
|
@object_type ["event", "actor", "post", "discussion", "resource", "member", "group", "comment"]
|
||||||
|
|
||||||
defenum(Type, @activity_types)
|
defenum(Type, @activity_types)
|
||||||
defenum(Subject, @subjects)
|
defenum(Subject, @subjects)
|
||||||
|
|
51
lib/service/activity/comment.ex
Normal file
51
lib/service/activity/comment.ex
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
defmodule Mobilizon.Service.Activity.Comment do
|
||||||
|
@moduledoc """
|
||||||
|
Insert a comment activity
|
||||||
|
"""
|
||||||
|
alias Mobilizon.{Actors, Events}
|
||||||
|
alias Mobilizon.Actors.Actor
|
||||||
|
alias Mobilizon.Discussions.Comment
|
||||||
|
alias Mobilizon.Events.Event
|
||||||
|
alias Mobilizon.Service.Activity
|
||||||
|
alias Mobilizon.Service.Workers.ActivityBuilder
|
||||||
|
|
||||||
|
@behaviour Activity
|
||||||
|
|
||||||
|
@impl Activity
|
||||||
|
def insert_activity(comment, options \\ [])
|
||||||
|
|
||||||
|
def insert_activity(
|
||||||
|
%Comment{
|
||||||
|
actor_id: actor_id,
|
||||||
|
event_id: event_id,
|
||||||
|
in_reply_to_comment_id: in_reply_to_comment_id
|
||||||
|
} = comment,
|
||||||
|
options
|
||||||
|
)
|
||||||
|
when not is_nil(actor_id) and not is_nil(event_id) do
|
||||||
|
with {:ok, %Event{attributed_to: %Actor{type: :Group} = group} = event} <-
|
||||||
|
Events.get_event_with_preload(event_id),
|
||||||
|
%Actor{id: actor_id} <- Actors.get_actor(actor_id),
|
||||||
|
subject <- Keyword.fetch!(options, :subject) do
|
||||||
|
ActivityBuilder.enqueue(:build_activity, %{
|
||||||
|
"type" => "event",
|
||||||
|
"subject" => subject,
|
||||||
|
"subject_params" => %{
|
||||||
|
event_title: event.title,
|
||||||
|
event_uuid: event.uuid,
|
||||||
|
comment_reply_to: !is_nil(in_reply_to_comment_id)
|
||||||
|
},
|
||||||
|
"group_id" => group.id,
|
||||||
|
"author_id" => actor_id,
|
||||||
|
"object_type" => "comment",
|
||||||
|
"object_id" => to_string(comment.id),
|
||||||
|
"inserted_at" => DateTime.utc_now()
|
||||||
|
})
|
||||||
|
else
|
||||||
|
# Event not from group
|
||||||
|
{:ok, %Event{}} -> {:ok, nil}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_activity(_, _), do: {:ok, nil}
|
||||||
|
end
|
Loading…
Reference in a new issue