Merge pull request #206 from dollars0427/toot-menu

Fix: Allow user view toot detail at sidebar
This commit is contained in:
AkiraFukushima 2018-04-12 20:20:36 +09:00 committed by GitHub
commit 00ed3f4b3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 156 additions and 2 deletions

View File

@ -95,6 +95,7 @@
"vue": "^2.3.3",
"vue-awesome": "^2.3.5",
"vue-electron": "^1.0.6",
"vue-js-popover": "^1.1.7",
"vue-router": "^2.5.3",
"vue-shortkey": "^3.1.0",
"vuex": "^2.3.1"

View File

@ -3,7 +3,7 @@
<div class="icon">
<img :src="originalMessage(message).account.avatar" @click="openUser(originalMessage(message).account)"/>
</div>
<div class="detail">
<div class="detail" @click="openDetail(message)">
<div class="toot-header">
<div class="user" @click="openUser(originalMessage(message).account)">
{{ username(originalMessage(message).account) }}
@ -38,6 +38,16 @@
<el-button type="text" @click="changeFavourite(originalMessage(message))" :class="originalMessage(message).favourited ? 'favourited' : 'favourite'">
<icon name="star" scale="0.9"></icon>
</el-button>
<el-button type="text" v-popover="{ name: message.id }">
<icon name="ellipsis-h" scale="0.9"></icon>
</el-button>
<popover :name="message.id" :width="120">
<ul class="toot-menu">
<li role="button" @click="openDetail(message)">
View Toot Detail
</li>
</ul>
</popover>
</div>
</div>
<div class="clearfix"></div>
@ -79,6 +89,11 @@ export default {
openReply (message) {
this.$store.dispatch('TimelineSpace/Modals/NewToot/openReply', message)
},
openDetail (message) {
this.$store.dispatch('TimelineSpace/Contents/SideBar/openTootComponent')
this.$store.dispatch('TimelineSpace/Contents/SideBar/TootDetail/changeToot', message)
this.$store.commit('TimelineSpace/Contents/SideBar/changeOpenSideBar', true)
},
changeReblog (message) {
if (message.reblogged) {
this.$store.dispatch('TimelineSpace/Contents/Cards/Toot/unreblog', message)
@ -247,6 +262,28 @@ function findLink (target) {
.favourited {
color: #e6a23c;
}
.toot-menu{
padding: 0;
font-size: 0.8em;
margin-left: 0.5em;
list-style-type: none;
text-align: center;
li{
padding-bottom: 0.5em;
border-bottom: 1px solid #ddd;
&:hover{
cursor: pointer;
}
&:last-child{
border: 0;
padding: 0;
}
}
}
}
.reply:hover,

View File

@ -4,16 +4,19 @@
<i class="el-icon-close" @click="close"></i>
</div>
<account-profile v-if="component === 1"></account-profile>
<toot-detail v-if="component === 2"></toot-detail>
</div>
</template>
<script>
import { mapState } from 'vuex'
import TootDetail from './SideBar/TootDetail'
import AccountProfile from './SideBar/AccountProfile'
export default {
name: 'side-bar',
components: {
TootDetail,
AccountProfile
},
computed: {

View File

@ -0,0 +1,62 @@
<template>
<div class="toot-detail" ref="detail">
<div class="toot-ancestors" v-for="(message, index) in ancestors" v-bind:key="'ancestors-' + index">
<toot :message="message"></toot>
</div>
<div class="original-toot" ref="original">
<toot :message="message"></toot>
</div>
<div class="toot-descendants" v-for="(message, index) in descendants" v-bind:key="'descendants' + index">
<toot :message="message"></toot>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import Toot from '../Cards/Toot'
export default {
name: 'toot-detail',
components: { Toot },
computed: {
...mapState({
message: state => state.TimelineSpace.Contents.SideBar.TootDetail.message,
ancestors: state => state.TimelineSpace.Contents.SideBar.TootDetail.ancestors,
descendants: state => state.TimelineSpace.Contents.SideBar.TootDetail.descendants
})
},
created () {
this.load()
},
watch: {
message: function () {
this.load()
}
},
methods: {
load () {
this.$store.dispatch('TimelineSpace/Contents/SideBar/TootDetail/fetchToot', this.message)
.then(() => {
const toot = this.$refs.original
toot.scrollIntoView()
})
.catch(() => {
this.$message({
message: 'Could not fetch toot detail',
type: 'error'
})
})
}
}
}
</script>
<style lang="scss" scoped>
.original-toot{
.toot{
background-color: #f2f6fc;
outline: 0;
}
}
</style>

View File

@ -1,6 +1,7 @@
import Vue from 'vue'
import axios from 'axios'
import ElementUI from 'element-ui'
import Popover from 'vue-js-popover'
import 'element-ui/lib/theme-chalk/index.css'
import 'vue-awesome/icons'
import Icon from 'vue-awesome/components/Icon'
@ -11,6 +12,7 @@ import router from './router'
import store from './store'
Vue.use(ElementUI)
Vue.use(Popover)
Vue.component('icon', Icon)
if (!process.env.IS_WEB) Vue.use(require('vue-electron'))

View File

@ -1,14 +1,17 @@
import AccountProfile from './SideBar/AccountProfile'
import TootDetail from './SideBar/TootDetail'
const SideBar = {
namespaced: true,
modules: {
AccountProfile
AccountProfile,
TootDetail
},
state: {
openSideBar: false,
// 0: blank
// 1: account-profile
// 2: toot-detail
component: 0
},
mutations: {
@ -26,6 +29,9 @@ const SideBar = {
},
openAccountComponent ({ commit }) {
commit('changeComponent', 1)
},
openTootComponent ({ commit }) {
commit('changeComponent', 2)
}
}
}

View File

@ -0,0 +1,43 @@
import Mastodon from 'mastodon-api'
const TootDetail = {
namespaced: true,
state: {
message: null,
ancestors: [],
descendants: []
},
mutations: {
changeToot (state, message) {
state.message = message
},
updateAncestors (state, ancestors) {
state.ancestors = ancestors
},
updateDescendants (state, descendants) {
state.descendants = descendants
}
},
actions: {
changeToot ({ commit, dispatch }, message) {
commit('changeToot', message)
},
fetchToot ({ state, commit, rootState }, message) {
return new Promise((resolve, reject) => {
const client = new Mastodon(
{
access_token: rootState.TimelineSpace.account.accessToken,
api_url: rootState.TimelineSpace.account.baseURL + '/api/v1'
})
client.get(`/statuses/${message.id}/context`, { limit: 40 }, (err, data, res) => {
if (err) return reject(err)
commit('updateAncestors', data.ancestors)
commit('updateDescendants', data.descendants)
resolve(res)
})
})
}
}
}
export default TootDetail