diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ce8f40..0a193e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add a dialog window with a confirmation when a remove button is clicked on the Settings page - Disable tab on the Settings page if there are no settings on this tab that can be changed in Admin FE - Settings that can't be altered in Admin FE are removed: HTTP Signatures settings, Federation publisher modules and Oban Repo +- When rendering user's profile, statuses, reports and notes check if required properties exist +- Remove ability to moderate users that don't have valid nickname ### Fixed diff --git a/src/api/__mocks__/reports.js b/src/api/__mocks__/reports.js index 5c6fe3a1..5d2e2097 100644 --- a/src/api/__mocks__/reports.js +++ b/src/api/__mocks__/reports.js @@ -1,14 +1,14 @@ const reports = [ - { created_at: '2019-05-21T21:35:33.000Z', account: { display_name: 'Benjamin Fame', tags: [] }, actor: {}, state: 'open', id: '2', content: 'This is a report', statuses: [] }, - { created_at: '2019-05-20T22:45:33.000Z', account: { display_name: 'Alice Pool', tags: [] }, actor: {}, state: 'resolved', id: '1', content: 'Please block this user', statuses: [] }, - { created_at: '2019-05-18T13:01:33.000Z', account: { display_name: 'Nick Keys', tags: [] }, actor: {}, state: 'closed', id: '3', content: '', statuses: [] }, - { created_at: '2019-05-21T21:35:33.000Z', account: { display_name: 'Benjamin Fame', tags: [] }, actor: {}, state: 'open', id: '5', content: 'This is a report', statuses: [] }, - { created_at: '2019-05-20T22:45:33.000Z', account: { display_name: 'Alice Pool', tags: [] }, actor: {}, state: 'resolved', id: '7', content: 'Please block this user', statuses: [ - { account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' }, - { account: { display_name: 'Alice Pool', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' } + { created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '2', content: 'This is a report', statuses: [] }, + { created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '1', content: 'Please block this user', statuses: [] }, + { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '3', content: '', statuses: [] }, + { created_at: '2019-05-21T21:35:33.000Z', account: { nickname: 'benjamin', tags: [] }, actor: {}, state: 'open', id: '5', content: 'This is a report', statuses: [] }, + { created_at: '2019-05-20T22:45:33.000Z', account: { nickname: 'alice', tags: [] }, actor: {}, state: 'resolved', id: '7', content: 'Please block this user', statuses: [ + { account: { nickname: 'alice', avatar: '' }, visibility: 'public', sensitive: false, id: '11', content: 'Hey!', url: '', created_at: '2019-05-10T21:35:33.000Z' }, + { account: { nickname: 'alice', avatar: '' }, visibility: 'unlisted', sensitive: true, id: '10', content: 'Bye!', url: '', created_at: '2019-05-10T21:00:33.000Z' } ] }, - { created_at: '2019-05-18T13:01:33.000Z', account: { display_name: 'Nick Keys', tags: [] }, actor: {}, state: 'closed', id: '6', content: '', statuses: [] }, - { created_at: '2019-05-18T13:01:33.000Z', account: { display_name: 'Nick Keys', tags: [] }, actor: {}, state: 'closed', id: '4', content: '', statuses: [] } + { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '6', content: '', statuses: [] }, + { created_at: '2019-05-18T13:01:33.000Z', account: { nickname: 'nick_keys', tags: [] }, actor: {}, state: 'closed', id: '4', content: '', statuses: [] } ] export async function fetchReports(filter, page, pageSize, authHost, token) { diff --git a/src/api/__mocks__/status.js b/src/api/__mocks__/status.js index 232ba69a..0fa2ccf5 100644 --- a/src/api/__mocks__/status.js +++ b/src/api/__mocks__/status.js @@ -11,7 +11,7 @@ export async function fetchStatus(id, authHost, token) { account: { id: '9n1bySks25olxWrku0', avatar: 'http://localhost:4000/images/avi.png', - display_name: 'dolin', + nickname: 'dolin', tags: ['strip_media', 'sandbox', 'disable_any_subscription', 'force_nsfw'], url: 'http://localhost:4000/users/dolin' }, @@ -36,7 +36,7 @@ export async function fetchStatusesByInstance({ instance, authHost, token, pageS ? [{ 'account': { 'avatar': 'http://localhost:4000/images/avi.png', - 'display_name': 'sky', + 'nickname': 'sky', 'url': 'http://localhost:4000/users/sky' }, 'content': 'A nice young couple contacted us from Brazil to decorate their newly acquired apartment.', @@ -52,7 +52,7 @@ export async function fetchStatusesByInstance({ instance, authHost, token, pageS { 'account': { 'avatar': 'http://localhost:4000/images/avi.png', - 'display_name': 'sky', + 'nickname': 'sky', 'url': 'http://localhost:4000/users/sky' }, 'content': 'A nice young couple contacted us from Brazil to decorate their newly acquired apartment.', @@ -65,7 +65,7 @@ export async function fetchStatusesByInstance({ instance, authHost, token, pageS { 'account': { 'avatar': 'http://localhost:4000/images/avi.png', - 'display_name': 'sky', + 'nickname': 'sky', 'url': 'http://localhost:4000/users/sky' }, 'content': 'the happiest man ever', diff --git a/src/api/__mocks__/users.js b/src/api/__mocks__/users.js index bdcf404a..7d4172d6 100644 --- a/src/api/__mocks__/users.js +++ b/src/api/__mocks__/users.js @@ -4,12 +4,12 @@ export let users = [ { active: false, deactivated: true, id: 'abc', nickname: 'john', local: true, external: false, roles: { admin: false, moderator: false }, tags: ['strip_media'] } ] -const userProfile = { avatar: 'avatar.jpg', display_name: 'Allis', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false } +const userProfile = { avatar: 'avatar.jpg', nickname: 'allis', id: '2', tags: [], roles: { admin: true, moderator: false }, local: true, external: false } const userStatuses = [ - { account: { id: '9n1bySks25olxWrku0', display_name: 'dolin' }, content: 'pizza makes everything better', id: '9vJOO3iFPyjNaEhJ5s', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }, - { account: { id: '9n1bySks25olxWrku0', display_name: 'dolin' }, content: 'pizza time', id: '9vJPD5XKOdzQ0bvGLY', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }, - { account: { id: '9n1bySks25olxWrku0', display_name: 'dolin' }, content: 'what is yout favorite pizza?', id: '9jop82OBXeFPYulVjM', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' } + { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza makes everything better', id: '9vJOO3iFPyjNaEhJ5s', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }, + { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'pizza time', id: '9vJPD5XKOdzQ0bvGLY', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' }, + { account: { id: '9n1bySks25olxWrku0', nickname: 'dolin' }, content: 'what is yout favorite pizza?', id: '9jop82OBXeFPYulVjM', created_at: '2020-05-22T17:34:34.000Z', visibility: 'public' } ] const filterUsers = (str) => { diff --git a/src/components/Status/index.vue b/src/components/Status/index.vue index ffb8f74c..292e8e68 100644 --- a/src/components/Status/index.vue +++ b/src/components/Status/index.vue @@ -5,16 +5,18 @@
- +
- - + + + + + +
- - - -
@@ -228,6 +230,12 @@ export default { }, parseTimestamp(timestamp) { return moment(timestamp).format('YYYY-MM-DD HH:mm') + }, + propertyExists(account, property, _secondProperty) { + if (_secondProperty) { + return account[property] && account[_secondProperty] + } + return account[property] } } } @@ -245,6 +253,11 @@ export default { .account:hover { text-decoration: underline; } + .deactivated { + color: gray; + line-height: 28px; + vertical-align: middle; + } .image { width: 20%; img { @@ -267,7 +280,8 @@ export default { .status-account-name { display: inline-block; margin: 0; - font-size: 16px; + font-size: 15px; + font-weight: 500; } .status-body { display: flex; diff --git a/src/lang/en.js b/src/lang/en.js index 86bc614c..291bbde3 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -238,7 +238,11 @@ export default { unconfirmedEmail: 'User didn\'t confirm the email', confirmAccount: 'Confirm account', confirmAccounts: 'Confirm accounts', - resendConfirmation: 'Resend confirmation email' + resendConfirmation: 'Resend confirmation email', + invalidAccount: 'This account has invalid nickname and can\'t be modified', + invalidNickname: 'invalid nickname', + passwordResetTokenGenerated: 'Password reset token was generated:', + linkToResetPassword: 'You can also use this link to reset password:' }, statuses: { statuses: 'Statuses', diff --git a/src/store/modules/reports.js b/src/store/modules/reports.js index 3a836a2f..6bc98993 100644 --- a/src/store/modules/reports.js +++ b/src/store/modules/reports.js @@ -61,9 +61,8 @@ const reports = { const optimisticNote = { user: { avatar: rootState.user.avatar, - display_name: rootState.user.name, - url: `${rootState.user.authHost}/${rootState.user.name}`, - acct: rootState.user.name + nickname: rootState.user.name, + id: rootState.user.id }, content: content, created_at: new Date().getTime() diff --git a/src/store/modules/users.js b/src/store/modules/users.js index e0645784..90b37e56 100644 --- a/src/store/modules/users.js +++ b/src/store/modules/users.js @@ -123,6 +123,10 @@ const users = { dispatch('ApplyChanges', { updatedUsers, callApiFn, userId: _userId, statusId: _statusId }) }, + ClearUsersState({ commit }) { + commit('SET_SEARCH_QUERY', '') + commit('SET_USERS_FILTERS', { local: false, external: false, active: false, deactivated: false }) + }, async ClearFilters({ commit, dispatch, state }) { commit('CLEAR_USERS_FILTERS') dispatch('SearchUsers', { query: state.searchQuery, page: 1 }) diff --git a/src/views/reports/components/NoteCard.vue b/src/views/reports/components/NoteCard.vue index 79637f16..a2a6a427 100644 --- a/src/views/reports/components/NoteCard.vue +++ b/src/views/reports/components/NoteCard.vue @@ -2,25 +2,14 @@
-
-
- -

{{ note.user.display_name }}

-
- - @{{ note.user.display_name }} - +
+ + {{ note.user.nickname }}
- - - {{ $t('reports.deleteNote') }} - - + + {{ $t('reports.deleteNote') }} +
@@ -47,11 +36,29 @@ export default { } }, methods: { + handleNoteDeletion(noteID, reportID) { + this.$confirm('Are you sure you want to delete this note?', 'Warning', { + confirmButtonText: 'OK', + cancelButtonText: 'Cancel', + type: 'warning' + }).then(() => { + this.$store.dispatch('DeleteReportNote', { noteID, reportID }) + this.$message({ + type: 'success', + message: 'Delete completed' + }) + }).catch(() => { + this.$message({ + type: 'info', + message: 'Delete canceled' + }) + }) + }, parseTimestamp(timestamp) { return moment(timestamp).format('YYYY-MM-DD HH:mm') }, - handleNoteDeletion(noteID, reportID) { - this.$store.dispatch('DeleteReportNote', { noteID, reportID }) + propertyExists(account, property) { + return account[property] } } } @@ -76,7 +83,7 @@ export default { } .note-actor-name { margin: 0; - height: 22px; + height: 28px; } .note-avatar-img { width: 15px; @@ -96,6 +103,10 @@ export default { .note-header { display: flex; justify-content: space-between; + align-items: center; + height: 28px; + font-size: 15px; + font-weight: 500; } @media only screen and (max-width:480px) { @@ -105,14 +116,15 @@ export default { .note-header { display: flex; flex-direction: column; - height: 80px; + height: 65px; } - .note-actor-container { + .note-actor { margin-bottom: 5px; } .note-header { display: flex; flex-direction: column; + align-items: flex-start; } } diff --git a/src/views/reports/components/Report.vue b/src/views/reports/components/Report.vue index 565b3cb0..cd938c91 100644 --- a/src/views/reports/components/Report.vue +++ b/src/views/reports/components/Report.vue @@ -10,9 +10,9 @@
-

{{ $t('reports.reportOn') }} {{ report.account.display_name }}

+

{{ $t('reports.reportOn') }} {{ report.account.nickname }}

{{ $t('reports.report') }}

-
{{ $t('reports.id') }}: {{ report.id }}
+
{{ $t('reports.id') }}: {{ report.id }}
{{ capitalizeFirstLetter(report.state) }} @@ -24,26 +24,26 @@ {{ $t('reports.close') }} - +
{{ $t('reports.account') }}: - - avatar - - - {{ report.account.display_name }} - (deactivated) + avatar + + + + - ({{ $t('reports.notFound') }})
@@ -54,22 +54,26 @@
{{ $t('reports.actor') }}: - - avatar - + avatar + + + + - ({{ $t('reports.notFound') }})
- +
@@ -142,9 +146,6 @@ export default { } }, methods: { - accountExists(account, key) { - return account[key] - }, changeReportState(state, id) { this.$store.dispatch('ChangeReportState', [{ state, id }]) }, @@ -177,6 +178,12 @@ export default { parseTimestamp(timestamp) { return moment(timestamp).format('L HH:mm') }, + propertyExists(account, property, _secondProperty) { + if (_secondProperty) { + return account[property] && account[_secondProperty] + } + return account[property] + }, showStatuses(statuses = []) { return statuses.length > 0 } @@ -262,6 +269,10 @@ export default { font-style: italic; color: gray; } + .report-account-name { + font-size: 15px; + font-weight: 500; + } .report-row-key { font-size: 14px; font-weight: 500; diff --git a/src/views/statuses/show.vue b/src/views/statuses/show.vue index 8ae05bcb..d6136129 100644 --- a/src/views/statuses/show.vue +++ b/src/views/statuses/show.vue @@ -2,13 +2,14 @@
- +
- -

{{ user.display_name }}

+ +

{{ user.nickname }}

+

({{ $t('users.invalidNickname') }})

-
@@ -24,8 +25,8 @@
- -

{{ user.display_name }}

+ +

{{ user.nickname }}

@@ -41,7 +42,10 @@
-

{{ $t('userProfile.recentStatuses') }} by {{ user.display_name }}

+

+ {{ $t('userProfile.recentStatuses') }} by {{ user.nickname }} +

+

{{ $t('userProfile.recentStatuses') }}

{{ $t('statuses.showPrivateStatuses') }} @@ -102,9 +106,6 @@ export default { this.$store.dispatch('FetchStatus', this.$route.params.id) }, methods: { - accountExists(account, key) { - return account[key] - }, closeResetPasswordDialog() { this.resetPasswordDialogOpen = false this.$store.dispatch('RemovePasswordToken') @@ -114,6 +115,9 @@ export default { }, openResetPasswordDialog() { this.resetPasswordDialogOpen = true + }, + propertyExists(account, property) { + return account[property] } } } @@ -134,6 +138,9 @@ export default { height: 40px; align-items: center; } +.invalid { + color: gray; +} .no-statuses { margin-left: 28px; color: #606266; @@ -176,6 +183,7 @@ export default { display: flex; justify-content: space-between; margin: 22px 15px 22px 20px; + padding: 0; align-items: center; h1 { display: inline; diff --git a/src/views/users/components/ModerationDropdown.vue b/src/views/users/components/ModerationDropdown.vue index f8cf5ee6..ef5e2395 100644 --- a/src/views/users/components/ModerationDropdown.vue +++ b/src/views/users/components/ModerationDropdown.vue @@ -1,10 +1,10 @@