#468 - add extra buttons for status actions

This commit is contained in:
dave 2019-04-12 15:35:29 -04:00 committed by taehoon
parent 80ef855a63
commit 9fc997500e
8 changed files with 118 additions and 68 deletions

View File

@ -1,21 +0,0 @@
const DeleteButton = {
props: [ 'status' ],
methods: {
deleteStatus () {
const confirmed = window.confirm('Do you really want to delete this status?')
if (confirmed) {
this.$store.dispatch('deleteStatus', { id: this.status.id })
}
}
},
computed: {
currentUser () { return this.$store.state.users.currentUser },
canDelete () {
if (!this.currentUser) { return }
const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin
return superuser || this.status.user.id === this.currentUser.id
}
}
}
export default DeleteButton

View File

@ -1,21 +0,0 @@
<template>
<div v-if="canDelete">
<a href="#" v-on:click.prevent="deleteStatus()">
<i class='button-icon icon-cancel delete-status'></i>
</a>
</div>
</template>
<script src="./delete_button.js" ></script>
<style lang="scss">
@import '../../_variables.scss';
.icon-cancel,.delete-status {
cursor: pointer;
&:hover {
color: $fallback--cRed;
color: var(--cRed, $fallback--cRed);
}
}
</style>

View File

@ -0,0 +1,51 @@
import Popper from 'vue-popperjs/src/component/popper.js.vue'
const ExtraButtons = {
props: [ 'status' ],
components: {
Popper
},
data () {
return {
showDropDown: false
}
},
methods: {
deleteStatus () {
const confirmed = window.confirm(this.$t('status.delete_confirm'))
if (confirmed) {
this.$store.dispatch('deleteStatus', { id: this.status.id })
}
},
toggleMenu () {
this.showDropDown = !this.showDropDown
},
pinStatus () {
this.$store.state.api.backendInteractor.pinOwnStatus(this.status.id).then((status) => {
if (status.error) {
this.$emit('onError', status.error)
} else {
this.$store.dispatch('updatePinned', status)
}
})
},
unpinStatus () {
this.$store.state.api.backendInteractor.unpinOwnStatus(this.status.id).then((status) => {
this.$store.dispatch('updatePinned', status)
})
}
},
computed: {
currentUser () { return this.$store.state.users.currentUser },
canDelete () {
if (!this.currentUser) { return }
const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin
return superuser || this.status.user.id === this.currentUser.id
},
ownStatus () {
return this.status.user.id === this.currentUser.id
}
}
}
export default ExtraButtons

View File

@ -0,0 +1,46 @@
<template>
<Popper
trigger="click"
@hide='showDropDown = false'
append-to-body
:options="{
placement: 'top',
modifiers: {
arrow: { enabled: true },
offset: { offset: '0, 5px' },
}
}"
>
<div class="popper-wrapper">
<div class="dropdown-menu">
<button class="dropdown-item dropdown-item-icon" @click.prevent="pinStatus" v-if="!status.pinned && ownStatus">
<i class="icon-pin"></i><span>{{$t("status.pin")}}</span>
</button>
<button class="dropdown-item dropdown-item-icon" @click.prevent="unpinStatus" v-if="status.pinned && ownStatus">
<i class="icon-pin"></i><span>{{$t("status.unpin")}}</span>
</button>
<button class="dropdown-item dropdown-item-icon" @click.prevent="deleteStatus" v-if="canDelete">
<i class="icon-cancel"></i><span>{{$t("status.delete")}}</span>
</button>
</div>
</div>
<div class="button-icon" slot="reference" @click="toggleMenu">
<i class='icon-ellipsis' :class="{'icon-clicked': showDropDown}"></i>
</div>
</Popper>
</template>
<script src="./extra_buttons.js" ></script>
<style lang="scss">
@import '../../_variables.scss';
.icon-ellipsis {
cursor: pointer;
&:hover, &.icon-clicked {
color: $fallback--cBlue;
color: var(--cBlue, $fallback--cBlue);
}
}
</style>

View File

@ -127,6 +127,14 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
&-icon {
padding-left: 0.5rem;
i {
margin-right: 0.25rem;
}
}
&:hover { &:hover {
// TODO: improve the look on breeze themes // TODO: improve the look on breeze themes
background-color: $fallback--fg; background-color: $fallback--fg;

View File

@ -1,7 +1,7 @@
import Attachment from '../attachment/attachment.vue' import Attachment from '../attachment/attachment.vue'
import FavoriteButton from '../favorite_button/favorite_button.vue' import FavoriteButton from '../favorite_button/favorite_button.vue'
import RetweetButton from '../retweet_button/retweet_button.vue' import RetweetButton from '../retweet_button/retweet_button.vue'
import DeleteButton from '../delete_button/delete_button.vue' import ExtraButtons from '../extra_buttons/extra_buttons.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue' import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCard from '../user_card/user_card.vue' import UserCard from '../user_card/user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue' import UserAvatar from '../user_avatar/user_avatar.vue'
@ -280,7 +280,7 @@ const Status = {
Attachment, Attachment,
FavoriteButton, FavoriteButton,
RetweetButton, RetweetButton,
DeleteButton, ExtraButtons,
PostStatusForm, PostStatusForm,
UserCard, UserCard,
UserAvatar, UserAvatar,
@ -301,6 +301,12 @@ const Status = {
return 'icon-globe' return 'icon-globe'
} }
}, },
showError (error) {
this.error = error
setTimeout(() => {
this.error = null
}, 5000)
},
linkClicked (event) { linkClicked (event) {
let { target } = event let { target } = event
if (target.tagName === 'SPAN') { if (target.tagName === 'SPAN') {
@ -358,23 +364,6 @@ const Status = {
this.expandingSubject = true this.expandingSubject = true
} }
}, },
pinStatus () {
this.$store.state.api.backendInteractor.pinOwnStatus(this.status.id).then((status) => {
if (status.error) {
this.error = status.error
setTimeout(() => {
this.error = null
}, 5000)
} else {
this.$store.dispatch('updatePinned', status)
}
})
},
unpinStatus () {
this.$store.state.api.backendInteractor.unpinOwnStatus(this.status.id).then((status) => {
this.$store.dispatch('updatePinned', status)
})
},
replyEnter (id, event) { replyEnter (id, event) {
this.showPreview = true this.showPreview = true
const targetId = id const targetId = id

View File

@ -16,9 +16,6 @@
<div v-if="pinned" class="status-pin"> <div v-if="pinned" class="status-pin">
<i class="fa icon-pin faint"></i> <i class="fa icon-pin faint"></i>
<span class="faint">Pinned</span> <span class="faint">Pinned</span>
<div class="button-icon button-action-icon" v-if="status.pinned && ownStatus" @click.prevent="unpinStatus" title="Unpin">
<i class="fa icon-cancel"></i>
</div>
</div> </div>
<div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info"> <div v-if="retweet && !noHeading && !inConversation" :class="[repeaterClass, { highlighted: repeaterStyle }]" :style="[repeaterStyle]" class="media container retweet-info">
<UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/> <UserAvatar class="media-left" v-if="retweet" :betterShadow="betterShadow" :user="statusoid.user"/>
@ -60,9 +57,6 @@
<a :href="status.external_url" target="_blank" v-if="!status.is_local && !isPreview" class="source_url" title="Source"> <a :href="status.external_url" target="_blank" v-if="!status.is_local && !isPreview" class="source_url" title="Source">
<i class="button-icon icon-link-ext-alt"></i> <i class="button-icon icon-link-ext-alt"></i>
</a> </a>
<div class="button-icon button-action-icon" v-if="!status.pinned && ownStatus" @click.prevent="pinStatus" title="Pin">
<i class="fa icon-pin"></i>
</div>
<div class="button-icon button-action-icon" v-if="expandable && !isPreview" @click.prevent="toggleExpanded" title="Expand"> <div class="button-icon button-action-icon" v-if="expandable && !isPreview" @click.prevent="toggleExpanded" title="Expand">
<i class="icon-plus-squared"></i> <i class="icon-plus-squared"></i>
</div> </div>
@ -175,7 +169,7 @@
</div> </div>
<retweet-button :visibility='status.visibility' :loggedIn='loggedIn' :status='status'></retweet-button> <retweet-button :visibility='status.visibility' :loggedIn='loggedIn' :status='status'></retweet-button>
<favorite-button :loggedIn='loggedIn' :status='status'></favorite-button> <favorite-button :loggedIn='loggedIn' :status='status'></favorite-button>
<delete-button :status='status'></delete-button> <extra-buttons :status="status" @onError="showError"></extra-buttons>
</div> </div>
</div> </div>
</div> </div>

View File

@ -402,6 +402,10 @@
"status": { "status": {
"favorites": "Favorites", "favorites": "Favorites",
"repeats": "Repeats", "repeats": "Repeats",
"delete": "Delete status",
"pin": "Pin on profile",
"unpin": "Unpin form profile",
"delete_confirm": "Do you really want to delete this status?",
"reply_to": "Reply to", "reply_to": "Reply to",
"replies_list": "Replies:" "replies_list": "Replies:"
}, },