Merge pull request #1729 from nextcloud/artonge/fix/again_some_fixes

Fix blocking issues
pull/1716/head
Maxence Lange 2023-04-11 16:52:17 -01:00 zatwierdzone przez GitHub
commit 6d945ff03c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 257 dodań i 143 usunięć

Wyświetl plik

@ -378,7 +378,7 @@ export default {
this.updateStatusContent() this.updateStatusContent()
}, },
keyup(event) { keyup(event) {
if (event.shiftKey || event.ctrlKey) { if (event.ctrlKey) {
this.createPost(event) this.createPost(event)
} }
}, },

Wyświetl plik

@ -1,10 +1,24 @@
<template> <template>
<li :class="['timeline-entry', hasHeader ? 'with-header' : '']"> <component :is="element" class="timeline-entry" :class="{ 'notification': isNotification, 'with-header': hasHeader }">
<div v-if="isNotification" class="notification"> <div v-if="isNotification" class="notification__header">
<Bell :size="22" /> <span class="notification__summary">
<span class="notification-action"> <img :src="notification.account.avatar">
<Heart v-if="notification.type === 'favourite'" :size="16" />
<Repeat v-if="notification.type === 'reblog'" :size="16" />
{{ actionSummary }} {{ actionSummary }}
</span> </span>
<span class="notification__details">
<router-link :to="{ name: 'single-post', params: {
account: item.account.display_name,
id: notification.status.id,
type: 'single-post',
} }"
:data-timestamp="notification.created_at"
class="post-timestamp live-relative-timestamp"
:title="notificationFormattedDate">
{{ notificationRelativeTimestamp }}
</router-link>
</span>
</div> </div>
<template v-else-if="isBoost"> <template v-else-if="isBoost">
<div class="container-icon-boost boost"> <div class="container-icon-boost boost">
@ -24,18 +38,22 @@
:item="item.account" /> :item="item.account" />
<template v-else> <template v-else>
<div class="wrapper"> <div class="wrapper">
<TimelineAvatar class="entry__avatar" :item="entryContent" /> <TimelineAvatar v-if="!isNotification" class="entry__avatar" :item="entryContent" />
<TimelinePost class="entry__content" <TimelinePost class="entry__content"
:item="entryContent" :item="entryContent"
:type="type" /> :type="type" />
</div> </div>
</template> </template>
</li> </component>
</template> </template>
<script> <script>
import Bell from 'vue-material-design-icons/Bell.vue' import Bell from 'vue-material-design-icons/Bell.vue'
import Repeat from 'vue-material-design-icons/Repeat.vue'
import Reply from 'vue-material-design-icons/Reply.vue'
import Heart from 'vue-material-design-icons/Heart.vue'
import { translate } from '@nextcloud/l10n' import { translate } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'
import TimelinePost from './TimelinePost.vue' import TimelinePost from './TimelinePost.vue'
import TimelineAvatar from './TimelineAvatar.vue' import TimelineAvatar from './TimelineAvatar.vue'
import UserEntry from './UserEntry.vue' import UserEntry from './UserEntry.vue'
@ -48,6 +66,9 @@ export default {
TimelineAvatar, TimelineAvatar,
UserEntry, UserEntry,
Bell, Bell,
Repeat,
Reply,
Heart,
}, },
props: { props: {
/** @type {import('vue').PropType<import('../types/Mastodon.js').Status|import('../types/Mastodon.js').Notification>} */ /** @type {import('vue').PropType<import('../types/Mastodon.js').Status|import('../types/Mastodon.js').Notification>} */
@ -59,6 +80,10 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
element: {
type: String,
default: 'li',
},
}, },
computed: { computed: {
/** /**
@ -77,6 +102,14 @@ export default {
isNotification() { isNotification() {
return this.item.type !== undefined return this.item.type !== undefined
}, },
/** @return {string} */
notificationFormattedDate() {
return moment(this.notification.created_at).format('LLL')
},
/** @return {string} */
notificationRelativeTimestamp() {
return moment(this.notification.created_at).fromNow()
},
/** @return {boolean} */ /** @return {boolean} */
isBoost() { isBoost() {
return this.status.reblog !== null return this.status.reblog !== null
@ -137,21 +170,61 @@ export default {
} }
.notification { .notification {
display: flex; border-bottom: 1px solid var(--color-border);
padding-left: 2rem;
gap: 0.2rem;
margin-top: 1rem;
&-action { &__header {
display: flex;
gap: 0.2rem;
margin-top: 1rem;
}
&__summary {
flex-grow: 1; flex-grow: 1;
display: inline-block; display: inline-block;
grid-row: 1; grid-row: 1;
grid-column: 2; grid-column: 2;
color: var(--color-text-lighter); color: var(--color-text-lighter);
position: relative;
margin-bottom: 8px;
img {
width: 32px;
border-radius: 50%;
overflow: hidden;
margin-right: 3px;
vertical-align: middle;
margin-top: -1px;
margin-right: 8px;
}
.material-design-icon {
position: absolute;
top: 16px;
left: 20px;
padding: 2px;
background: var(--color-main-background);
border-radius: 50%;
border: 1px solid var(--color-background-dark);
}
} }
.bell-icon { &__details a {
opacity: .5; color: var(--color-text-lighter);
&:hover {
text-decoration: underline;
}
}
:deep(.post-header) {
.post-visibility {
display: none;
}
.post-timestamp {
display: none;
}
} }
} }

Wyświetl plik

@ -14,16 +14,16 @@
</span> </span>
</router-link> </router-link>
</div> </div>
<VisibilityIcon v-if="visibility"
:title="visibility.text"
class="post-visibility"
:visibility="visibility.id" />
<a :data-timestamp="timestamp" <a :data-timestamp="timestamp"
class="post-timestamp live-relative-timestamp" class="post-timestamp live-relative-timestamp"
:title="formattedDate" :title="formattedDate"
@click="getSinglePostTimeline"> @click="getSinglePostTimeline">
{{ relativeTimestamp }} {{ relativeTimestamp }}
</a> </a>
<VisibilityIcon v-if="visibility"
:title="visibility.text"
class="post-visibility"
:visibility="visibility.id" />
</div> </div>
<div v-if="item.content" class="post-message"> <div v-if="item.content" class="post-message">
<MessageContent :item="item" /> <MessageContent :item="item" />
@ -33,7 +33,7 @@
<PostAttachment v-if="hasAttachments" :attachments="item.media_attachments || []" /> <PostAttachment v-if="hasAttachments" :attachments="item.media_attachments || []" />
<div v-if="$route && $route.params.type !== 'notifications' && !serverData.public" class="post-actions"> <div v-if="$route && $route.params.type !== 'notifications' && !serverData.public" class="post-actions">
<NcButton :title="t('social', 'Reply')" <NcButton :title="t('social', 'Reply')"
type="tertiary-no-background" type="tertiary"
@click="reply"> @click="reply">
<template #icon> <template #icon>
<Reply :size="20" /> <Reply :size="20" />
@ -46,7 +46,7 @@
</NcButton> </NcButton>
<NcButton v-if="item.visibility === 'public' || item.visibility === 'unlisted'" <NcButton v-if="item.visibility === 'public' || item.visibility === 'unlisted'"
:title="t('social', 'Boost')" :title="t('social', 'Boost')"
type="tertiary-no-background" type="tertiary"
@click="boost"> @click="boost">
<template #icon> <template #icon>
<Repeat :size="20" :fill-color="isBoosted ? 'var(--color-primary)' : 'var(--color-main-text)'" /> <Repeat :size="20" :fill-color="isBoosted ? 'var(--color-primary)' : 'var(--color-main-text)'" />
@ -59,7 +59,7 @@
</NcButton> </NcButton>
<NcButton v-if="!isLiked" <NcButton v-if="!isLiked"
:title="t('social', 'Like')" :title="t('social', 'Like')"
type="tertiary-no-background" type="tertiary"
@click="like"> @click="like">
<template #icon> <template #icon>
<HeartOutline :size="20" /> <HeartOutline :size="20" />
@ -72,7 +72,7 @@
</NcButton> </NcButton>
<NcButton v-if="isLiked" <NcButton v-if="isLiked"
:title="t('social', 'Undo Like')" :title="t('social', 'Undo Like')"
type="tertiary-no-background" type="tertiary"
@click="like"> @click="like">
<template #icon> <template #icon>
<Heart :size="20" :fill-color="'var(--color-error)'" /> <Heart :size="20" :fill-color="'var(--color-error)'" />
@ -208,24 +208,18 @@ export default {
getSinglePostTimeline(e) { getSinglePostTimeline(e) {
// Display internal or external post // Display internal or external post
if (!this.isLocal) { if (!this.isLocal) {
// TODO - fix logger.warn("Don't know what to do with posts of type " + this.type, { post: this.item })
if (this.type === 'Note') { return
window.open(this.item.id)
} else if (this.type === 'Announce') {
window.open(this.item.object)
} else {
logger.warn("Don't know what to do with posts of type " + this.type, { post: this.item })
}
} else {
this.$router.push({
name: 'single-post',
params: {
account: this.item.account.display_name,
id: this.item.id,
type: 'single-post',
},
})
} }
this.$router.push({
name: 'single-post',
params: {
account: this.item.account.display_name,
id: this.item.id,
type: 'single-post',
},
})
}, },
userDisplayName(actorInfo) { userDisplayName(actorInfo) {
return actorInfo.name !== '' ? actorInfo.name : actorInfo.preferredUsername return actorInfo.name !== '' ? actorInfo.name : actorInfo.preferredUsername
@ -236,7 +230,7 @@ export default {
}, },
boost() { boost() {
const params = { const params = {
post: this.item, status: this.item,
parentAnnounce: this.reblog, parentAnnounce: this.reblog,
} }
if (this.isBoosted) { if (this.isBoosted) {
@ -250,7 +244,7 @@ export default {
}, },
like() { like() {
const params = { const params = {
post: this.item, status: this.item,
parentAnnounce: this.reblog, parentAnnounce: this.reblog,
} }
if (this.isLiked) { if (this.isLiked) {
@ -330,6 +324,11 @@ export default {
margin-left: -13px; margin-left: -13px;
height: 44px; height: 44px;
display: flex; display: flex;
margin: 4px;
.button-vue:hover {
background: var(--color-background-dark);
}
.post-actions-more { .post-actions-more {
position: relative; position: relative;

Wyświetl plik

@ -33,13 +33,17 @@ import logger from '../services/logger.js'
const state = { const state = {
/** /**
* @type {Object<string, import('../types/Mastodon.js').Status>} timeline - The posts' collection * @type {Object<string, import('../types/Mastodon.js').Status>} List of locally known statuses
*/ */
timeline: {}, statuses: {},
/** /**
* @type {Object<string, import('../types/Mastodon.js').Status>} timeline - The parents posts' collection * @type {string[]} timeline - The statuses' collection
*/ */
parentsTimeline: {}, timeline: [],
/**
* @type {string[]} parentsTimeline - The parents statuses' collection
*/
parentsTimeline: [],
/** /**
* @type {string} type - Timeline's type: 'home', 'single-post',... * @type {string} type - Timeline's type: 'home', 'single-post',...
*/ */
@ -49,6 +53,7 @@ const state = {
* @property {string} params.account ??? * @property {string} params.account ???
* @property {string} params.id * @property {string} params.id
* @property {string} params.type ??? * @property {string} params.type ???
* @property {string?} params.singlePost ???
*/ */
params: {}, params: {},
/** /**
@ -66,28 +71,63 @@ const state = {
/** @type {import('vuex').MutationTree<state>} */ /** @type {import('vuex').MutationTree<state>} */
const mutations = { const mutations = {
/**
* @param state
* @param {import ('../types/Mastodon.js').Status} status
*/
addToStatuses(state, status) {
Vue.set(state.statuses, status.id, status)
},
/** /**
* @param state * @param state
* @param {import ('../types/Mastodon.js').Status[]|import('../types/Mastodon.js').Context} data * @param {import ('../types/Mastodon.js').Status[]|import('../types/Mastodon.js').Context} data
*/ */
addToTimeline(state, data) { addToTimeline(state, data) {
if (Array.isArray(data)) { if (Array.isArray(data)) {
data.forEach((post) => Vue.set(state.timeline, post.id, post)) data.forEach(status => Vue.set(state.statuses, status.id, status))
data
.filter(status => state.timeline.indexOf(status.id) === -1)
.forEach(status => state.timeline.push(status.id))
} else { } else {
data.descendants.forEach((post) => Vue.set(state.timeline, post.id, post)) data.descendants.forEach(status => Vue.set(state.statuses, status.id, status))
data.ancestors.forEach((post) => Vue.set(state.parentsTimeline, post.id, post)) data.ancestors.forEach(status => Vue.set(state.statuses, status.id, status))
data.descendants
.filter(status => state.timeline.indexOf(status.id) === -1)
.forEach(status => state.timeline.push(status.id))
data.ancestors
.filter(status => state.parentsTimeline.indexOf(status.id) === -1)
.forEach(status => state.parentsTimeline.push(status.id))
} }
}, },
/** /**
* @param state * @param state
* @param {import('../types/Mastodon.js').Status} post * @param {import ('../types/Mastodon.js').Status[]} data
*/ */
removePost(state, post) { updateInTimelines(state, data) {
Vue.delete(state.timeline, post.id) data.forEach((status) => {
if (state.statuses[status.id] !== undefined) {
Vue.set(state.statuses, status.id, status)
}
})
},
/**
* @param state
* @param {import('../types/Mastodon.js').Status} status
*/
removeStatusf(state, status) {
const timelineIndex = state.timeline.indexOf(status.id)
if (timelineIndex !== -1) {
state.timeline.splice(timelineIndex, 1)
}
const parentsTimelineIndex = state.parentsTimeline.indexOf(status.id)
if (timelineIndex !== -1) {
state.parentsTimeline.splice(parentsTimelineIndex, 1)
}
}, },
resetTimeline(state) { resetTimeline(state) {
state.timeline = {} state.timeline = []
state.parentsTimeline = {} state.parentsTimeline = []
}, },
/** /**
* @param state * @param state
@ -116,53 +156,41 @@ const mutations = {
/** /**
* @param state * @param state
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
likePost(state, { post }) { likeStatus(state, { status }) {
if (state.timeline[post.id] !== undefined) { if (state.statuses[status.id] !== undefined) {
Vue.set(state.timeline[post.id], 'favourited', true) Vue.set(state.statuses[status.id], 'favourited', true)
}
if (post.reblog !== null && state.timeline[post.reblog.id] !== undefined) {
Vue.set(state.timeline[post.reblog.id], 'favourited', true)
} }
}, },
/** /**
* @param state * @param state
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
unlikePost(state, { post }) { unlikeStatus(state, { status }) {
if (state.timeline[post.id] !== undefined) { if (state.statuses[status.id] !== undefined) {
Vue.set(state.timeline[post.id], 'favourited', false) Vue.set(state.statuses[status.id], 'favourited', false)
}
if (post.reblog !== null && state.timeline[post.reblog.id] !== undefined) {
Vue.set(state.timeline[post.reblog.id], 'favourited', false)
} }
}, },
/** /**
* @param state * @param state
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
boostPost(state, { post }) { boostStatus(state, { status }) {
if (state.timeline[post.id] !== undefined) { if (state.statuses[status.id] !== undefined) {
Vue.set(state.timeline[post.id], 'reblogged', true) Vue.set(state.statuses[status.id], 'reblogged', true)
}
if (post.reblog !== null && state.timeline[post.reblog.id] !== undefined) {
Vue.set(state.timeline[post.reblog.id], 'reblogged', true)
} }
}, },
/** /**
* @param state * @param state
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
unboostPost(state, { post }) { unboostStatus(state, { status }) {
if (state.timeline[post.id] !== undefined) { if (state.statuses[status.id] !== undefined) {
Vue.set(state.timeline[post.id], 'reblogged', false) Vue.set(state.statuses[status.id], 'reblogged', false)
}
if (post.reblog !== null && state.timeline[post.reblog.id] !== undefined) {
Vue.set(state.timeline[post.reblog.id], 'reblogged', false)
} }
}, },
} }
@ -173,23 +201,24 @@ const getters = {
return state.composerDisplayStatus return state.composerDisplayStatus
}, },
getTimeline(state) { getTimeline(state) {
return Object.values(state.timeline).sort(function(a, b) { return state.timeline
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime() .map(statusId => state.statuses[statusId])
}) .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())
}, },
getParentsTimeline(state) { getParentsTimeline(state) {
return Object.values(state.parentsTimeline).sort(function(a, b) { return state.parentsTimeline
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime() .map(statusId => state.statuses[statusId])
}) .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())
},
getSinglePost(state) {
return state.statuses[state.params.singlePost]
}, },
getPostFromTimeline(state) { getPostFromTimeline(state) {
return (postId) => { return (/** @type {string} */ statusId) => {
if (state.timeline[postId] !== undefined) { if (state.statuses[statusId] !== undefined) {
return state.timeline[postId] return state.statuses[statusId]
} else if (state.parentsTimeline[postId] !== undefined) {
return state.parentsTimeline[postId]
} else { } else {
logger.warn('Could not find post in timeline', { postId }) logger.warn('Could not find status in timeline', { statusId })
} }
} }
}, },
@ -234,108 +263,108 @@ const actions = {
}, },
/** /**
* @param context * @param context
* @param {import('../types/Mastodon.js').Status} post * @param {import('../types/Mastodon.js').Status} status
*/ */
async post(context, post) { async post(context, status) {
try { try {
const { data } = await axios.post(generateUrl('apps/social/api/v1/statuses'), post) const { data } = await axios.post(generateUrl('apps/social/api/v1/statuses'), status)
logger.info('Post created', data.id) logger.info('Post created', data.id)
} catch (error) { } catch (error) {
showError('Failed to create a post') showError('Failed to create a status')
logger.error('Failed to create a post', { error }) logger.error('Failed to create a status', { error })
} }
}, },
/** /**
* @param context * @param context
* @param {import('../types/Mastodon.js').Status} post * @param {import('../types/Mastodon.js').Status} status
*/ */
async postDelete(context, post) { async postDelete(context, status) {
try { try {
context.commit('removePost', post) context.commit('removeStatusf', status)
const response = await axios.delete(generateUrl(`apps/social/api/v1/post?id=${post.uri}`)) const response = await axios.delete(generateUrl(`apps/social/api/v1/post?id=${status.uri}`))
logger.info('Post deleted with token ' + response.data.result.token) logger.info('Post deleted with token ' + response.data.result.token)
} catch (error) { } catch (error) {
context.commit('addToTimeline', [post]) context.commit('updateInTimelines', [status])
showError('Failed to delete the post') showError('Failed to delete the status')
logger.error('Failed to delete the post', { error }) logger.error('Failed to delete the status', { error })
} }
}, },
/** /**
* @param context * @param context
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
async postLike(context, { post }) { async postLike(context, { status }) {
try { try {
context.commit('likePost', { post }) context.commit('likeStatus', { status })
const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${post.id}/favourite`)) const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${status.id}/favourite`))
logger.info('Post liked') logger.info('Post liked')
context.commit('addToTimeline', [response.data]) context.commit('updateInTimelines', [response.data])
return response return response
} catch (error) { } catch (error) {
context.commit('unlikePost', { post }) context.commit('unlikeStatus', { status })
showError('Failed to like post') showError('Failed to like status')
logger.error('Failed to like post', { error }) logger.error('Failed to like status', { error })
} }
}, },
/** /**
* @param context * @param context
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
async postUnlike(context, { post }) { async postUnlike(context, { status }) {
try { try {
// Remove post from list if we are in the 'liked' timeline // Remove status from list if we are in the 'liked' timeline
if (state.type === 'liked') { if (state.type === 'liked') {
context.commit('removePost', post) context.commit('removeStatusf', status)
} }
context.commit('unlikePost', { post }) context.commit('unlikeStatus', { status })
const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${post.id}/unfavourite`)) const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${status.id}/unfavourite`))
logger.info('Post unliked') logger.info('Post unliked')
context.commit('addToTimeline', [response.data]) context.commit('updateInTimelines', [response.data])
return response return response
} catch (error) { } catch (error) {
// Readd post from list if we are in the 'liked' timeline // Readd status from list if we are in the 'liked' timeline
if (state.type === 'liked') { if (state.type === 'liked') {
context.commit('addToTimeline', [post]) context.commit('addToTimeline', [status])
} }
context.commit('likePost', { post }) context.commit('likeStatus', { status })
showError('Failed to unlike post') showError('Failed to unlike status')
logger.error('Failed to unlike post', { error }) logger.error('Failed to unlike status', { error })
} }
}, },
/** /**
* @param context * @param context
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
async postBoost(context, { post }) { async postBoost(context, { status }) {
try { try {
context.commit('boostPost', { post }) context.commit('boostStatus', { status })
const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${post.id}/reblog`)) const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${status.id}/reblog`))
logger.info('Post boosted') logger.info('Post boosted')
context.commit('addToTimeline', [response.data]) context.commit('updateInTimelines', [response.data])
return response return response
} catch (error) { } catch (error) {
context.commit('unboostPost', { post }) context.commit('unboostStatus', { status })
showError('Failed to create a boost post') showError('Failed to create a boost status')
logger.error('Failed to create a boost post', { error }) logger.error('Failed to create a boost status', { error })
} }
}, },
/** /**
* @param context * @param context
* @param {object} root0 * @param {object} root0
* @param {import('../types/Mastodon.js').Status} root0.post * @param {import('../types/Mastodon.js').Status} root0.status
*/ */
async postUnBoost(context, { post }) { async postUnBoost(context, { status }) {
try { try {
context.commit('unboostPost', { post }) context.commit('unboostStatus', { status })
const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${post.id}/unreblog`)) const response = await axios.post(generateUrl(`apps/social/api/v1/statuses/${status.id}/unreblog`))
logger.info('Boost deleted') logger.info('Boost deleted')
context.commit('addToTimeline', [response.data]) context.commit('updateInTimelines', [response.data])
return response return response
} catch (error) { } catch (error) {
context.commit('boostPost', { post }) context.commit('boostStatus', { status })
showError('Failed to delete the boost') showError('Failed to delete the boost')
logger.error('Failed to delete the boost', { error }) logger.error('Failed to delete the boost', { error })
} }

Wyświetl plik

@ -25,10 +25,17 @@
</div> </div>
</div> </div>
</transition> </transition>
<Composer v-if="type !== 'notifications' && type !== 'single-post'" :default-visibility="type === 'direct' ? 'direct' : undefined" /> <Composer v-if="type !== 'notifications' && type !== 'single-post'" :default-visibility="type === 'direct' ? 'direct' : undefined" />
<h2 v-if="type === 'tags'"> <h2 v-if="type === 'tags'">
#{{ $route.params.tag }} #{{ $route.params.tag }}
</h2> </h2>
<h2 v-if="type === 'notifications'">
{{ t('social', 'Notifications') }}
</h2>
<TimelineList :type="type" /> <TimelineList :type="type" />
</div> </div>
</template> </template>

Wyświetl plik

@ -7,8 +7,9 @@
:reverse-order="true" /> :reverse-order="true" />
<TimelineEntry ref="mainPost" <TimelineEntry ref="mainPost"
class="main-post" class="main-post"
:item="mainPost" :item="singlePost"
type="single-post" /> type="single-post"
element="div" />
<TimelineList v-if="timeline" class="descendants" :type="$route.params.type" /> <TimelineList v-if="timeline" class="descendants" :type="$route.params.type" />
</div> </div>
</template> </template>
@ -36,11 +37,14 @@ export default {
], ],
data() { data() {
return { return {
mainPost: {},
uid: this.$route.params.account, uid: this.$route.params.account,
} }
}, },
computed: { computed: {
/** @return {Status?} */
singlePost() {
return this.$store.getters.getSinglePost
},
/** /**
* @description Tells whether Composer shall be displayed or not * @description Tells whether Composer shall be displayed or not
* @return {boolean} * @return {boolean}
@ -79,15 +83,17 @@ export default {
}, },
}, },
async beforeMount() { async beforeMount() {
this.mainPost = this.$store.getters.getPostFromTimeline(this.$route.params.id) || loadState('social', 'item') const singlePost = this.$store.getters.getPostFromTimeline(this.$route.params.id) || loadState('social', 'item')
// Fetch single post timeline // Fetch single post timeline
this.$store.commit('addToStatuses', singlePost)
this.$store.dispatch('changeTimelineType', { this.$store.dispatch('changeTimelineType', {
type: 'single-post', type: 'single-post',
params: { params: {
account: this.account, account: this.account,
id: this.$route.params.id, id: this.$route.params.id,
type: 'single-post', type: 'single-post',
singlePost: this.$route.params.id || loadState('social', 'item').id,
}, },
}) })