Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop
This commit is contained in:
commit
954d5c05df
76 changed files with 1639 additions and 468 deletions
|
@ -138,9 +138,6 @@ const api = {
|
|||
if (!fetcher) return
|
||||
store.commit('removeFetcher', { fetcherName: 'notifications', fetcher })
|
||||
},
|
||||
fetchAndUpdateNotifications (store) {
|
||||
store.state.backendInteractor.fetchAndUpdateNotifications({ store })
|
||||
},
|
||||
|
||||
// Follow requests
|
||||
startFetchingFollowRequests (store) {
|
||||
|
|
|
@ -15,6 +15,8 @@ const defaultState = {
|
|||
|
||||
// Stuff from static/config.json
|
||||
alwaysShowSubjectInput: true,
|
||||
defaultAvatar: '/images/avi.png',
|
||||
defaultBanner: '/images/banner.png',
|
||||
background: '/static/aurora_borealis.jpg',
|
||||
collapseMessageWithSubject: false,
|
||||
disableChat: false,
|
||||
|
|
|
@ -14,7 +14,8 @@ const defaultState = {
|
|||
window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')
|
||||
)
|
||||
},
|
||||
mobileLayout: false
|
||||
mobileLayout: false,
|
||||
globalNotices: []
|
||||
}
|
||||
|
||||
const interfaceMod = {
|
||||
|
@ -58,6 +59,12 @@ const interfaceMod = {
|
|||
if (!state.settingsModalLoaded) {
|
||||
state.settingsModalLoaded = true
|
||||
}
|
||||
},
|
||||
pushGlobalNotice (state, notice) {
|
||||
state.globalNotices.push(notice)
|
||||
},
|
||||
removeGlobalNotice (state, notice) {
|
||||
state.globalNotices = state.globalNotices.filter(n => n !== notice)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
@ -81,6 +88,28 @@ const interfaceMod = {
|
|||
},
|
||||
togglePeekSettingsModal ({ commit }) {
|
||||
commit('togglePeekSettingsModal')
|
||||
},
|
||||
pushGlobalNotice (
|
||||
{ commit, dispatch },
|
||||
{
|
||||
messageKey,
|
||||
messageArgs = {},
|
||||
level = 'error',
|
||||
timeout = 0
|
||||
}) {
|
||||
const notice = {
|
||||
messageKey,
|
||||
messageArgs,
|
||||
level
|
||||
}
|
||||
if (timeout) {
|
||||
setTimeout(() => dispatch('removeGlobalNotice', notice), timeout)
|
||||
}
|
||||
commit('pushGlobalNotice', notice)
|
||||
return notice
|
||||
},
|
||||
removeGlobalNotice ({ commit }, notice) {
|
||||
commit('removeGlobalNotice', notice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ const mediaViewer = {
|
|||
setMedia ({ commit }, attachments) {
|
||||
const media = attachments.filter(attachment => {
|
||||
const type = fileTypeService.fileType(attachment.mimetype)
|
||||
return type === 'image' || type === 'video'
|
||||
return type === 'image' || type === 'video' || type === 'audio'
|
||||
})
|
||||
commit('setMedia', media)
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
omitBy
|
||||
} from 'lodash'
|
||||
import { set } from 'vue'
|
||||
import { isStatusNotification } from '../services/notification_utils/notification_utils.js'
|
||||
import { isStatusNotification, prepareNotificationObject } from '../services/notification_utils/notification_utils.js'
|
||||
import apiService from '../services/api/api.service.js'
|
||||
import { muteWordHits } from '../services/status_parser/status_parser.js'
|
||||
|
||||
|
@ -62,7 +62,8 @@ export const defaultState = () => ({
|
|||
publicAndExternal: emptyTl(),
|
||||
friends: emptyTl(),
|
||||
tag: emptyTl(),
|
||||
dms: emptyTl()
|
||||
dms: emptyTl(),
|
||||
bookmarks: emptyTl()
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -163,8 +164,7 @@ const removeStatusFromGlobalStorage = (state, status) => {
|
|||
}
|
||||
}
|
||||
|
||||
const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {},
|
||||
noIdUpdate = false, userId }) => {
|
||||
const addNewStatuses = (state, { statuses, showImmediately = false, timeline, user = {}, noIdUpdate = false, userId, pagination = {} }) => {
|
||||
// Sanity check
|
||||
if (!isArray(statuses)) {
|
||||
return false
|
||||
|
@ -173,8 +173,13 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
const allStatuses = state.allStatuses
|
||||
const timelineObject = state.timelines[timeline]
|
||||
|
||||
const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
|
||||
const minNew = statuses.length > 0 ? minBy(statuses, 'id').id : 0
|
||||
// Mismatch between API pagination and our internal minId/maxId tracking systems:
|
||||
// pagination.maxId is the oldest of the returned statuses when fetching older,
|
||||
// and pagination.minId is the newest when fetching newer. The names come directly
|
||||
// from the arguments they're supposed to be passed as for the next fetch.
|
||||
const minNew = pagination.maxId || (statuses.length > 0 ? minBy(statuses, 'id').id : 0)
|
||||
const maxNew = pagination.minId || (statuses.length > 0 ? maxBy(statuses, 'id').id : 0)
|
||||
|
||||
const newer = timeline && (maxNew > timelineObject.maxId || timelineObject.maxId === 0) && statuses.length > 0
|
||||
const older = timeline && (minNew < timelineObject.minId || timelineObject.minId === 0) && statuses.length > 0
|
||||
|
||||
|
@ -315,7 +320,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
})
|
||||
|
||||
// Keep the visible statuses sorted
|
||||
if (timeline) {
|
||||
if (timeline && !(timeline === 'bookmarks')) {
|
||||
sortTimeline(timelineObject)
|
||||
}
|
||||
}
|
||||
|
@ -344,42 +349,7 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
|
|||
state.notifications.idStore[notification.id] = notification
|
||||
|
||||
if ('Notification' in window && window.Notification.permission === 'granted') {
|
||||
const notifObj = {}
|
||||
const status = notification.status
|
||||
const title = notification.from_profile.name
|
||||
notifObj.icon = notification.from_profile.profile_image_url
|
||||
let i18nString
|
||||
switch (notification.type) {
|
||||
case 'like':
|
||||
i18nString = 'favorited_you'
|
||||
break
|
||||
case 'repeat':
|
||||
i18nString = 'repeated_you'
|
||||
break
|
||||
case 'follow':
|
||||
i18nString = 'followed_you'
|
||||
break
|
||||
case 'move':
|
||||
i18nString = 'migrated_to'
|
||||
break
|
||||
case 'follow_request':
|
||||
i18nString = 'follow_request'
|
||||
break
|
||||
}
|
||||
|
||||
if (notification.type === 'pleroma:emoji_reaction') {
|
||||
notifObj.body = rootGetters.i18n.t('notifications.reacted_with', [notification.emoji])
|
||||
} else if (i18nString) {
|
||||
notifObj.body = rootGetters.i18n.t('notifications.' + i18nString)
|
||||
} else if (isStatusNotification(notification.type)) {
|
||||
notifObj.body = notification.status.text
|
||||
}
|
||||
|
||||
// Shows first attached non-nsfw image, if any. Should add configuration for this somehow...
|
||||
if (status && status.attachments && status.attachments.length > 0 && !status.nsfw &&
|
||||
status.attachments[0].mimetype.startsWith('image/')) {
|
||||
notifObj.image = status.attachments[0].url
|
||||
}
|
||||
const notifObj = prepareNotificationObject(notification, rootGetters.i18n)
|
||||
|
||||
const reasonsToMuteNotif = (
|
||||
notification.seen ||
|
||||
|
@ -393,7 +363,7 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot
|
|||
)
|
||||
)
|
||||
if (!reasonsToMuteNotif) {
|
||||
let desktopNotification = new window.Notification(title, notifObj)
|
||||
let desktopNotification = new window.Notification(notifObj.title, notifObj)
|
||||
// Chrome is known for not closing notifications automatically
|
||||
// according to MDN, anyway.
|
||||
setTimeout(desktopNotification.close.bind(desktopNotification), 5000)
|
||||
|
@ -498,6 +468,14 @@ export const mutations = {
|
|||
newStatus.rebloggedBy.push(user)
|
||||
}
|
||||
},
|
||||
setBookmarked (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.bookmarked = value
|
||||
},
|
||||
setBookmarkedConfirm (state, { status }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.bookmarked = status.bookmarked
|
||||
},
|
||||
setDeleted (state, { status }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
newStatus.deleted = true
|
||||
|
@ -550,6 +528,11 @@ export const mutations = {
|
|||
queueFlush (state, { timeline, id }) {
|
||||
state.timelines[timeline].flushMarker = id
|
||||
},
|
||||
queueFlushAll (state) {
|
||||
Object.keys(state.timelines).forEach((timeline) => {
|
||||
state.timelines[timeline].flushMarker = state.timelines[timeline].maxId
|
||||
})
|
||||
},
|
||||
addRepeats (state, { id, rebloggedByUsers, currentUser }) {
|
||||
const newStatus = state.allStatusesObject[id]
|
||||
newStatus.rebloggedBy = rebloggedByUsers.filter(_ => _)
|
||||
|
@ -620,8 +603,8 @@ export const mutations = {
|
|||
const statuses = {
|
||||
state: defaultState(),
|
||||
actions: {
|
||||
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId }) {
|
||||
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId })
|
||||
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false, userId, pagination }) {
|
||||
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser, userId, pagination })
|
||||
},
|
||||
addNewNotifications ({ rootState, commit, dispatch, rootGetters }, { notifications, older }) {
|
||||
commit('addNewNotifications', { visibleNotificationTypes: visibleNotificationTypes(rootState), dispatch, notifications, older, rootGetters })
|
||||
|
@ -696,9 +679,26 @@ const statuses = {
|
|||
rootState.api.backendInteractor.unretweet({ id: status.id })
|
||||
.then(status => commit('setRetweetedConfirm', { status, user: rootState.users.currentUser }))
|
||||
},
|
||||
bookmark ({ rootState, commit }, status) {
|
||||
commit('setBookmarked', { status, value: true })
|
||||
rootState.api.backendInteractor.bookmarkStatus({ id: status.id })
|
||||
.then(status => {
|
||||
commit('setBookmarkedConfirm', { status })
|
||||
})
|
||||
},
|
||||
unbookmark ({ rootState, commit }, status) {
|
||||
commit('setBookmarked', { status, value: false })
|
||||
rootState.api.backendInteractor.unbookmarkStatus({ id: status.id })
|
||||
.then(status => {
|
||||
commit('setBookmarkedConfirm', { status })
|
||||
})
|
||||
},
|
||||
queueFlush ({ rootState, commit }, { timeline, id }) {
|
||||
commit('queueFlush', { timeline, id })
|
||||
},
|
||||
queueFlushAll ({ rootState, commit }) {
|
||||
commit('queueFlushAll')
|
||||
},
|
||||
markNotificationsAsSeen ({ rootState, commit }) {
|
||||
commit('markNotificationsAsSeen')
|
||||
apiService.markNotificationsAsSeen({
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||
import oauthApi from '../services/new_api/oauth.js'
|
||||
import { compact, map, each, merge, last, concat, uniq } from 'lodash'
|
||||
import { compact, map, each, mergeWith, last, concat, uniq, isArray } from 'lodash'
|
||||
import { set } from 'vue'
|
||||
import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js'
|
||||
|
||||
|
@ -10,7 +10,7 @@ export const mergeOrAdd = (arr, obj, item) => {
|
|||
const oldItem = obj[item.id]
|
||||
if (oldItem) {
|
||||
// We already have this, so only merge the new info.
|
||||
merge(oldItem, item)
|
||||
mergeWith(oldItem, item, mergeArrayLength)
|
||||
return { item: oldItem, new: false }
|
||||
} else {
|
||||
// This is a new item, prepare it
|
||||
|
@ -23,6 +23,13 @@ export const mergeOrAdd = (arr, obj, item) => {
|
|||
}
|
||||
}
|
||||
|
||||
const mergeArrayLength = (oldValue, newValue) => {
|
||||
if (isArray(oldValue) && isArray(newValue)) {
|
||||
oldValue.length = newValue.length
|
||||
return mergeWith(oldValue, newValue, mergeArrayLength)
|
||||
}
|
||||
}
|
||||
|
||||
const getNotificationPermission = () => {
|
||||
const Notification = window.Notification
|
||||
|
||||
|
@ -120,7 +127,7 @@ export const mutations = {
|
|||
},
|
||||
setCurrentUser (state, user) {
|
||||
state.lastLoginName = user.screen_name
|
||||
state.currentUser = merge(state.currentUser || {}, user)
|
||||
state.currentUser = mergeWith(state.currentUser || {}, user, mergeArrayLength)
|
||||
},
|
||||
clearCurrentUser (state) {
|
||||
state.currentUser = false
|
||||
|
@ -266,6 +273,11 @@ const users = {
|
|||
mutations,
|
||||
getters,
|
||||
actions: {
|
||||
fetchUserIfMissing (store, id) {
|
||||
if (!store.getters.findUser(id)) {
|
||||
store.dispatch('fetchUser', id)
|
||||
}
|
||||
},
|
||||
fetchUser (store, id) {
|
||||
return store.rootState.api.backendInteractor.fetchUser({ id })
|
||||
.then((user) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue