Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop

This commit is contained in:
Maksim Pechnikov 2020-01-14 22:08:24 +03:00
commit f892b26d73
9 changed files with 48 additions and 20 deletions

View File

@ -4,18 +4,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased] ## [Unreleased]
### Fixed
- Single notifications left unread when hitting read on another device/tab
## [1.1.8] - 2020-01-10
### Added ### Added
- Icons in nav panel - Icons in nav panel
- Private mode support - Private mode support
- Support for 'Move' type notifications - Support for 'Move' type notifications
- Pleroma AMOLED dark theme - Pleroma AMOLED dark theme
### Changed ### Changed
- Captcha now resets on failed registrations
- Notifications column now cleans itself up to optimize performance when tab is left open for a long time
- 403 messaging - 403 messaging
### Fixed ### Fixed
- Single notifications left unread when hitting read on another device/tab
- Registration fixed
- Deactivation of remote accounts from frontend - Deactivation of remote accounts from frontend
## [1.1.7 and earlier] - 2019-12-14 ## [1.1.7 and earlier] - 2019-12-14

View File

@ -2,10 +2,12 @@ import Notification from '../notification/notification.vue'
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js' import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
import { import {
notificationsFromStore, notificationsFromStore,
visibleNotificationsFromStore, filteredNotificationsFromStore,
unseenNotificationsFromStore unseenNotificationsFromStore
} from '../../services/notification_utils/notification_utils.js' } from '../../services/notification_utils/notification_utils.js'
const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
const Notifications = { const Notifications = {
props: { props: {
// Disables display of panel header // Disables display of panel header
@ -18,7 +20,11 @@ const Notifications = {
}, },
data () { data () {
return { return {
bottomedOut: false bottomedOut: false,
// How many seen notifications to display in the list. The more there are,
// the heavier the page becomes. This count is increased when loading
// older notifications, and cut back to default whenever hitting "Read!".
seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT
} }
}, },
computed: { computed: {
@ -34,14 +40,17 @@ const Notifications = {
unseenNotifications () { unseenNotifications () {
return unseenNotificationsFromStore(this.$store) return unseenNotificationsFromStore(this.$store)
}, },
visibleNotifications () { filteredNotifications () {
return visibleNotificationsFromStore(this.$store, this.filterMode) return filteredNotificationsFromStore(this.$store, this.filterMode)
}, },
unseenCount () { unseenCount () {
return this.unseenNotifications.length return this.unseenNotifications.length
}, },
loading () { loading () {
return this.$store.state.statuses.notifications.loading return this.$store.state.statuses.notifications.loading
},
notificationsToDisplay () {
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
} }
}, },
components: { components: {
@ -64,12 +73,21 @@ const Notifications = {
methods: { methods: {
markAsSeen () { markAsSeen () {
this.$store.dispatch('markNotificationsAsSeen') this.$store.dispatch('markNotificationsAsSeen')
this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT
}, },
fetchOlderNotifications () { fetchOlderNotifications () {
if (this.loading) { if (this.loading) {
return return
} }
const seenCount = this.filteredNotifications.length - this.unseenCount
if (this.seenToDisplayCount < seenCount) {
this.seenToDisplayCount = Math.min(this.seenToDisplayCount + 20, seenCount)
return
} else if (this.seenToDisplayCount > seenCount) {
this.seenToDisplayCount = seenCount
}
const store = this.$store const store = this.$store
const credentials = store.state.users.currentUser.credentials const credentials = store.state.users.currentUser.credentials
store.commit('setNotificationsLoading', { value: true }) store.commit('setNotificationsLoading', { value: true })
@ -82,6 +100,7 @@ const Notifications = {
if (notifs.length === 0) { if (notifs.length === 0) {
this.bottomedOut = true this.bottomedOut = true
} }
this.seenToDisplayCount += notifs.length
}) })
} }
} }

View File

@ -32,7 +32,7 @@
</div> </div>
<div class="panel-body"> <div class="panel-body">
<div <div
v-for="notification in visibleNotifications" v-for="notification in notificationsToDisplay"
:key="notification.id" :key="notification.id"
class="notification" class="notification"
:class="{&quot;unseen&quot;: !minimalMode && !notification.seen}" :class="{&quot;unseen&quot;: !minimalMode && !notification.seen}"

View File

@ -63,7 +63,8 @@ const registration = {
await this.signUp(this.user) await this.signUp(this.user)
this.$router.push({ name: 'friends' }) this.$router.push({ name: 'friends' })
} catch (error) { } catch (error) {
console.warn('Registration failed: ' + error) console.warn('Registration failed: ', error)
this.setCaptcha()
} }
} }
}, },

View File

@ -170,7 +170,7 @@
<label <label
class="form--label" class="form--label"
for="captcha-label" for="captcha-label"
>{{ $t('captcha') }}</label> >{{ $t('registration.captcha') }}</label>
<template v-if="['kocaptcha', 'native'].includes(captcha.type)"> <template v-if="['kocaptcha', 'native'].includes(captcha.type)">
<img <img

View File

@ -401,7 +401,9 @@ const users = {
let rootState = store.rootState let rootState = store.rootState
try { try {
let data = await rootState.api.backendInteractor.register({ ...userInfo }) let data = await rootState.api.backendInteractor.register(
{ params: { ...userInfo } }
)
store.commit('signUpSuccess') store.commit('signUpSuccess')
store.commit('setToken', data.access_token) store.commit('setToken', data.access_token)
store.dispatch('loginUser', data.access_token) store.dispatch('loginUser', data.access_token)

View File

@ -32,12 +32,18 @@ export class RegistrationError extends Error {
} }
if (typeof error === 'object') { if (typeof error === 'object') {
const errorContents = JSON.parse(error.error)
// keys will have the property that has the error, for example 'ap_id',
// 'email' or 'captcha', the value will be an array of its error
// like "ap_id": ["has been taken"] or "captcha": ["Invalid CAPTCHA"]
// replace ap_id with username // replace ap_id with username
if (error.ap_id) { if (errorContents.ap_id) {
error.username = error.ap_id errorContents.username = errorContents.ap_id
delete error.ap_id delete errorContents.ap_id
} }
this.message = humanizeErrors(error)
this.message = humanizeErrors(errorContents)
} else { } else {
this.message = error this.message = error
} }

View File

@ -26,7 +26,7 @@ const sortById = (a, b) => {
} }
} }
export const visibleNotificationsFromStore = (store, types) => { export const filteredNotificationsFromStore = (store, types) => {
// map is just to clone the array since sort mutates it and it causes some issues // map is just to clone the array since sort mutates it and it causes some issues
let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById) let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById)
sortedNotifications = sortBy(sortedNotifications, 'seen') sortedNotifications = sortBy(sortedNotifications, 'seen')
@ -36,4 +36,4 @@ export const visibleNotificationsFromStore = (store, types) => {
} }
export const unseenNotificationsFromStore = store => export const unseenNotificationsFromStore = store =>
filter(visibleNotificationsFromStore(store), ({ seen }) => !seen) filter(filteredNotificationsFromStore(store), ({ seen }) => !seen)

View File

@ -1,7 +1,7 @@
import * as NotificationUtils from 'src/services/notification_utils/notification_utils.js' import * as NotificationUtils from 'src/services/notification_utils/notification_utils.js'
describe('NotificationUtils', () => { describe('NotificationUtils', () => {
describe('visibleNotificationsFromStore', () => { describe('filteredNotificationsFromStore', () => {
it('should return sorted notifications with configured types', () => { it('should return sorted notifications with configured types', () => {
const store = { const store = {
state: { state: {
@ -47,7 +47,7 @@ describe('NotificationUtils', () => {
type: 'like' type: 'like'
} }
] ]
expect(NotificationUtils.visibleNotificationsFromStore(store)).to.eql(expected) expect(NotificationUtils.filteredNotificationsFromStore(store)).to.eql(expected)
}) })
}) })