#468 - add extra buttons for status actions
This commit is contained in:
parent
80ef855a63
commit
9fc997500e
8 changed files with 118 additions and 68 deletions
|
@ -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
|
|
|
@ -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>
|
|
51
src/components/extra_buttons/extra_buttons.js
Normal file
51
src/components/extra_buttons/extra_buttons.js
Normal 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
|
46
src/components/extra_buttons/extra_buttons.vue
Normal file
46
src/components/extra_buttons/extra_buttons.vue
Normal 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>
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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:"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue