Move previews from conversation to status, put the reply preview arrow back on timeline statuses, add a spinner when the preview is still loading.

このコミットが含まれているのは:
shpuld 2017-11-13 16:33:54 +02:00
コミット ab1d1b3dd0
4個のファイルの変更84行の追加60行の削除

ファイルの表示

@ -1,4 +1,4 @@
import { reduce, find, filter, sortBy } from 'lodash'
import { reduce, filter, sortBy } from 'lodash'
import { statusType } from '../../modules/statuses.js'
import Status from '../status/status.vue'
@ -10,12 +10,7 @@ const sortAndFilterConversation = (conversation) => {
const conversation = {
data () {
return {
highlight: null,
preview: {
x: 0,
y: 0,
status: null
}
highlight: null
}
},
props: [
@ -86,15 +81,6 @@ const conversation = {
},
setHighlight (id) {
this.highlight = Number(id)
},
setPreview (id, x, y) {
if (id) {
this.preview.x = x
this.preview.y = y
this.preview.status = find(this.conversation, { id: id })
} else {
this.preview.status = null
}
}
}
}

ファイルの表示

@ -8,48 +8,10 @@
</div>
<div class="panel-body">
<div class="timeline">
<status v-for="status in conversation" @goto="setHighlight" :key="status.id" @preview="setPreview" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight" :replies="getReplies(status.id)"></status>
</div>
</div>
<div class="status-preview base00-background base03-border" :style="{ left: preview.x + 'px', top: preview.y + 'px'}" v-if="preview.status">
<img class="avatar" :src="preview.status.user.profile_image_url_original">
<div class="text">
<h4>
{{ preview.status.user.name }}
<small><a>{{ preview.status.user.screen_name}}</a></small>
</h4>
<div @click.prevent="linkClicked" class="status-content" v-html="preview.status.statusnet_html"></div>
<status v-for="status in conversation" @goto="setHighlight" :key="status.id" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight" :replies="getReplies(status.id)"></status>
</div>
</div>
</div>
</template>
<script src="./conversation.js"></script>
<style lang="scss">
.status-preview {
position: absolute;
max-width: 35em;
padding: 0.5em;
display: flex;
border-color: inherit;
border-style: solid;
border-width: 1px;
border-radius: 4px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
.avatar {
width: 32px;
height: 32px;
border-radius: 50%;
}
.text {
h4 {
margin-bottom: 0.4em;
small {
font-weight: lighter;
}
}
padding: 0 0.5em 0.5em 0.5em;
}
}
</style>

ファイルの表示

@ -4,7 +4,7 @@ import RetweetButton from '../retweet_button/retweet_button.vue'
import DeleteButton from '../delete_button/delete_button.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCardContent from '../user_card_content/user_card_content.vue'
import { filter } from 'lodash'
import { filter, find } from 'lodash'
const Status = {
props: [
@ -20,7 +20,9 @@ const Status = {
replying: false,
expanded: false,
unmuted: false,
userExpanded: false
userExpanded: false,
preview: null,
showPreview: false
}),
computed: {
muteWords () {
@ -90,7 +92,9 @@ const Status = {
},
gotoOriginal (id) {
// only handled by conversation, not status_or_conversation
this.$emit('goto', id)
if (this.expanded) {
this.$emit('goto', id)
}
},
toggleExpanded () {
this.$emit('toggleExpanded')
@ -102,13 +106,34 @@ const Status = {
this.userExpanded = !this.userExpanded
},
replyEnter (id, event) {
this.showPreview = true
const targetId = Number(id)
const statuses = this.$store.state.statuses.allStatuses
if (!this.preview) {
// if we have the status somewhere already
this.preview = find(statuses, { 'id': targetId })
// or if we have to fetch it
if (!this.preview) {
this.$store.state.api.backendInteractor.fetchStatus({id}).then((status) => {
this.preview = status
})
}
} else if (this.preview.id !== targetId) {
this.preview = find(statuses, { 'id': targetId })
}
/*
if (this.$store.state.config.hoverPreview) {
let rect = event.target.getBoundingClientRect()
this.$emit('preview', Number(id), rect.left + 20, rect.top + 20 + window.pageYOffset)
}
*/
},
replyLeave () {
this.showPreview = false
/*
this.$emit('preview', 0, 0, 0)
*/
}
},
watch: {

ファイルの表示

@ -54,7 +54,7 @@
{{status.in_reply_to_screen_name}}
</router-link>
</small>
<template v-if="isReply && !expandable">
<template v-if="isReply">
<small>
<a href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)"><i class="icon-reply" @mouseenter="replyEnter(status.in_reply_to_status_id, $event)" @mouseout="replyLeave()"></i></a>
</small>
@ -83,6 +83,20 @@
</div>
</div>
<div class="status-preview base00-background base03-border" v-if="showPreview && preview">
<img class="avatar" :src="preview.user.profile_image_url_original">
<div class="text">
<h4>
{{ preview.user.name }}
<small><a>{{ preview.user.screen_name}}</a></small>
</h4>
<div @click.prevent="linkClicked" class="status-content" v-html="preview.statusnet_html"></div>
</div>
</div>
<div class="status-preview status-preview-loading base00-background base03-border" v-else-if="showPreview">
<i class="fa icon-spin4 animate-spin"></i>
</div>
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
<div v-if='status.attachments' class='attachments'>
@ -120,7 +134,44 @@
status-text-container {
display: block;
}
}
.status-preview {
position: absolute;
max-width: 34em;
padding: 0.5em;
display: flex;
border-color: inherit;
border-style: solid;
border-width: 1px;
border-radius: 4px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
margin-top: 0.5em;
margin-left: 1em;
.avatar {
flex-shrink: 0;
width: 32px;
height: 32px;
border-radius: 50%;
}
.text {
h4 {
margin-bottom: 0.4em;
small {
font-weight: lighter;
}
}
padding: 0 0.5em 0.5em 0.5em;
}
}
.status-preview-loading {
display: block;
font-size: 2em;
min-width: 8em;
text-align: center;
}
.status-el {
hyphens: auto;