forked from AkkomaGang/akkoma-fe
Merge branch '549' into 'develop'
Prevent showing pinned statuses twice Closes #549 See merge request pleroma/pleroma-fe!812
This commit is contained in:
commit
8aa3e7d52e
6 changed files with 74 additions and 26 deletions
src
components
modules
services/entity_normalizer
test/unit/specs/components
|
@ -1,7 +1,20 @@
|
|||
import Status from '../status/status.vue'
|
||||
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
|
||||
import Conversation from '../conversation/conversation.vue'
|
||||
import { throttle } from 'lodash'
|
||||
import { throttle, keyBy } from 'lodash'
|
||||
|
||||
export const getExcludedStatusIdsByPinning = (statuses, pinnedStatusIds) => {
|
||||
const ids = []
|
||||
if (pinnedStatusIds && pinnedStatusIds.length > 0) {
|
||||
for (let status of statuses) {
|
||||
if (!pinnedStatusIds.includes(status.id)) {
|
||||
break
|
||||
}
|
||||
ids.push(status.id)
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
const Timeline = {
|
||||
props: [
|
||||
|
@ -11,7 +24,8 @@ const Timeline = {
|
|||
'userId',
|
||||
'tag',
|
||||
'embedded',
|
||||
'count'
|
||||
'count',
|
||||
'pinnedStatusIds'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
|
@ -39,6 +53,12 @@ const Timeline = {
|
|||
body: ['timeline-body'].concat(!this.embedded ? ['panel-body'] : []),
|
||||
footer: ['timeline-footer'].concat(!this.embedded ? ['panel-footer'] : [])
|
||||
}
|
||||
},
|
||||
// id map of statuses which need to be hidden in the main list due to pinning logic
|
||||
excludedStatusIdsObject () {
|
||||
const ids = getExcludedStatusIdsByPinning(this.timeline.visibleStatuses, this.pinnedStatusIds)
|
||||
// Convert id array to object
|
||||
return keyBy(ids, id => id)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -28,13 +28,25 @@
|
|||
</div>
|
||||
<div :class="classes.body">
|
||||
<div class="timeline">
|
||||
<conversation
|
||||
v-for="status in timeline.visibleStatuses"
|
||||
:key="status.id"
|
||||
class="status-fadein"
|
||||
:statusoid="status"
|
||||
:collapsable="true"
|
||||
/>
|
||||
<template v-for="statusId in pinnedStatusIds">
|
||||
<conversation
|
||||
v-if="timeline.statusesObject[statusId]"
|
||||
:key="statusId + '-pinned'"
|
||||
class="status-fadein"
|
||||
:statusoid="timeline.statusesObject[statusId]"
|
||||
:collapsable="true"
|
||||
:show-pinned="true"
|
||||
/>
|
||||
</template>
|
||||
<template v-for="status in timeline.visibleStatuses">
|
||||
<conversation
|
||||
v-if="!excludedStatusIdsObject[status.id]"
|
||||
:key="status.id"
|
||||
class="status-fadein"
|
||||
:statusoid="status"
|
||||
:collapsable="true"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="classes.footer">
|
||||
|
|
|
@ -15,25 +15,14 @@
|
|||
:render-only-focused="true"
|
||||
>
|
||||
<div :label="$t('user_card.statuses')">
|
||||
<div class="timeline">
|
||||
<template v-for="statusId in user.pinnedStatuseIds">
|
||||
<Conversation
|
||||
v-if="timeline.statusesObject[statusId]"
|
||||
:key="statusId"
|
||||
class="status-fadein"
|
||||
:statusoid="timeline.statusesObject[statusId]"
|
||||
:collapsable="true"
|
||||
:show-pinned="true"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
<Timeline
|
||||
:count="user.statuses_count"
|
||||
:embedded="true"
|
||||
:title="$t('user_profile.timeline_title')"
|
||||
:timeline="timeline"
|
||||
:timeline-name="'user'"
|
||||
timeline-name="user"
|
||||
:user-id="userId"
|
||||
:pinned-status-ids="user.pinnedStatusIds"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -167,11 +167,11 @@ export const mutations = {
|
|||
},
|
||||
setPinned (state, status) {
|
||||
const user = state.usersObject[status.user.id]
|
||||
const index = user.pinnedStatuseIds.indexOf(status.id)
|
||||
const index = user.pinnedStatusIds.indexOf(status.id)
|
||||
if (status.pinned && index === -1) {
|
||||
user.pinnedStatuseIds.push(status.id)
|
||||
user.pinnedStatusIds.push(status.id)
|
||||
} else if (!status.pinned && index !== -1) {
|
||||
user.pinnedStatuseIds.splice(index, 1)
|
||||
user.pinnedStatusIds.splice(index, 1)
|
||||
}
|
||||
},
|
||||
setUserForStatus (state, status) {
|
||||
|
|
|
@ -152,7 +152,7 @@ export const parseUser = (data) => {
|
|||
output.statuses_count = data.statuses_count
|
||||
output.friendIds = []
|
||||
output.followerIds = []
|
||||
output.pinnedStatuseIds = []
|
||||
output.pinnedStatusIds = []
|
||||
|
||||
if (data.pleroma) {
|
||||
output.follow_request_count = data.pleroma.follow_request_count
|
||||
|
|
27
test/unit/specs/components/timeline.spec.js
Normal file
27
test/unit/specs/components/timeline.spec.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
import { getExcludedStatusIdsByPinning } from 'src/components/timeline/timeline.js'
|
||||
|
||||
describe('Timeline', () => {
|
||||
describe('getExcludedStatusIdsByPinning', () => {
|
||||
const mockStatuses = (ids) => ids.map(id => ({ id }))
|
||||
|
||||
it('should return only members of both pinnedStatusIds and ids of the given statuses', () => {
|
||||
const statusIds = [1, 2, 3, 4]
|
||||
const statuses = mockStatuses(statusIds)
|
||||
const pinnedStatusIds = [1, 3, 5]
|
||||
const result = getExcludedStatusIdsByPinning(statuses, pinnedStatusIds)
|
||||
result.forEach(item => {
|
||||
expect(item).to.be.oneOf(statusIds)
|
||||
expect(item).to.be.oneOf(pinnedStatusIds)
|
||||
})
|
||||
})
|
||||
|
||||
it('should return ids of pinned statuses not posted before any unpinned status', () => {
|
||||
const pinnedStatusIdSet1 = ['PINNED1', 'PINNED2']
|
||||
const pinnedStatusIdSet2 = ['PINNED3', 'PINNED4']
|
||||
const pinnedStatusIds = [...pinnedStatusIdSet1, ...pinnedStatusIdSet2]
|
||||
const statusIds = [...pinnedStatusIdSet1, 'UNPINNED1', ...pinnedStatusIdSet2]
|
||||
const statuses = mockStatuses(statusIds)
|
||||
expect(getExcludedStatusIdsByPinning(statuses, pinnedStatusIds)).to.eql(pinnedStatusIdSet1)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue