Merge branch 'bugs' into 'main'

Various bugs

Closes #873 et #862

See merge request framasoft/mobilizon!1108
This commit is contained in:
Thomas Citharel 2021-11-13 15:12:25 +00:00
commit 3d2fea6bb8
21 changed files with 151 additions and 127 deletions

View file

@ -9,7 +9,7 @@
type="is-danger"
:title="$t('Warning').toLocaleUpperCase()"
closable
aria-close-label="Close"
:aria-close-label="$t('Close')"
>
<p>
{{ $t("This is a demonstration site to test Mobilizon.") }}

View file

@ -299,6 +299,10 @@ export default class Comment extends Vue {
onConfirm: this.reportComment,
outsideDomain: this.comment.actor.domain,
},
// https://github.com/buefy/buefy/pull/3589
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
closeButtonAriaLabel: this.$t("Close"),
});
}

View file

@ -45,8 +45,8 @@
type="is-primary"
class="comment-button-submit"
icon-left="send"
:aria-label="$t('Post a comment')"
/>
>{{ $t("Send") }}</b-button
>
</div>
</article>
</form>
@ -63,7 +63,7 @@
<transition-group
key="list"
name="comment-list"
v-if="comments.length"
v-if="filteredOrderedComments.length"
class="comment-list"
tag="ul"
>
@ -77,9 +77,9 @@
@delete-comment="deleteComment"
/>
</transition-group>
<div v-else class="no-comments" key="no-comments">
<empty-content v-else icon="comment" key="no-comments" :inline="true">
<span>{{ $t("No comments yet") }}</span>
</div>
</empty-content>
</transition-group>
</div>
</template>
@ -99,6 +99,7 @@ import { CURRENT_ACTOR_CLIENT } from "../../graphql/actor";
import { IPerson } from "../../types/actor";
import { IEvent } from "../../types/event.model";
import { ApolloCache, FetchResult, InMemoryCache } from "@apollo/client/core";
import EmptyContent from "@/components/Utils/EmptyContent.vue";
@Component({
apollo: {
@ -119,6 +120,7 @@ import { ApolloCache, FetchResult, InMemoryCache } from "@apollo/client/core";
components: {
Comment,
IdentityPickerWrapper,
EmptyContent,
editor: () =>
import(/* webpackChunkName: "editor" */ "@/components/Editor.vue"),
},
@ -364,21 +366,34 @@ export default class CommentTree extends Vue {
<style lang="scss" scoped>
@use "@/styles/_mixins" as *;
@import "~bulma/sass/utilities/mixins.sass";
form.new-comment {
padding-bottom: 1rem;
.media-content {
display: flex;
align-items: center;
align-content: center;
.media {
flex-wrap: wrap;
justify-content: center;
.media-left {
@include mobile {
@include margin-right(0.5rem);
@include margin-left(0.5rem);
}
}
.field {
flex: 1;
@include padding-right(10px);
margin-bottom: 0;
.media-content {
display: flex;
align-items: center;
align-content: center;
width: min-content;
&.notify-participants {
margin-top: 0.5rem;
.field {
flex: 1;
@include padding-right(10px);
margin-bottom: 0;
&.notify-participants {
margin-top: 0.5rem;
}
}
}
}

View file

@ -145,8 +145,10 @@ export default class DiscussionComment extends Vue {
}
updateComment(): void {
this.comment.text = this.updatedComment;
this.$emit("update-comment", this.comment);
this.$emit("update-comment", {
...this.comment,
text: this.updatedComment,
});
this.toggleEditMode();
}
}

View file

@ -62,7 +62,11 @@
</b-button>
</p>
</b-field>
<b-modal has-modal-card v-model="showNewElementModal">
<b-modal
has-modal-card
v-model="showNewElementModal"
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<header class="modal-card-head">
<button

View file

@ -46,7 +46,11 @@
/>
<b-icon v-else size="is-large" icon="account-circle" />
</span>
<b-modal :active.sync="isComponentModalActive" has-modal-card>
<b-modal
:active.sync="isComponentModalActive"
has-modal-card
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">{{ $t("Pick a profile or a group") }}</p>

View file

@ -65,6 +65,7 @@
<b-modal
:active.sync="isAnonymousParticipationModalOpen"
has-modal-card
:close-button-aria-label="$t('Close')"
ref="anonymous-participation-modal"
>
<div class="modal-card">

View file

@ -1,7 +1,7 @@
<template>
<div class="modal-card">
<header class="modal-card-head" v-if="title">
<p class="modal-card-title">{{ title }}</p>
<h2 class="modal-card-title">{{ title }}</h2>
</header>
<section
@ -17,7 +17,7 @@
<article class="media">
<div class="media-left">
<figure class="image is-48x48" v-if="comment.actor.avatar">
<img :src="comment.actor.avatar.url" alt="Image" />
<img :src="comment.actor.avatar.url" alt="" />
</figure>
<b-icon
class="media-left"
@ -45,12 +45,16 @@
</p>
<div class="control">
<b-input
v-model="content"
type="textarea"
@keyup.enter="confirm"
:placeholder="$t('Additional comments')"
/>
<b-field
:label="$t('Additional comments')"
label-for="additonal-comments"
>
<b-input
v-model="content"
type="textarea"
id="additonal-comments"
/>
</b-field>
</div>
<div class="control" v-if="outsideDomain">
@ -73,7 +77,12 @@
<button class="button" ref="cancelButton" @click="close">
{{ translatedCancelText }}
</button>
<button class="button is-primary" ref="confirmButton" @click="confirm">
<button
class="button is-primary"
ref="confirmButton"
@click="confirm"
@keyup.enter="confirm"
>
{{ translatedConfirmText }}
</button>
</footer>

View file

@ -1246,5 +1246,10 @@
"Your membership was approved by {profile}.": "Your membership was approved by {profile}.",
"{profile} approved {member}'s membership.": "{profile} approved {member}'s membership.",
"You rejected {member}'s membership request.": "You rejected {member}'s membership request.",
"{profile} rejected {member}'s membership request.": "{profile} rejected {member}'s membership request."
"{profile} rejected {member}'s membership request.": "{profile} rejected {member}'s membership request.",
"Send": "Send",
"Approve member": "Approve member",
"Reject member": "Reject member",
"The membership request from {profile} was rejected": "The membership request from {profile} was rejected",
"The member was approved": "The member was approved"
}

View file

@ -165,7 +165,7 @@
"Click for more information": "Cliquez pour plus d'informations",
"Click to select": "Cliquez pour sélectionner",
"Click to upload": "Cliquez pour téléverser",
"Close": "Fermé",
"Close": "Fermer",
"Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateur⋅rice·s)",
"Closed": "Fermé",
"Comment deleted": "Commentaire supprimé",
@ -1350,5 +1350,10 @@
"Your membership was approved by {profile}.": "Votre demande d'adhésion a été approuvée par {profile}.",
"{profile} approved {member}'s membership.": "{profile} a approuvé la demande d'adhésion de {member}.",
"You rejected {member}'s membership request.": "Vous avez rejeté la demande d'adhésion de {member}.",
"{profile} rejected {member}'s membership request.": "{profile} a rejeté la demande d'adhésion de {member}."
"{profile} rejected {member}'s membership request.": "{profile} a rejeté la demande d'adhésion de {member}.",
"Send": "Envoyer",
"Approve member": "Approuver le ou la membre",
"Reject member": "Rejeter le ou la membre",
"The membership request from {profile} was rejected": "La demande d'adhésion de {profile} a été rejetée",
"The member was approved": "Le ou la membre a été approuvée"
}

View file

@ -45,7 +45,11 @@
</figure>
<b-icon v-else size="is-large" icon="account-circle" />
</span>
<b-modal v-model="isComponentModalActive" has-modal-card>
<b-modal
v-model="isComponentModalActive"
has-modal-card
:close-button-aria-label="$t('Close')"
>
<identity-picker v-model="currentIdentity" />
</b-modal>
</div>

View file

@ -154,7 +154,7 @@ import { GraphQLError } from "graphql";
import { DELETE_COMMENT, UPDATE_COMMENT } from "@/graphql/comment";
import RouteName from "../../router/name";
import { IComment } from "../../types/comment.model";
import { ApolloCache, FetchResult } from "@apollo/client/core";
import { ApolloCache, FetchResult, gql, Reference } from "@apollo/client/core";
import { mixins } from "vue-class-component";
import GroupMixin from "@/mixins/group";
@ -310,49 +310,23 @@ export default class Discussion extends mixins(GroupMixin) {
variables: {
commentId: comment.id,
},
update: (
store: ApolloCache<{ deleteComment: IComment }>,
{ data }: FetchResult
) => {
if (!data || !data.deleteComment) return;
const discussionData = store.readQuery<{
discussion: IDiscussion;
}>({
query: GET_DISCUSSION,
variables: {
slug: this.slug,
page: this.page,
},
});
if (!discussionData) return;
const { discussion: discussionCached } = discussionData;
const index = discussionCached.comments.elements.findIndex(
({ id }) => id === data.deleteComment.id
);
let discussionUpdated = discussionCached;
if (index > -1) {
const updatedComment = {
...discussionCached.comments.elements[index],
update: (store: ApolloCache<{ deleteComment: IComment }>) => {
store.writeFragment({
id: store.identify(comment as unknown as Reference),
fragment: gql`
fragment CommentDeleted on Comment {
deletedAt
actor {
id
}
text
}
`,
data: {
deletedAt: new Date(),
text: "",
actor: null,
updatedComment: {
text: "",
},
};
const elements = [...discussionCached.comments.elements];
elements.splice(index, 1, updatedComment);
discussionUpdated = {
...discussionCached,
comments: {
total: discussionCached.comments.total,
elements,
},
};
}
store.writeQuery({
query: GET_DISCUSSION,
variables: { slug: this.slug, page: this.page },
data: { discussion: discussionUpdated },
},
});
},
});
@ -369,20 +343,6 @@ export default class Discussion extends mixins(GroupMixin) {
page: this.page,
limit: this.COMMENTS_PER_PAGE,
},
updateQuery: (previousResult, { fetchMoreResult }) => {
return {
discussion: {
...previousResult.discussion,
comments: {
...fetchMoreResult.discussion.comments,
elements: [
...previousResult.discussion.comments.elements,
...fetchMoreResult.discussion.comments.elements,
],
},
},
};
},
});
this.hasMoreComments = !this.discussion.comments.elements
.map(({ id }) => id)
@ -399,32 +359,6 @@ export default class Discussion extends mixins(GroupMixin) {
discussionId: this.discussion.id,
title: this.newTitle,
},
update: (
store: ApolloCache<{ updateDiscussion: IDiscussion }>,
{ data }: FetchResult<{ updateDiscussion: IDiscussion }>
) => {
const discussionData = store.readQuery<{
discussion: IDiscussion;
}>({
query: GET_DISCUSSION,
variables: {
slug: this.slug,
page: this.page,
},
});
if (discussionData && data?.updateDiscussion) {
store.writeQuery({
query: GET_DISCUSSION,
variables: { slug: this.slug, page: this.page },
data: {
discussion: {
...discussionData.discussion,
title: data?.updateDiscussion.title,
},
},
});
}
},
});
this.editTitleMode = false;
}

View file

@ -339,7 +339,12 @@
{{ $t("Only group moderators can create, edit and delete events.") }}
</b-message>
</div>
<b-modal v-model="dateSettingsIsOpen" has-modal-card trap-focus>
<b-modal
v-model="dateSettingsIsOpen"
has-modal-card
trap-focus
:close-button-aria-label="$t('Close')"
>
<form action>
<div class="modal-card" style="width: auto">
<header class="modal-card-head">

View file

@ -325,6 +325,7 @@
:active.sync="isReportModalActive"
has-modal-card
ref="reportModal"
:close-button-aria-label="$t('Close')"
>
<report-modal
:on-confirm="reportEvent"
@ -334,6 +335,7 @@
/>
</b-modal>
<b-modal
:close-button-aria-label="$t('Close')"
:active.sync="isShareModalActive"
has-modal-card
ref="shareModal"
@ -344,6 +346,7 @@
:active.sync="isJoinModalActive"
has-modal-card
ref="participationModal"
:close-button-aria-label="$t('Close')"
>
<identity-picker v-model="identity">
<template v-slot:footer>
@ -380,6 +383,7 @@
:active.sync="isJoinConfirmationModalActive"
has-modal-card
ref="joinConfirmationModal"
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<header class="modal-card-head">
@ -427,6 +431,7 @@
</div>
</b-modal>
<b-modal
:close-button-aria-label="$t('Close')"
class="map-modal"
v-if="event.physicalAddress && event.physicalAddress.geom"
:active.sync="showMap"

View file

@ -647,6 +647,7 @@
<b-modal
v-if="physicalAddress && physicalAddress.geom"
:active.sync="showMap"
:close-button-aria-label="$t('Close')"
>
<div class="map">
<map-leaflet
@ -660,6 +661,7 @@
</b-modal>
</div>
<b-modal
:close-button-aria-label="$t('Close')"
:active.sync="isReportModalActive"
has-modal-card
ref="reportModal"
@ -673,6 +675,7 @@
/>
</b-modal>
<b-modal
:close-button-aria-label="$t('Close')"
v-if="group"
:active.sync="isShareModalActive"
has-modal-card

View file

@ -176,6 +176,7 @@
</router-link>
</section>
<b-modal
:close-button-aria-label="$t('Close')"
:active.sync="isReportModalActive"
has-modal-card
ref="reportModal"
@ -187,7 +188,12 @@
@close="$refs.reportModal.close()"
/>
</b-modal>
<b-modal :active.sync="isShareModalActive" has-modal-card ref="shareModal">
<b-modal
:active.sync="isShareModalActive"
has-modal-card
ref="shareModal"
:close-button-aria-label="$t('Close')"
>
<share-post-modal :post="post" />
</b-modal>
</article>

View file

@ -157,7 +157,11 @@
:aria-current-label="$t('Current page')"
>
</b-pagination>
<b-modal :active.sync="renameModal" has-modal-card>
<b-modal
:active.sync="renameModal"
has-modal-card
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<section class="modal-card-body">
<form @submit.prevent="renameResource">
@ -172,7 +176,11 @@
</section>
</div>
</b-modal>
<b-modal :active.sync="moveModal" has-modal-card>
<b-modal
:active.sync="moveModal"
has-modal-card
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<section class="modal-card-body">
<resource-selector
@ -184,7 +192,11 @@
</section>
</div>
</b-modal>
<b-modal :active.sync="createResourceModal" has-modal-card>
<b-modal
:active.sync="createResourceModal"
has-modal-card
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<section class="modal-card-body">
<form @submit.prevent="createResource">
@ -208,6 +220,7 @@
has-modal-card
class="link-resource-modal"
aria-modal
:close-button-aria-label="$t('Close')"
>
<div class="modal-card">
<section class="modal-card-body">

View file

@ -149,6 +149,7 @@
</b-button>
<b-modal
:close-button-aria-label="$t('Close')"
:active.sync="isDeleteAccountModalActive"
has-modal-card
full-screen

View file

@ -162,7 +162,9 @@ describe("CommentTree", () => {
requestHandlers.eventCommentThreadsQueryHandler
).toHaveBeenCalledWith({ eventUUID: eventData.uuid });
expect(wrapper.find(".no-comments").text()).toBe("No comments yet");
expect(wrapper.findComponent({ name: "EmptyContent" }).text()).toBe(
"No comments yet"
);
expect(wrapper.html()).toMatchSnapshot();
});
});

View file

@ -20,7 +20,7 @@ exports[`CommentTree renders a comment tree with comments 1`] = `
</div>
</div>
<div class="send-comment">
<b-button-stub type="is-primary" iconleft="send" nativetype="submit" tag="button" aria-label="Post a comment" class="comment-button-submit"></b-button-stub>
<b-button-stub type="is-primary" iconleft="send" nativetype="submit" tag="button" class="comment-button-submit">Send</b-button-stub>
</div>
</article>
</form>
@ -62,12 +62,12 @@ exports[`CommentTree renders an empty comment tree 1`] = `
</div>
</div>
<div class="send-comment">
<b-button-stub type="is-primary" iconleft="send" nativetype="submit" tag="button" aria-label="Post a comment" class="comment-button-submit"></b-button-stub>
<b-button-stub type="is-primary" iconleft="send" nativetype="submit" tag="button" class="comment-button-submit">Send</b-button-stub>
</div>
</article>
</form>
<transition-group-stub tag="div" name="comment-empty-list">
<div class="no-comments"><span>No comments yet</span></div>
<empty-content-stub icon="comment" inline="true"><span>No comments yet</span></empty-content-stub>
</transition-group-stub>
</div>
`;

View file

@ -3,7 +3,7 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
Tools for calculating content audience
"""
alias Mobilizon.{Actors, Events, Share}
alias Mobilizon.{Actors, Discussions, Events, Share}
alias Mobilizon.Actors.{Actor, Member}
alias Mobilizon.Discussions.{Comment, Discussion}
alias Mobilizon.Events.{Event, Participant}
@ -43,8 +43,10 @@ defmodule Mobilizon.Federation.ActivityPub.Audience do
%{"to" => [@ap_public], "cc" => []}
end
def get_audience(%Comment{discussion: %Discussion{} = discussion}) do
get_audience(discussion)
def get_audience(%Comment{discussion: %Discussion{id: discussion_id}}) do
discussion_id
|> Discussions.get_discussion()
|> get_audience()
end
def get_audience(%Comment{