diff options
Diffstat (limited to 'src/components/conversation')
| -rw-r--r-- | src/components/conversation/conversation.js | 99 | ||||
| -rw-r--r-- | src/components/conversation/conversation.vue | 50 |
2 files changed, 112 insertions, 37 deletions
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 48b8aaaa..69058bf6 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -1,9 +1,12 @@ -import { reduce, filter } from 'lodash' +import { reduce, filter, findIndex } from 'lodash' +import { set } from 'vue' import Status from '../status/status.vue' const sortById = (a, b) => { - const seqA = Number(a.id) - const seqB = Number(b.id) + const idA = a.type === 'retweet' ? a.retweeted_status.id : a.id + const idB = b.type === 'retweet' ? b.retweeted_status.id : b.id + const seqA = Number(idA) + const seqB = Number(idB) const isSeqA = !Number.isNaN(seqA) const isSeqB = !Number.isNaN(seqB) if (isSeqA && isSeqB) { @@ -13,29 +16,53 @@ const sortById = (a, b) => { } else if (!isSeqA && isSeqB) { return 1 } else { - return a.id < b.id ? -1 : 1 + return idA < idB ? -1 : 1 } } -const sortAndFilterConversation = (conversation) => { - conversation = filter(conversation, (status) => status.type !== 'retweet') +const sortAndFilterConversation = (conversation, statusoid) => { + if (statusoid.type === 'retweet') { + conversation = filter( + conversation, + (status) => (status.type === 'retweet' || status.id !== statusoid.retweeted_status.id) + ) + } else { + conversation = filter(conversation, (status) => status.type !== 'retweet') + } return conversation.filter(_ => _).sort(sortById) } const conversation = { data () { return { - highlight: null + highlight: null, + expanded: false, + converationStatusIds: [] } }, props: [ 'statusoid', - 'collapsable' + 'collapsable', + 'isPage' ], + created () { + if (this.isPage) { + this.fetchConversation() + } + }, computed: { status () { return this.statusoid }, + idsToShow () { + if (this.converationStatusIds.length > 0) { + return this.converationStatusIds + } else if (this.statusId) { + return [this.statusId] + } else { + return [] + } + }, statusId () { if (this.statusoid.retweeted_status) { return this.statusoid.retweeted_status.id @@ -48,10 +75,22 @@ const conversation = { return [] } - const conversationId = this.status.statusnet_conversation_id - const statuses = this.$store.state.statuses.allStatuses - const conversation = filter(statuses, { statusnet_conversation_id: conversationId }) - return sortAndFilterConversation(conversation) + if (!this.isExpanded) { + return [this.status] + } + + const statusesObject = this.$store.state.statuses.allStatusesObject + const conversation = this.idsToShow.reduce((acc, id) => { + acc.push(statusesObject[id]) + return acc + }, []) + + const statusIndex = findIndex(conversation, { id: this.statusId }) + if (statusIndex !== -1) { + conversation[statusIndex] = this.status + } + + return sortAndFilterConversation(conversation, this.status) }, replies () { let i = 1 @@ -69,23 +108,34 @@ const conversation = { i++ return result }, {}) + }, + isExpanded () { + return this.expanded || this.isPage } }, components: { Status }, - created () { - this.fetchConversation() - }, watch: { - '$route': 'fetchConversation' + '$route': 'fetchConversation', + expanded (value) { + if (value) { + this.fetchConversation() + } + } }, methods: { fetchConversation () { if (this.status) { - const conversationId = this.status.statusnet_conversation_id - this.$store.state.api.backendInteractor.fetchConversation({id: conversationId}) - .then((statuses) => this.$store.dispatch('addNewStatuses', { statuses })) + this.$store.state.api.backendInteractor.fetchConversation({id: this.status.id}) + .then(({ancestors, descendants}) => { + this.$store.dispatch('addNewStatuses', { statuses: ancestors }) + this.$store.dispatch('addNewStatuses', { statuses: descendants }) + set(this, 'converationStatusIds', [].concat( + ancestors.map(_ => _.id).filter(_ => _ !== this.statusId), + this.statusId, + descendants.map(_ => _.id).filter(_ => _ !== this.statusId))) + }) .then(() => this.setHighlight(this.statusId)) } else { const id = this.$route.params.id @@ -98,10 +148,19 @@ const conversation = { return this.replies[id] || [] }, focused (id) { - return id === this.statusId + return (this.isExpanded) && id === this.status.id }, setHighlight (id) { this.highlight = id + }, + getHighlight () { + return this.isExpanded ? this.highlight : null + }, + toggleExpanded () { + this.expanded = !this.expanded + if (!this.expanded) { + this.setHighlight(null) + } } } } diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 5528fef6..c39a3ed9 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -1,26 +1,42 @@ <template> - <div class="timeline panel panel-default"> - <div class="panel-heading conversation-heading"> + <div class="timeline panel-default" :class="[isExpanded ? 'panel' : 'panel-disabled']"> + <div v-if="isExpanded" class="panel-heading conversation-heading"> <span class="title"> {{ $t('timeline.conversation') }} </span> <span v-if="collapsable"> - <a href="#" @click.prevent="$emit('toggleExpanded')">{{ $t('timeline.collapse') }}</a> + <a href="#" @click.prevent="toggleExpanded">{{ $t('timeline.collapse') }}</a> </span> </div> - <div class="panel-body"> - <div class="timeline"> - <status - v-for="status in conversation" - @goto="setHighlight" :key="status.id" - :inlineExpanded="collapsable" :statusoid="status" - :expandable='false' :focused="focused(status.id)" - :inConversation='true' - :highlight="highlight" - :replies="getReplies(status.id)" - class="status-fadein"> - </status> - </div> - </div> + <status + v-for="status in conversation" + @goto="setHighlight" + @toggleExpanded="toggleExpanded" + :key="status.id" + :inlineExpanded="collapsable" + :statusoid="status" + :expandable='!expanded' + :focused="focused(status.id)" + :inConversation="isExpanded" + :highlight="getHighlight()" + :replies="getReplies(status.id)" + class="status-fadein panel-body" + /> </div> </template> <script src="./conversation.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; + +.timeline { + .panel-disabled { + .status-el { + border-left: none; + border-bottom-width: 1px; + border-bottom-style: solid; + border-color: var(--border, $fallback--border); + border-radius: 0; + } + } +} +</style> |
