mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
add clipboard button
This commit is contained in:
parent
2f7ac7e00f
commit
477256bb94
78
client/src/components/clipboard.vue
Normal file
78
client/src/components/clipboard.vue
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="clipboard"
|
||||||
|
v-if="opened"
|
||||||
|
@click="$event.stopPropagation()"
|
||||||
|
>
|
||||||
|
<textarea ref="textarea" v-model="clipboard" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.clipboard {
|
||||||
|
background-color: $background-primary;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
|
||||||
|
&, textarea {
|
||||||
|
max-width: 320px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 120px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
border: 0;
|
||||||
|
color: $text-normal;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
&::selection {
|
||||||
|
background: $text-normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Ref, Vue } from 'vue-property-decorator'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'neko-clipboard',
|
||||||
|
})
|
||||||
|
export default class extends Vue {
|
||||||
|
@Ref('textarea') readonly _textarea!: HTMLTextAreaElement
|
||||||
|
|
||||||
|
private opened: boolean = false
|
||||||
|
private typing: any = null
|
||||||
|
|
||||||
|
get clipboard() {
|
||||||
|
return this.$accessor.remote.clipboard
|
||||||
|
}
|
||||||
|
|
||||||
|
set clipboard(data: string) {
|
||||||
|
this.$accessor.remote.setClipboard(data)
|
||||||
|
|
||||||
|
if (this.typing) {
|
||||||
|
clearTimeout(this.typing)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.typing = setTimeout(() => this.$accessor.remote.sendClipboard(this.clipboard), 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
this.opened = true
|
||||||
|
document.body.addEventListener('click', this.close)
|
||||||
|
setTimeout(() => this._textarea.focus(), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.opened = false
|
||||||
|
document.body.removeEventListener('click', this.close)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -26,11 +26,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div ref="aspect" class="player-aspect" />
|
<div ref="aspect" class="player-aspect" />
|
||||||
</div>
|
</div>
|
||||||
<ul v-if="!fullscreen" class="video-menu">
|
<ul v-if="!fullscreen" class="video-menu top">
|
||||||
<li><i @click.stop.prevent="requestFullscreen" class="fas fa-expand"></i></li>
|
<li><i @click.stop.prevent="requestFullscreen" class="fas fa-expand"></i></li>
|
||||||
<li v-if="admin"><i @click.stop.prevent="onResolution" class="fas fa-desktop"></i></li>
|
<li v-if="admin"><i @click.stop.prevent="onResolution" class="fas fa-desktop"></i></li>
|
||||||
</ul>
|
</ul>
|
||||||
<neko-resolution ref="resolution" />
|
<ul v-if="!fullscreen" class="video-menu bottom">
|
||||||
|
<li v-if="hosting"><i @click.stop.prevent="onClipboard" class="fas fa-clipboard"></i></li>
|
||||||
|
</ul>
|
||||||
|
<neko-resolution ref="resolution" v-if="admin" />
|
||||||
|
<neko-clipboard ref="clipboard" v-if="hosting" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -49,7 +53,14 @@
|
|||||||
.video-menu {
|
.video-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
|
|
||||||
|
&.top {
|
||||||
top: 15px;
|
top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bottom {
|
||||||
|
bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
@ -65,6 +76,10 @@
|
|||||||
color: rgba($color: #fff, $alpha: 0.6);
|
color: rgba($color: #fff, $alpha: 0.6);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +154,7 @@
|
|||||||
|
|
||||||
import Emote from './emote.vue'
|
import Emote from './emote.vue'
|
||||||
import Resolution from './resolution.vue'
|
import Resolution from './resolution.vue'
|
||||||
|
import Clipboard from './clipboard.vue'
|
||||||
|
|
||||||
import GuacamoleKeyboard from '~/utils/guacamole-keyboard.ts'
|
import GuacamoleKeyboard from '~/utils/guacamole-keyboard.ts'
|
||||||
|
|
||||||
@ -147,6 +163,7 @@
|
|||||||
components: {
|
components: {
|
||||||
'neko-emote': Emote,
|
'neko-emote': Emote,
|
||||||
'neko-resolution': Resolution,
|
'neko-resolution': Resolution,
|
||||||
|
'neko-clipboard': Clipboard,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
@ -157,6 +174,7 @@
|
|||||||
@Ref('player') readonly _player!: HTMLElement
|
@Ref('player') readonly _player!: HTMLElement
|
||||||
@Ref('video') readonly _video!: HTMLVideoElement
|
@Ref('video') readonly _video!: HTMLVideoElement
|
||||||
@Ref('resolution') readonly _resolution!: any
|
@Ref('resolution') readonly _resolution!: any
|
||||||
|
@Ref('clipboard') readonly _clipboard!: any
|
||||||
|
|
||||||
private keyboard = GuacamoleKeyboard()
|
private keyboard = GuacamoleKeyboard()
|
||||||
private observer = new ResizeObserver(this.onResise.bind(this))
|
private observer = new ResizeObserver(this.onResise.bind(this))
|
||||||
@ -512,5 +530,9 @@
|
|||||||
onResolution(event: MouseEvent) {
|
onResolution(event: MouseEvent) {
|
||||||
this._resolution.open(event)
|
this._resolution.open(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClipboard(event: MouseEvent) {
|
||||||
|
this._clipboard.open(event)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user