misskey-awawa/src/client/app/desktop/views/components/drive.file.vue

345 lines
6.9 KiB
Vue
Raw Normal View History

2018-02-14 10:03:48 +00:00
<template>
2018-07-24 19:36:02 +00:00
<div class="gvfdktuvdgwhmztnuekzkswkjygptfcv"
2018-02-14 10:03:48 +00:00
:data-is-selected="isSelected"
:data-is-contextmenu-showing="isContextmenuShowing"
@click="onClick"
draggable="true"
@dragstart="onDragstart"
@dragend="onDragend"
2018-02-18 03:35:18 +00:00
@contextmenu.prevent.stop="onContextmenu"
2018-02-14 10:03:48 +00:00
:title="title"
>
2018-08-18 18:56:44 +00:00
<div class="label" v-if="$store.state.i.avatarId == file.id">
<img src="/assets/label.svg"/>
2018-04-14 16:04:40 +00:00
<p>%i18n:@avatar%</p>
2018-02-14 10:03:48 +00:00
</div>
2018-08-18 18:56:44 +00:00
<div class="label" v-if="$store.state.i.bannerId == file.id">
<img src="/assets/label.svg"/>
2018-04-14 16:04:40 +00:00
<p>%i18n:@banner%</p>
2018-02-14 10:03:48 +00:00
</div>
2018-08-18 18:56:44 +00:00
<div class="label red" v-if="file.isSensitive">
<img src="/assets/label-red.svg"/>
<p>%i18n:@nsfw%</p>
</div>
2018-02-18 03:35:18 +00:00
<div class="thumbnail" ref="thumbnail" :style="`background-color: ${ background }`">
2018-08-15 22:17:04 +00:00
<img :src="file.thumbnailUrl" alt="" @load="onThumbnailLoaded"/>
2018-02-14 10:03:48 +00:00
</div>
<p class="name">
2018-02-18 03:35:18 +00: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 10:03:48 +00:00
</p>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import * as anime from 'animejs';
2018-02-18 03:35:18 +00:00
import contextmenu from '../../api/contextmenu';
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
2018-02-14 10:03:48 +00:00
export default Vue.extend({
2018-02-18 03:35:18 +00:00
props: ['file'],
2018-02-14 10:03:48 +00:00
data() {
return {
isContextmenuShowing: false,
isDragging: false
};
},
computed: {
2018-02-18 03:35:18 +00:00
browser(): any {
return this.$parent;
},
2018-02-14 10:03:48 +00:00
isSelected(): boolean {
return this.browser.selectedFiles.some(f => f.id == this.file.id);
},
title(): string {
2018-02-19 23:05:41 +00:00
return `${this.file.name}\n${this.file.type} ${Vue.filter('bytes')(this.file.datasize)}`;
2018-02-18 03:35:18 +00:00
},
background(): string {
return this.file.properties.avgColor && this.file.properties.avgColor.length == 3
2018-03-29 05:48:47 +00:00
? `rgb(${this.file.properties.avgColor.join(',')})`
2018-02-18 03:35:18 +00:00
: 'transparent';
2018-02-14 10:03:48 +00:00
}
},
methods: {
onClick() {
this.browser.chooseFile(this.file);
},
onContextmenu(e) {
this.isContextmenuShowing = true;
2018-05-29 15:15:32 +00:00
contextmenu((this as any).os)(e, [{
2018-02-18 03:35:18 +00:00
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.rename%',
2018-02-18 03:35:18 +00:00
icon: '%fa:i-cursor%',
2018-06-08 02:46:45 +00:00
action: this.rename
2018-02-18 03:35:18 +00:00
}, {
2018-07-19 17:40:37 +00:00
type: 'item',
text: this.file.isSensitive ? '%i18n:@contextmenu.unmark-as-sensitive%' : '%i18n:@contextmenu.mark-as-sensitive%',
icon: this.file.isSensitive ? '%fa:R eye%' : '%fa:R eye-slash%',
action: this.toggleSensitive
}, null, {
2018-02-18 03:35:18 +00:00
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.copy-url%',
2018-02-18 03:35:18 +00:00
icon: '%fa:link%',
2018-06-08 02:46:45 +00:00
action: this.copyUrl
2018-02-18 03:35:18 +00:00
}, {
type: 'link',
href: `${this.file.url}?download`,
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.download%',
2018-02-18 03:35:18 +00:00
icon: '%fa:download%',
2018-06-08 02:46:45 +00:00
}, null, {
2018-02-18 03:35:18 +00:00
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:common.delete%',
2018-02-18 03:35:18 +00:00
icon: '%fa:R trash-alt%',
2018-06-08 02:46:45 +00:00
action: this.deleteFile
}, null, {
2018-02-18 03:35:18 +00:00
type: 'nest',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.else-files%',
2018-02-18 03:35:18 +00:00
menu: [{
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.set-as-avatar%',
2018-06-08 02:46:45 +00:00
action: this.setAsAvatar
2018-02-18 03:35:18 +00:00
}, {
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.set-as-banner%',
2018-06-08 02:46:45 +00:00
action: this.setAsBanner
2018-02-18 03:35:18 +00:00
}]
2018-08-13 13:08:59 +00:00
}, /*{
2018-02-18 03:35:18 +00:00
type: 'nest',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.open-in-app%',
2018-02-18 03:35:18 +00:00
menu: [{
type: 'item',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.add-app%...',
2018-06-08 02:46:45 +00:00
action: this.addApp
2018-02-18 03:35:18 +00:00
}]
2018-08-13 13:08:59 +00:00
}*/], {
closed: () => {
this.isContextmenuShowing = false;
}
});
2018-02-14 10:03:48 +00:00
},
onDragstart(e) {
e.dataTransfer.effectAllowed = 'move';
2018-02-26 21:25:17 +00:00
e.dataTransfer.setData('mk_drive_file', JSON.stringify(this.file));
2018-02-14 10:03:48 +00: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 10:03:48 +00:00
anime({
targets: this.$refs.thumbnail,
2018-03-29 05:48:47 +00:00
backgroundColor: `rgba(${this.file.properties.avgColor.join(',')}, 0)`,
2018-02-14 10:03:48 +00:00
duration: 100,
easing: 'linear'
});
}
2018-02-18 03:35:18 +00:00
},
rename() {
(this as any).apis.input({
2018-05-20 11:26:38 +00:00
title: '%i18n:@contextmenu.rename-file%',
placeholder: '%i18n:@contextmenu.input-new-file-name%',
2018-02-18 13:14:51 +00:00
default: this.file.name,
allowEmpty: false
2018-02-18 03:35:18 +00:00
}).then(name => {
(this as any).api('drive/files/update', {
2018-03-29 05:48:47 +00:00
fileId: this.file.id,
2018-02-18 03:35:18 +00:00
name: name
});
2018-02-18 03:35:18 +00:00
});
},
2018-07-19 17:40:37 +00:00
toggleSensitive() {
(this as any).api('drive/files/update', {
fileId: this.file.id,
isSensitive: !this.file.isSensitive
});
},
2018-02-18 03:35:18 +00:00
copyUrl() {
copyToClipboard(this.file.url);
(this as any).apis.dialog({
2018-04-14 16:04:40 +00:00
title: '%fa:check%%i18n:@contextmenu.copied%',
2018-05-20 11:26:38 +00:00
text: '%i18n:@contextmenu.copied-url-to-clipboard%',
2018-02-18 03:35:18 +00:00
actions: [{
2018-05-20 11:26:38 +00:00
text: '%i18n:common.ok%'
2018-02-18 03:35:18 +00:00
}]
});
},
setAsAvatar() {
(this as any).apis.updateAvatar(this.file);
},
setAsBanner() {
(this as any).apis.updateBanner(this.file);
},
addApp() {
alert('not implemented yet');
},
deleteFile() {
(this as any).api('drive/files/delete', {
fileId: this.file.id
});
2018-02-14 10:03:48 +00:00
}
}
});
</script>
<style lang="stylus" scoped>
2018-09-28 10:59:19 +00:00
.gvfdktuvdgwhmztnuekzkswkjygptfcv
2018-02-14 10:03:48 +00:00
padding 8px 0 0 0
height 180px
border-radius 4px
&, *
cursor pointer
&:hover
2018-04-28 23:51:17 +00:00
background rgba(#000, 0.05)
2018-02-14 10:03:48 +00:00
> .label
&:before
&:after
background #0b65a5
2018-08-18 18:56:44 +00:00
&.red
&:before
&:after
background #c12113
2018-02-14 10:03:48 +00:00
&:active
2018-04-28 23:51:17 +00:00
background rgba(#000, 0.1)
2018-02-14 10:03:48 +00:00
> .label
&:before
&:after
background #0b588c
2018-08-18 18:56:44 +00:00
&.red
&:before
&:after
background #ce2212
2018-02-14 10:03:48 +00:00
&[data-is-selected]
2018-09-26 11:19:35 +00:00
background var(--primary)
2018-02-14 10:03:48 +00:00
&:hover
2018-09-26 11:19:35 +00:00
background var(--primaryLighten10)
2018-02-14 10:03:48 +00:00
&:active
2018-09-26 11:19:35 +00:00
background var(--primaryDarken10)
2018-02-14 10:03:48 +00:00
> .label
&:before
&:after
display none
> .name
2018-09-26 11:19:35 +00:00
color var(--primaryForeground)
2018-02-14 10:03:48 +00:00
&[data-is-contextmenu-showing]
&:after
content ""
pointer-events none
position absolute
top -4px
right -4px
bottom -4px
left -4px
2018-09-26 11:19:35 +00:00
border 2px dashed var(--primaryAlpha03)
2018-02-14 10:03:48 +00:00
border-radius 4px
> .label
position absolute
top 0
left 0
pointer-events none
&:before
2018-08-18 18:56:44 +00:00
&:after
2018-02-14 10:03:48 +00:00
content ""
display block
position absolute
z-index 1
2018-08-18 18:56:44 +00:00
background #0c7ac9
&:before
2018-02-14 10:03:48 +00:00
top 0
left 57px
width 28px
height 8px
&:after
top 57px
left 0
width 8px
height 28px
2018-08-18 18:56:44 +00:00
&.red
&:before
&:after
background #c12113
2018-02-14 10:03:48 +00: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 10:59:19 +00:00
color var(--text)
2018-02-14 10:03:48 +00:00
overflow hidden
> .ext
opacity 0.5
</style>