Newer
Older
<textarea
v-model="text"
ref="textarea"
@keypress="onKeypress"
@paste="onPaste"
<div class="file" @click="file = null" v-if="file">{{ file.name }}</div>
<mk-uploader ref="uploader" @uploaded="onUploaded"/>
<button class="send" @click="send" :disabled="!canSend || sending" title="%i18n:@send%">
<template v-if="!sending">%fa:paper-plane%</template><template v-if="sending">%fa:spinner .spin%</template>
</button>
<button class="attach-from-local" @click="chooseFile" title="%i18n:@attach-from-local%">
<button class="attach-from-drive" @click="chooseFileFromDrive" title="%i18n:@attach-from-drive%">
export default Vue.extend({
props: ['user'],
data() {
return {
text: null,
},
canSend(): boolean {
return (this.text != null && this.text != '') || this.file != null;
}
},
watch: {
text() {
this.saveDraft();
},
file() {
this.saveDraft();
if (this.room.isBottom()) {
this.room.scrollToBottom();
}
// 書きかけの投稿を復元
const draft = JSON.parse(localStorage.getItem('message_drafts') || '{}')[this.draftId];
if (draft) {
this.text = draft.data.text;
this.file = draft.data.file;
}
methods: {
onPaste(e) {
const data = e.clipboardData;
const items = data.items;
if (items.length == 1) {
if (items[0].kind == 'file') {
this.upload(items[0].getAsFile());
}
} else {
if (items[0].kind == 'file') {
alert('メッセージに添付できるのはひとつのファイルのみです');
}
}
},
onDragover(e) {
const isFile = e.dataTransfer.items[0].kind == 'file';
const isDriveFile = e.dataTransfer.types[0] == 'mk_drive_file';
if (isFile || isDriveFile) {
e.preventDefault();
e.dataTransfer.dropEffect = e.dataTransfer.effectAllowed == 'all' ? 'copy' : 'move';
}
},
onDrop(e): void {
// ファイルだったら
if (e.dataTransfer.files.length == 1) {
this.upload(e.dataTransfer.files[0]);
return;
} else if (e.dataTransfer.files.length > 1) {
//#region ドライブのファイル
const driveFile = e.dataTransfer.getData('mk_drive_file');
if (driveFile != null && driveFile != '') {
this.file = JSON.parse(driveFile);
e.preventDefault();
},
onKeypress(e) {
if ((e.which == 10 || e.which == 13) && e.ctrlKey) {
this.send();
}
},
chooseFile() {
(this.$refs.file as any).click();
},
chooseFileFromDrive() {
(this as any).apis.chooseDriveFile({
multiple: false
}).then(file => {
this.file = file;
onChangeFile() {
this.upload((this.$refs.file as any).files[0]);
},
upload(file) {
(this.$refs.uploader as any).upload(file);
},
onUploaded(file) {
this.file = file;
}).then(message => {
this.clear();
}).catch(err => {
console.error(err);
}).then(() => {
this.sending = false;
});
},
clear() {
this.text = '';
this.deleteDraft();
},
saveDraft() {
const data = JSON.parse(localStorage.getItem('message_drafts') || '{}');
data[this.draftId] = {
data: {
text: this.text,
file: this.file
}
}
localStorage.setItem('message_drafts', JSON.stringify(data));
},
deleteDraft() {
const data = JSON.parse(localStorage.getItem('message_drafts') || '{}');
delete data[this.draftId];
localStorage.setItem('message_drafts', JSON.stringify(data));
},
> textarea
cursor auto
display block
width 100%
min-width 100%
max-width 100%
height 64px
margin 0
padding 8px
> .file
padding 8px
color #444
background #eee
cursor pointer
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
> .send
position absolute
bottom 0
right 0
margin 0
padding 10px 14px
font-size 1em
color #aaa
transition color 0.1s ease
&:hover
color $theme-color
&:active
color darken($theme-color, 10%)
transition color 0s ease
.files
display block
margin 0
padding 0 8px
list-style none
&:after
content ''
display block
clear both
> li
display block
float left
margin 4px
padding 0
width 64px
height 64px
background-color #eee
background-repeat no-repeat
background-position center center
background-size cover
cursor move
&:hover
> .remove
display block
> .remove
display none
position absolute
right -6px
top -6px
margin 0
padding 0
background transparent
outline none
border none
border-radius 0
box-shadow none
cursor pointer
.attach-from-local
.attach-from-drive
margin 0
padding 10px 14px
font-size 1em
font-weight normal
text-decoration none
color #aaa
transition color 0.1s ease
&:hover
color $theme-color
&:active
color darken($theme-color, 10%)
transition color 0s ease
input[type=file]
display none
.mk-messaging-form[data-darkmode]
root(true)
.mk-messaging-form:not([data-darkmode])
root(false)