Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into develop
This commit is contained in:
commit
edb5826072
121 changed files with 7584 additions and 1777 deletions
|
@ -163,7 +163,12 @@ const updateProfileImages = ({ credentials, avatar = null, banner = null, backgr
|
|||
body: form
|
||||
})
|
||||
.then((data) => data.json())
|
||||
.then((data) => parseUser(data))
|
||||
.then((data) => {
|
||||
if (data.error) {
|
||||
throw new Error(data.error)
|
||||
}
|
||||
return parseUser(data)
|
||||
})
|
||||
}
|
||||
|
||||
const updateProfile = ({ credentials, params }) => {
|
||||
|
@ -561,7 +566,7 @@ const fetchTimeline = ({
|
|||
})
|
||||
.then((data) => data.json())
|
||||
.then((data) => {
|
||||
if (!data.error) {
|
||||
if (!data.errors) {
|
||||
return { data: data.map(isNotifications ? parseNotification : parseStatus), pagination }
|
||||
} else {
|
||||
data.status = status
|
||||
|
|
|
@ -21,7 +21,7 @@ const clear = (storage) => {
|
|||
failedMessageIds.push(message.id)
|
||||
} else {
|
||||
delete storage.idIndex[message.id]
|
||||
delete storage.idempotencyKeyIndex[message.id]
|
||||
delete storage.idempotencyKeyIndex[message.idempotency_key]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,15 @@ import escape from 'escape-html'
|
|||
import parseLinkHeader from 'parse-link-header'
|
||||
import { isStatusNotification } from '../notification_utils/notification_utils.js'
|
||||
|
||||
/** NOTICE! **
|
||||
* Do not initialize UI-generated data here.
|
||||
* It will override existing data.
|
||||
*
|
||||
* i.e. user.pinnedStatusIds was set to [] here
|
||||
* UI code would update it with data but upon next user fetch
|
||||
* it would be reverted back to []
|
||||
*/
|
||||
|
||||
const qvitterStatusType = (status) => {
|
||||
if (status.is_post_verb) {
|
||||
return 'status'
|
||||
|
@ -173,9 +182,6 @@ export const parseUser = (data) => {
|
|||
output.locked = data.locked
|
||||
output.followers_count = data.followers_count
|
||||
output.statuses_count = data.statuses_count
|
||||
output.friendIds = []
|
||||
output.followerIds = []
|
||||
output.pinnedStatusIds = []
|
||||
|
||||
if (data.pleroma) {
|
||||
output.follow_request_count = data.pleroma.follow_request_count
|
||||
|
@ -274,7 +280,7 @@ export const parseStatus = (data) => {
|
|||
if (output.poll) {
|
||||
output.poll.options = (output.poll.options || []).map(field => ({
|
||||
...field,
|
||||
title_html: addEmojis(field.title, data.emojis)
|
||||
title_html: addEmojis(escape(field.title), data.emojis)
|
||||
}))
|
||||
}
|
||||
output.pinned = data.pinned
|
||||
|
|
61
src/services/favicon_service/favicon_service.js
Normal file
61
src/services/favicon_service/favicon_service.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { find } from 'lodash'
|
||||
|
||||
const createFaviconService = () => {
|
||||
let favimg, favcanvas, favcontext, favicon
|
||||
const faviconWidth = 128
|
||||
const faviconHeight = 128
|
||||
const badgeRadius = 32
|
||||
|
||||
const initFaviconService = () => {
|
||||
const nodes = document.getElementsByTagName('link')
|
||||
favicon = find(nodes, node => node.rel === 'icon')
|
||||
if (favicon) {
|
||||
favcanvas = document.createElement('canvas')
|
||||
favcanvas.width = faviconWidth
|
||||
favcanvas.height = faviconHeight
|
||||
favimg = new Image()
|
||||
favimg.src = favicon.href
|
||||
favcontext = favcanvas.getContext('2d')
|
||||
}
|
||||
}
|
||||
|
||||
const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0
|
||||
|
||||
const clearFaviconBadge = () => {
|
||||
if (!favimg || !favcontext || !favicon) return
|
||||
|
||||
favcontext.clearRect(0, 0, faviconWidth, faviconHeight)
|
||||
if (isImageLoaded(favimg)) {
|
||||
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
||||
}
|
||||
favicon.href = favcanvas.toDataURL('image/png')
|
||||
}
|
||||
|
||||
const drawFaviconBadge = () => {
|
||||
if (!favimg || !favcontext || !favcontext) return
|
||||
|
||||
clearFaviconBadge()
|
||||
|
||||
const style = getComputedStyle(document.body)
|
||||
const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}`
|
||||
|
||||
if (isImageLoaded(favimg)) {
|
||||
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
||||
}
|
||||
favcontext.fillStyle = badgeColor
|
||||
favcontext.beginPath()
|
||||
favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false)
|
||||
favcontext.fill()
|
||||
favicon.href = favcanvas.toDataURL('image/png')
|
||||
}
|
||||
|
||||
return {
|
||||
initFaviconService,
|
||||
clearFaviconBadge,
|
||||
drawFaviconBadge
|
||||
}
|
||||
}
|
||||
|
||||
const FaviconService = createFaviconService()
|
||||
|
||||
export default FaviconService
|
|
@ -2,7 +2,6 @@ import apiService from '../api/api.service.js'
|
|||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
||||
|
||||
const update = ({ store, notifications, older }) => {
|
||||
store.dispatch('setNotificationsError', { value: false })
|
||||
store.dispatch('addNewNotifications', { notifications, older })
|
||||
}
|
||||
|
||||
|
@ -47,11 +46,22 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => {
|
|||
|
||||
const fetchNotifications = ({ store, args, older }) => {
|
||||
return apiService.fetchTimeline(args)
|
||||
.then(({ data: notifications }) => {
|
||||
.then((response) => {
|
||||
if (response.errors) {
|
||||
throw new Error(`${response.status} ${response.statusText}`)
|
||||
}
|
||||
const notifications = response.data
|
||||
update({ store, notifications, older })
|
||||
return notifications
|
||||
}, () => store.dispatch('setNotificationsError', { value: true }))
|
||||
.catch(() => store.dispatch('setNotificationsError', { value: true }))
|
||||
})
|
||||
.catch((error) => {
|
||||
store.dispatch('pushGlobalNotice', {
|
||||
level: 'error',
|
||||
messageKey: 'notifications.error',
|
||||
messageArgs: [error.message],
|
||||
timeout: 5000
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const startFetching = ({ credentials, store }) => {
|
||||
|
|
|
@ -84,6 +84,10 @@ export const SLOT_INHERITANCE = {
|
|||
opacity: 'bg',
|
||||
priority: 1
|
||||
},
|
||||
wallpaper: {
|
||||
depends: ['bg'],
|
||||
color: (mod, bg) => brightness(-2 * mod, bg).rgb
|
||||
},
|
||||
fg: {
|
||||
depends: [],
|
||||
priority: 1
|
||||
|
|
|
@ -6,9 +6,6 @@ import { promiseInterval } from '../promise_interval/promise_interval.js'
|
|||
const update = ({ store, statuses, timeline, showImmediately, userId, pagination }) => {
|
||||
const ccTimeline = camelCase(timeline)
|
||||
|
||||
store.dispatch('setError', { value: false })
|
||||
store.dispatch('setErrorData', { value: null })
|
||||
|
||||
store.dispatch('addNewStatuses', {
|
||||
timeline: ccTimeline,
|
||||
userId,
|
||||
|
@ -52,9 +49,8 @@ const fetchAndUpdate = ({
|
|||
|
||||
return apiService.fetchTimeline(args)
|
||||
.then(response => {
|
||||
if (response.error) {
|
||||
store.dispatch('setErrorData', { value: response })
|
||||
return
|
||||
if (response.errors) {
|
||||
throw new Error(`${response.status} ${response.statusText}`)
|
||||
}
|
||||
|
||||
const { data: statuses, pagination } = response
|
||||
|
@ -63,7 +59,15 @@ const fetchAndUpdate = ({
|
|||
}
|
||||
update({ store, statuses, timeline, showImmediately, userId, pagination })
|
||||
return { statuses, pagination }
|
||||
}, () => store.dispatch('setError', { value: true }))
|
||||
})
|
||||
.catch((error) => {
|
||||
store.dispatch('pushGlobalNotice', {
|
||||
level: 'error',
|
||||
messageKey: 'timeline.error',
|
||||
messageArgs: [error.message],
|
||||
timeout: 5000
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const startFetching = ({ timeline = 'friends', credentials, store, userId = false, tag = false }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue