iceshrimp/src/client/app/common/views/components/note-menu.vue

176 lines
3.9 KiB
Vue
Raw Normal View History

2018-02-13 08:11:10 +09:00
<template>
2018-04-08 02:30:37 +09:00
<div class="mk-note-menu">
2018-02-13 08:11:10 +09:00
<div class="backdrop" ref="backdrop" @click="close"></div>
2018-02-22 07:06:47 +09:00
<div class="popover" :class="{ compact }" ref="popover">
2018-04-20 13:31:43 +09:00
<button @click="favorite">%i18n:@favorite%</button>
2018-05-27 13:49:09 +09:00
<button v-if="note.userId == $store.state.i.id" @click="pin">%i18n:@pin%</button>
2018-05-28 14:39:46 +09:00
<button v-if="note.userId == $store.state.i.id" @click="del">%i18n:@delete%</button>
2018-04-17 15:12:59 +09:00
<a v-if="note.uri" :href="note.uri" target="_blank">%i18n:@remote%</a>
2018-02-13 08:11:10 +09:00
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
2018-02-13 09:27:57 +09:00
import * as anime from 'animejs';
2018-02-13 08:11:10 +09:00
export default Vue.extend({
2018-04-08 02:30:37 +09:00
props: ['note', 'source', 'compact'],
2018-02-13 08:11:10 +09:00
mounted() {
2018-02-22 07:06:47 +09:00
this.$nextTick(() => {
const popover = this.$refs.popover as any;
const rect = this.source.getBoundingClientRect();
const width = popover.offsetWidth;
const height = popover.offsetHeight;
if (this.compact) {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2);
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = (y - (height / 2)) + 'px';
} else {
const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2);
const y = rect.top + window.pageYOffset + this.source.offsetHeight;
popover.style.left = (x - (width / 2)) + 'px';
popover.style.top = y + 'px';
}
2018-02-13 08:11:10 +09:00
2018-02-22 07:06:47 +09:00
anime({
targets: this.$refs.backdrop,
opacity: 1,
duration: 100,
easing: 'linear'
});
2018-02-13 08:11:10 +09:00
2018-02-22 07:06:47 +09:00
anime({
targets: this.$refs.popover,
opacity: 1,
scale: [0.5, 1],
duration: 500
});
2018-02-13 08:11:10 +09:00
});
},
methods: {
pin() {
2018-02-18 12:35:18 +09:00
(this as any).api('i/pin', {
2018-04-08 02:30:37 +09:00
noteId: this.note.id
2018-02-13 08:11:10 +09:00
}).then(() => {
this.$destroy();
});
},
2018-05-28 14:39:46 +09:00
del() {
if (!window.confirm('%i18n:@delete-confirm%')) return;
(this as any).api('notes/delete', {
noteId: this.note.id
}).then(() => {
this.$destroy();
});
},
2018-04-20 13:31:43 +09:00
favorite() {
(this as any).api('notes/favorites/create', {
noteId: this.note.id
}).then(() => {
this.$destroy();
});
},
2018-02-13 08:11:10 +09:00
close() {
(this.$refs.backdrop as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.backdrop,
opacity: 0,
duration: 200,
easing: 'linear'
});
(this.$refs.popover as any).style.pointerEvents = 'none';
anime({
targets: this.$refs.popover,
opacity: 0,
scale: 0.5,
duration: 200,
easing: 'easeInBack',
complete: () => this.$destroy()
});
}
}
});
</script>
<style lang="stylus" scoped>
2018-04-17 15:12:59 +09:00
@import '~const.styl'
2018-02-13 08:11:10 +09:00
$border-color = rgba(27, 31, 35, 0.15)
2018-04-08 02:30:37 +09:00
.mk-note-menu
2018-02-13 08:11:10 +09:00
position initial
> .backdrop
position fixed
top 0
left 0
z-index 10000
width 100%
height 100%
2018-04-29 08:51:17 +09:00
background rgba(#000, 0.1)
2018-02-13 08:11:10 +09:00
opacity 0
> .popover
position absolute
z-index 10001
2018-04-17 15:12:59 +09:00
padding 8px 0
2018-02-13 08:11:10 +09:00
background #fff
border 1px solid $border-color
border-radius 4px
box-shadow 0 3px 12px rgba(27, 31, 35, 0.15)
transform scale(0.5)
opacity 0
$balloon-size = 16px
&:not(.compact)
margin-top $balloon-size
transform-origin center -($balloon-size)
&:before
content ""
display block
position absolute
top -($balloon-size * 2)
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size $border-color
&:after
content ""
display block
position absolute
top -($balloon-size * 2) + 1.5px
left s('calc(50% - %s)', $balloon-size)
border-top solid $balloon-size transparent
border-left solid $balloon-size transparent
border-right solid $balloon-size transparent
border-bottom solid $balloon-size #fff
> button
2018-04-17 15:12:59 +09:00
> a
2018-02-13 08:11:10 +09:00
display block
2018-04-17 15:12:59 +09:00
padding 8px 16px
2018-04-20 13:31:43 +09:00
width 100%
2018-04-17 15:12:59 +09:00
&:hover
color $theme-color-foreground
background $theme-color
text-decoration none
&:active
color $theme-color-foreground
background darken($theme-color, 10%)
2018-02-13 08:11:10 +09:00
</style>