iceshrimp-legacy/src/client/app/desktop/views/components/drive.file.vue

346 lines
6.9 KiB
Vue
Raw Normal View History

2018-02-14 11:03:48 +01:00
<template>
2018-07-24 21:36:02 +02:00
<div class="gvfdktuvdgwhmztnuekzkswkjygptfcv"
2018-02-14 11:03:48 +01:00
:data-is-selected="isSelected"
:data-is-contextmenu-showing="isContextmenuShowing"
@click="onClick"
draggable="true"
@dragstart="onDragstart"
@dragend="onDragend"
2018-02-18 04:35:18 +01:00
@contextmenu.prevent.stop="onContextmenu"
2018-02-14 11:03:48 +01:00
:title="title"
>
2018-08-18 20:56:44 +02:00
<div class="label" v-if="$store.state.i.avatarId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('avatar') }}</p>
2018-02-14 11:03:48 +01:00
</div>
2018-08-18 20:56:44 +02:00
<div class="label" v-if="$store.state.i.bannerId == file.id">
<img src="/assets/label.svg"/>
<p>{{ $t('banner') }}</p>
2018-02-14 11:03:48 +01:00
</div>
2018-08-18 20:56:44 +02:00
<div class="label red" v-if="file.isSensitive">
<img src="/assets/label-red.svg"/>
<p>{{ $t('nsfw') }}</p>
2018-08-18 20:56:44 +02:00
</div>
2018-02-18 04:35:18 +01:00
<div class="thumbnail" ref="thumbnail" :style="`background-color: ${ background }`">
2018-08-16 00:17:04 +02:00
<img :src="file.thumbnailUrl" alt="" @load="onThumbnailLoaded"/>
2018-02-14 11:03:48 +01:00
</div>
<p class="name">
2018-02-18 04:35:18 +01:00
<span>{{ file.name.lastIndexOf('.') != -1 ? file.name.substr(0, file.name.lastIndexOf('.')) : file.name }}</span>
<span class="ext" v-if="file.name.lastIndexOf('.') != -1">{{ file.name.substr(file.name.lastIndexOf('.')) }}</span>
2018-02-14 11:03:48 +01:00
</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
2018-02-14 11:03:48 +01:00
import * as anime from 'animejs';
2018-02-18 04:35:18 +01:00
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
2018-02-14 11:03:48 +01:00
export default Vue.extend({
i18n: i18n('desktop/views/components/drive.file.vue'),
2018-02-18 04:35:18 +01:00
props: ['file'],
2018-02-14 11:03:48 +01:00
data() {
return {
isContextmenuShowing: false,
isDragging: false
};
},
computed: {
2018-02-18 04:35:18 +01:00
browser(): any {
return this.$parent;
},
2018-02-14 11:03:48 +01:00
isSelected(): boolean {
return this.browser.selectedFiles.some(f => f.id == this.file.id);
},
title(): string {
2018-02-20 00:05:41 +01:00
return `${this.file.name}\n${this.file.type} ${Vue.filter('bytes')(this.file.datasize)}`;
2018-02-18 04:35:18 +01:00
},
background(): string {
return this.file.properties.avgColor && this.file.properties.avgColor.length == 3
2018-03-29 07:48:47 +02:00
? `rgb(${this.file.properties.avgColor.join(',')})`
2018-02-18 04:35:18 +01:00
: 'transparent';
2018-02-14 11:03:48 +01:00
}
},
methods: {
onClick() {
this.browser.chooseFile(this.file);
},
onContextmenu(e) {
this.isContextmenuShowing = true;
this.$contextmenu(e, [{
2018-02-18 04:35:18 +01:00
type: 'item',
text: this.$t('contextmenu.rename'),
icon: 'i-cursor',
2018-06-08 04:46:45 +02:00
action: this.rename
2018-02-18 04:35:18 +01:00
}, {
2018-07-19 19:40:37 +02:00
type: 'item',
text: this.file.isSensitive ? this.$t('contextmenu.unmark-as-sensitive') : this.$t('contextmenu.mark-as-sensitive'),
icon: this.file.isSensitive ? ['far', 'eye'] : ['far', 'eye-slash'],
2018-07-19 19:40:37 +02:00
action: this.toggleSensitive
}, null, {
2018-02-18 04:35:18 +01:00
type: 'item',
text: this.$t('contextmenu.copy-url'),
icon: 'link',
2018-06-08 04:46:45 +02:00
action: this.copyUrl
2018-02-18 04:35:18 +01:00
}, {
type: 'link',
href: `${this.file.url}?download`,
text: this.$t('contextmenu.download'),
icon: 'download',
2018-06-08 04:46:45 +02:00
}, null, {
2018-02-18 04:35:18 +01:00
type: 'item',
text: this.$t('@.delete'),
icon: ['far', 'trash-alt'],
2018-06-08 04:46:45 +02:00
action: this.deleteFile
}, null, {
2018-02-18 04:35:18 +01:00
type: 'nest',
text: this.$t('contextmenu.else-files'),
2018-02-18 04:35:18 +01:00
menu: [{
type: 'item',
text: this.$t('contextmenu.set-as-avatar'),
2018-06-08 04:46:45 +02:00
action: this.setAsAvatar
2018-02-18 04:35:18 +01:00
}, {
type: 'item',
text: this.$t('contextmenu.set-as-banner'),
2018-06-08 04:46:45 +02:00
action: this.setAsBanner
2018-02-18 04:35:18 +01:00
}]
2018-08-13 15:08:59 +02:00
}, /*{
2018-02-18 04:35:18 +01:00
type: 'nest',
text: this.$t('contextmenu.open-in-app'),
2018-02-18 04:35:18 +01:00
menu: [{
type: 'item',
2018-05-20 13:26:38 +02:00
text: '%i18n:@contextmenu.add-app%...',
2018-06-08 04:46:45 +02:00
action: this.addApp
2018-02-18 04:35:18 +01:00
}]
2018-08-13 15:08:59 +02:00
}*/], {
closed: () => {
this.isContextmenuShowing = false;
}
});
2018-02-14 11:03:48 +01:00
},
onDragstart(e) {
e.dataTransfer.effectAllowed = 'move';
2018-02-26 22:25:17 +01:00
e.dataTransfer.setData('mk_drive_file', JSON.stringify(this.file));
2018-02-14 11:03:48 +01:00
this.isDragging = true;
// 親ブラウザに対して、ドラッグが開始されたフラグを立てる
// (=あなたの子供が、ドラッグを開始しましたよ)
this.browser.isDragSource = true;
},
onDragend(e) {
this.isDragging = false;
this.browser.isDragSource = false;
},
onThumbnailLoaded() {
if (this.file.properties.avgColor && this.file.properties.avgColor.length == 3) {
2018-02-14 11:03:48 +01:00
anime({
targets: this.$refs.thumbnail,
2018-03-29 07:48:47 +02:00
backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`,
2018-02-14 11:03:48 +01:00
duration: 100,
easing: 'linear'
});
}
2018-02-18 04:35:18 +01:00
},
rename() {
2018-12-02 12:10:53 +01:00
this.$root.dialog({
title: this.$t('contextmenu.rename-file'),
2018-12-02 12:10:53 +01:00
input: {
placeholder: this.$t('contextmenu.input-new-file-name'),
default: this.file.name,
allowEmpty: false
}
}).then(({ canceled, result: name }) => {
if (canceled) return;
2018-11-09 00:13:34 +01:00
this.$root.api('drive/files/update', {
2018-03-29 07:48:47 +02:00
fileId: this.file.id,
2018-02-18 04:35:18 +01:00
name: name
});
2018-02-18 04:35:18 +01:00
});
},
2018-07-19 19:40:37 +02:00
toggleSensitive() {
2018-11-09 00:13:34 +01:00
this.$root.api('drive/files/update', {
2018-07-19 19:40:37 +02:00
fileId: this.file.id,
isSensitive: !this.file.isSensitive
});
},
2018-02-18 04:35:18 +01:00
copyUrl() {
copyToClipboard(this.file.url);
2018-12-02 07:28:52 +01:00
this.$root.dialog({
title: this.$t('contextmenu.copied'),
2018-11-14 08:30:58 +01:00
text: this.$t('contextmenu.copied-url-to-clipboard')
2018-02-18 04:35:18 +01:00
});
},
setAsAvatar() {
this.$updateAvatar(this.file);
2018-02-18 04:35:18 +01:00
},
setAsBanner() {
this.$updateBanner(this.file);
2018-02-18 04:35:18 +01:00
},
addApp() {
alert('not implemented yet');
},
deleteFile() {
2018-11-09 00:13:34 +01:00
this.$root.api('drive/files/delete', {
fileId: this.file.id
});
2018-02-14 11:03:48 +01:00
}
}
});
</script>
<style lang="stylus" scoped>
2018-09-28 12:59:19 +02:00
.gvfdktuvdgwhmztnuekzkswkjygptfcv
2018-02-14 11:03:48 +01:00
padding 8px 0 0 0
height 180px
border-radius 4px
&, *
cursor pointer
&:hover
2018-04-29 01:51:17 +02:00
background rgba(#000, 0.05)
2018-02-14 11:03:48 +01:00
> .label
&:before
&:after
background #0b65a5
2018-08-18 20:56:44 +02:00
&.red
&:before
&:after
background #c12113
2018-02-14 11:03:48 +01:00
&:active
2018-04-29 01:51:17 +02:00
background rgba(#000, 0.1)
2018-02-14 11:03:48 +01:00
> .label
&:before
&:after
background #0b588c
2018-08-18 20:56:44 +02:00
&.red
&:before
&:after
background #ce2212
2018-02-14 11:03:48 +01:00
&[data-is-selected]
2018-09-26 13:19:35 +02:00
background var(--primary)
2018-02-14 11:03:48 +01:00
&:hover
2018-09-26 13:19:35 +02:00
background var(--primaryLighten10)
2018-02-14 11:03:48 +01:00
&:active
2018-09-26 13:19:35 +02:00
background var(--primaryDarken10)
2018-02-14 11:03:48 +01:00
> .label
&:before
&:after
display none
> .name
2018-09-26 13:19:35 +02:00
color var(--primaryForeground)
2018-02-14 11:03:48 +01:00
&[data-is-contextmenu-showing]
&:after
content ""
pointer-events none
position absolute
top -4px
right -4px
bottom -4px
left -4px
2018-09-26 13:19:35 +02:00
border 2px dashed var(--primaryAlpha03)
2018-02-14 11:03:48 +01:00
border-radius 4px
> .label
position absolute
top 0
left 0
pointer-events none
&:before
2018-08-18 20:56:44 +02:00
&:after
2018-02-14 11:03:48 +01:00
content ""
display block
position absolute
z-index 1
2018-08-18 20:56:44 +02:00
background #0c7ac9
&:before
2018-02-14 11:03:48 +01:00
top 0
left 57px
width 28px
height 8px
&:after
top 57px
left 0
width 8px
height 28px
2018-08-18 20:56:44 +02:00
&.red
&:before
&:after
background #c12113
2018-02-14 11:03:48 +01:00
> img
position absolute
z-index 2
top 0
left 0
> p
position absolute
z-index 3
top 19px
left -28px
width 120px
margin 0
text-align center
line-height 28px
color #fff
transform rotate(-45deg)
> .thumbnail
width 128px
height 128px
margin auto
> img
display block
position absolute
top 0
left 0
right 0
bottom 0
margin auto
max-width 128px
max-height 128px
pointer-events none
> .name
display block
margin 4px 0 0 0
font-size 0.8em
text-align center
word-break break-all
2018-09-28 12:59:19 +02:00
color var(--text)
2018-02-14 11:03:48 +01:00
overflow hidden
> .ext
opacity 0.5
</style>