Improve rendering of single post

Signed-off-by: Louis Chemineau <louis@chmn.me>
pull/1696/head
Louis Chemineau 2023-03-22 18:16:40 +01:00
rodzic abed6af7f5
commit 19b3465ee1
5 zmienionych plików z 87 dodań i 53 usunięć

Wyświetl plik

@ -28,7 +28,7 @@
:item="entry"
:type="type" />
</transition-group>
<InfiniteLoading ref="infiniteLoading" @infinite="infiniteHandler">
<InfiniteLoading ref="infiniteLoading" :direction="reverseOrder ? 'top' : 'bottom'" @infinite="infiniteHandler">
<div slot="spinner">
<div class="icon-loading" />
</div>
@ -36,7 +36,7 @@
<div class="list-end" />
</div>
<div slot="no-results">
<EmptyContent v-if="timeline.length === 0" :item="emptyContentData" />
<EmptyContent v-if="timeline.length === 0 && emptyContentData.title !== ''" :item="emptyContentData" />
</div>
</InfiniteLoading>
</div>
@ -69,6 +69,10 @@ export default {
type: Boolean,
default: false,
},
reverseOrder: {
type: Boolean,
default: false,
},
},
data() {
return {
@ -114,7 +118,7 @@ export default {
title: t('social', 'No posts found for this tag'),
},
'single-post': {
title: t('social', 'No replies found'),
title: this.showParents ? '' : t('social', 'No replies found'),
},
},
}
@ -140,13 +144,22 @@ export default {
},
/**
* @return {import('../store/timeline.js').APObject[]}
* @return {import('../types/Mastodon').Status[]}
*/
timeline() {
/** @type {import('../types/Mastodon').Status[]} */
let timeline = []
if (this.showParents) {
return this.$store.getters.getParentsTimeline
timeline = this.$store.getters.getParentsTimeline
} else {
return this.$store.getters.getTimeline
timeline = this.$store.getters.getTimeline
}
if (this.reverseOrder) {
return timeline.reverse()
} else {
return timeline
}
},
},
@ -158,11 +171,21 @@ export default {
},
methods: {
async infiniteHandler($state) {
const params = {
account: this.currentUser.uid,
}
if (this.timeline.length !== 0) {
if (this.reverseOrder) {
params.min_id = Number.parseInt(this.timeline[0].id)
} else {
params.max_id = Number.parseInt(this.timeline[this.timeline.length - 1].id)
}
}
try {
const response = await this.$store.dispatch('fetchTimeline', {
account: this.currentUser.uid,
max_id: this.timeline.length > 0 ? Number.parseInt(this.timeline[this.timeline.length - 1].id) : undefined,
})
/** @type {import('../types/Mastodon').Context} */
const response = await this.$store.dispatch('fetchTimeline', params)
response.length > 0 ? $state.loaded() : $state.complete()
} catch (error) {
@ -172,10 +195,15 @@ export default {
}
},
async fetchNewStatuses() {
// No need to load new parents as they will not change.
if (this.showParents) {
return
}
try {
const response = await this.$store.dispatch('fetchTimeline', {
account: this.currentUser.uid,
min_id: this.timeline[0]?.id ?? undefined,
min_id: this.timeline[0]?.id,
})
if (response.length > 0) {

Wyświetl plik

@ -63,7 +63,7 @@
</template>
</NcButton>
<NcActions>
<NcActionButton v-if="item.account !== undefined && item.account.acct === currentAccount.acct"
<NcActionButton v-if="item.account.acct === currentAccount?.acct"
icon="icon-delete"
@click="remove()">
{{ t('social', 'Delete') }}
@ -204,7 +204,6 @@ export default {
params: {
account: this.item.account.display_name,
id: this.item.id,
localId: this.item.uri.split('/').pop(),
type: 'single-post',
},
})
@ -249,17 +248,17 @@ export default {
@import '@nextcloud/vue-richtext/dist/style.css';
.post-content {
padding: 4px 4px 4px 8px;
padding: 4px 8px;
font-size: 15px;
line-height: 1.6em;
position: relative;
border-radius: 8px;
::v-deep a.widget-default {
text-decoration: none !important;
}
&:hover {
border-radius: 8px;
background-color: var(--color-background-hover);
}

Wyświetl plik

@ -92,7 +92,7 @@ export default new Router({
],
},
{
path: '/:index(index.php/)?apps/social/@:account/:localId',
path: '/:index(index.php/)?apps/social/@:account/:id',
components: {
default: TimelineSinglePost,
},

Wyświetl plik

@ -48,7 +48,6 @@ const state = {
* @type {object} params - Timeline's parameters
* @property {string} params.account ???
* @property {string} params.id
* @property {string} params.localId
* @property {string} params.type ???
*/
params: {},
@ -74,7 +73,6 @@ const mutations = {
addToTimeline(state, data) {
if (Array.isArray(data)) {
data.forEach((post) => Vue.set(state.timeline, post.id, post))
state.parentsTimeline = {}
} else {
data.descendants.forEach((post) => Vue.set(state.timeline, post.id, post))
data.ancestors.forEach((post) => Vue.set(state.parentsTimeline, post.id, post))
@ -89,6 +87,7 @@ const mutations = {
},
resetTimeline(state) {
state.timeline = {}
state.parentsTimeline = {}
},
/**
* @param state
@ -174,12 +173,12 @@ const getters = {
return state.composerDisplayStatus
},
getTimeline(state) {
return Object.values(state.timeline).sort(function(a, b) {
return Object.values(state.timeline).sort(function (a, b) {
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
})
},
getParentsTimeline(state) {
return Object.values(state.parentsTimeline).sort(function(a, b) {
return Object.values(state.parentsTimeline).sort(function (a, b) {
return new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
})
},
@ -361,27 +360,27 @@ const actions = {
// Compute URL to get the data
let url = ''
switch (state.type) {
case 'account':
url = generateUrl(`apps/social/api/v1/accounts/${state.account}/statuses`)
break
case 'tags':
url = generateUrl(`apps/social/api/v1/timelines/tag/${state.params.tag}`)
break
case 'single-post':
url = generateUrl(`apps/social/api/v1/statuses/${state.params.localId}/context`)
break
case 'timeline':
url = generateUrl('apps/social/api/v1/timelines/public')
params.local = true
break
case 'federated':
url = generateUrl('apps/social/api/v1/timelines/public')
break
case 'notifications':
url = generateUrl('apps/social/api/v1/notifications')
break
default:
url = generateUrl(`apps/social/api/v1/timelines/${state.type}`)
case 'account':
url = generateUrl(`apps/social/api/v1/accounts/${state.account}/statuses`)
break
case 'tags':
url = generateUrl(`apps/social/api/v1/timelines/tag/${state.params.tag}`)
break
case 'single-post':
url = generateUrl(`apps/social/api/v1/statuses/${state.params.id}/context`)
break
case 'timeline':
url = generateUrl('apps/social/api/v1/timelines/public')
params.local = true
break
case 'federated':
url = generateUrl('apps/social/api/v1/timelines/public')
break
case 'notifications':
url = generateUrl('apps/social/api/v1/notifications')
break
default:
url = generateUrl(`apps/social/api/v1/timelines/${state.type}`)
}
// Get the data and add them to the timeline

Wyświetl plik

@ -2,9 +2,12 @@
<div class="social__wrapper">
<ProfileInfo v-if="accountLoaded && accountInfo" :uid="uid" />
<Composer v-show="composerDisplayStatus" />
<TimelineList v-if="timeline" :show-parents="true" :type="$route.params.type" />
<TimelineList v-if="timeline"
:show-parents="true"
:type="$route.params.type"
:reverse-order="true" />
<TimelineEntry class="main-post" :item="mainPost" type="single-post" />
<TimelineList v-if="timeline" :type="$route.params.type" />
<TimelineList v-if="timeline" class="descendants" :type="$route.params.type" />
</div>
</template>
@ -61,13 +64,8 @@ export default {
},
},
beforeMount() {
// Get data of post clicked on
if (typeof this.$route.params.id === 'undefined') {
this.mainPost = loadState('social', 'item')
} else {
this.mainPost = this.$store.getters.getPostFromTimeline(this.$route.params.id)
}
this.mainPost = this.$store.getters.getPostFromTimeline(this.$route.params.id) || loadState('social', 'item')
// Fetch information of the related account
this.$store.dispatch(this.serverData.public ? 'fetchPublicAccountInfo' : 'fetchAccountInfo', this.account).then((response) => {
@ -79,8 +77,7 @@ export default {
// Fetch single post timeline
const params = {
account: this.account,
id: window.location.href,
localId: this.mainPost.id,
id: this.$route.params.id,
type: 'single-post',
}
this.$store.dispatch('changeTimelineType', {
@ -94,9 +91,20 @@ export default {
</script>
<style scoped>
.social__wrapper {
padding-bottom: 25%;
}
.social__timeline {
max-width: 600px;
margin: 15px auto;
margin-left: 16px;
}
.main-post {
background: var(--color-background-dark);
border-radius: 8px;
padding: 16px;
box-sizing: content-box;
margin: 16px 0;
}
#app-content {