commit: e009510c52d62a19136e01d9f0753448ad703016
parent 515dcfd3395ce4c6bd228e6bfc20120de78976c1
Author: HJ <30-hj@users.noreply.git.pleroma.social>
Date: Thu, 22 Dec 2022 13:14:30 +0000
Merge branch 'from/develop/tusooa/user-note' into 'develop'
User note
See merge request pleroma/pleroma-fe!1612
Diffstat:
9 files changed, 182 insertions(+), 3 deletions(-)
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
@@ -4,6 +4,7 @@ import ProgressButton from '../progress_button/progress_button.vue'
import FollowButton from '../follow_button/follow_button.vue'
import ModerationTools from '../moderation_tools/moderation_tools.vue'
import AccountActions from '../account_actions/account_actions.vue'
+import UserNote from '../user_note/user_note.vue'
import Select from '../select/select.vue'
import UserLink from '../user_link/user_link.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
@@ -39,7 +40,8 @@ export default {
'rounded',
'bordered',
'avatarAction', // default - open profile, 'zoom' - zoom, function - call function
- 'onClose'
+ 'onClose',
+ 'hasNoteEditor'
],
data () {
return {
@@ -129,6 +131,12 @@ export default {
const privileges = this.loggedIn.privileges
return this.loggedIn.role === 'admin' || privileges.includes('users_manage_activation_state') || privileges.includes('users_delete') || privileges.includes('users_manage_tags')
},
+ hasNote () {
+ return this.relationship.note
+ },
+ supportsNote () {
+ return 'note' in this.relationship
+ },
...mapGetters(['mergedConfig'])
},
components: {
@@ -140,7 +148,8 @@ export default {
FollowButton,
Select,
RichContent,
- UserLink
+ UserLink,
+ UserNote
},
methods: {
muteUser () {
diff --git a/src/components/user_card/user_card.scss b/src/components/user_card/user_card.scss
@@ -315,6 +315,10 @@
margin: 0;
}
}
+
+ .user-note {
+ margin: 0 .75em .6em 0;
+ }
}
.sidebar .edit-profile-button {
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
@@ -268,6 +268,12 @@
>
<RemoteFollow :user="user" />
</div>
+ <UserNote
+ v-if="loggedIn && isOtherUser && (hasNote || (hasNoteEditor && supportsNote))"
+ :user="user"
+ :relationship="relationship"
+ :editable="hasNoteEditor"
+ />
</div>
</div>
<div
diff --git a/src/components/user_note/user_note.js b/src/components/user_note/user_note.js
@@ -0,0 +1,45 @@
+const UserNote = {
+ props: {
+ user: Object,
+ relationship: Object,
+ editable: Boolean
+ },
+ data () {
+ return {
+ localNote: '',
+ editing: false,
+ frozen: false
+ }
+ },
+ computed: {
+ shouldShow () {
+ return this.relationship.note || this.editing
+ }
+ },
+ methods: {
+ startEditing () {
+ this.localNote = this.relationship.note
+ this.editing = true
+ },
+ cancelEditing () {
+ this.editing = false
+ },
+ finalizeEditing () {
+ this.frozen = true
+
+ this.$store.dispatch('editUserNote', {
+ id: this.user.id,
+ comment: this.localNote
+ })
+ .then(() => {
+ this.frozen = false
+ this.editing = false
+ })
+ .catch(() => {
+ this.frozen = false
+ })
+ }
+ }
+}
+
+export default UserNote
diff --git a/src/components/user_note/user_note.vue b/src/components/user_note/user_note.vue
@@ -0,0 +1,88 @@
+<template>
+ <div
+ class="user-note"
+ >
+ <div class="heading">
+ <span>{{ $t('user_card.note') }}</span>
+ <div class="buttons">
+ <button
+ v-show="!editing && editable"
+ class="button-default btn"
+ @click="startEditing"
+ >
+ {{ $t('user_card.edit_note') }}
+ </button>
+ <button
+ v-show="editing"
+ class="button-default btn"
+ :disabled="frozen"
+ @click="finalizeEditing"
+ >
+ {{ $t('user_card.edit_note_apply') }}
+ </button>
+ <button
+ v-show="editing"
+ class="button-default btn"
+ :disabled="frozen"
+ @click="cancelEditing"
+ >
+ {{ $t('user_card.edit_note_cancel') }}
+ </button>
+ </div>
+ </div>
+ <textarea
+ v-show="editing"
+ v-model="localNote"
+ class="note-text"
+ />
+ <span
+ v-show="!editing"
+ class="note-text"
+ :class="{ '-blank': !relationship.note }"
+ >
+ {{ relationship.note || $t('user_card.note_blank') }}
+ </span>
+ </div>
+</template>
+
+<script src="./user_note.js"></script>
+
+<style lang="scss">
+@import '../../variables';
+
+.user-note {
+ display: flex;
+ flex-direction: column;
+
+ .heading {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 0.75em;
+
+ .btn {
+ min-width: 95px;
+ }
+
+ .buttons {
+ display: flex;
+ flex-direction: row;
+ justify-content: right;
+
+ .btn {
+ margin-left: 0.5em;
+ }
+ }
+ }
+
+ .note-text {
+ align-self: stretch;
+ }
+
+ .note-text.-blank {
+ font-style: italic;
+ color: var(--faint, $fallback--faint);
+ }
+}
+</style>
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
@@ -10,6 +10,7 @@
:selected="timeline.viewing"
avatar-action="zoom"
rounded="top"
+ :has-note-editor="true"
/>
<div
v-if="user.fields_html && user.fields_html.length > 0"
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -957,7 +957,12 @@
"solid": "Solid bg",
"striped": "Striped bg",
"side": "Side stripe"
- }
+ },
+ "note": "Note",
+ "note_blank": "(None)",
+ "edit_note": "Edit note",
+ "edit_note_apply": "Apply",
+ "edit_note_cancel": "Cancel"
},
"user_profile": {
"timeline_title": "User timeline",
diff --git a/src/modules/users.js b/src/modules/users.js
@@ -56,6 +56,11 @@ const removeUserFromFollowers = (store, id) => {
.then((relationship) => store.commit('updateUserRelationship', [relationship]))
}
+const editUserNote = (store, { id, comment }) => {
+ return store.rootState.api.backendInteractor.editUserNote({ id, comment })
+ .then((relationship) => store.commit('updateUserRelationship', [relationship]))
+}
+
const muteUser = (store, id) => {
const predictedRelationship = store.state.relationships[id] || { id }
predictedRelationship.muting = true
@@ -335,6 +340,9 @@ const users = {
unblockUsers (store, ids = []) {
return Promise.all(ids.map(id => unblockUser(store, id)))
},
+ editUserNote (store, args) {
+ return editUserNote(store, args)
+ },
fetchMutes (store) {
return store.rootState.api.backendInteractor.fetchMutes()
.then((mutes) => {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
@@ -70,6 +70,7 @@ const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute`
const MASTODON_REMOVE_USER_FROM_FOLLOWERS = id => `/api/v1/accounts/${id}/remove_from_followers`
const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe`
const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe`
+const MASTODON_USER_NOTE_URL = id => `/api/v1/accounts/${id}/note`
const MASTODON_BOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/bookmark`
const MASTODON_UNBOOKMARK_STATUS_URL = id => `/api/v1/statuses/${id}/unbookmark`
const MASTODON_POST_STATUS_URL = '/api/v1/statuses'
@@ -321,6 +322,17 @@ const removeUserFromFollowers = ({ id, credentials }) => {
}).then((data) => data.json())
}
+const editUserNote = ({ id, credentials, comment }) => {
+ return promisedRequest({
+ url: MASTODON_USER_NOTE_URL(id),
+ credentials,
+ payload: {
+ comment
+ },
+ method: 'POST'
+ })
+}
+
const approveUser = ({ id, credentials }) => {
const url = MASTODON_APPROVE_USER_URL(id)
return fetch(url, {
@@ -1667,6 +1679,7 @@ const apiService = {
blockUser,
unblockUser,
removeUserFromFollowers,
+ editUserNote,
fetchUser,
fetchUserByName,
fetchUserRelationship,