Newer
Older
<template>
<div class="mk-post-form">
<header>
<button class="cancel" @click="cancel">%fa:times%</button>
<div>
<span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span>
<button class="submit" :disabled="posting" @click="post">
<template v-if="reply">%i18n:@reply%</template>
<template v-else-if="renote">%i18n:@renote%</template>
<template v-else>%i18n:@submit%</template>
</button>
<div v-if="visibility == 'specified'" class="visibleUsers">
<span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
<a @click="addVisibleUser">+ユーザーを追加</a>
</div>
<textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:!@reply-placeholder%' : renote ? '%i18n:!@renote-placeholder%' : '%i18n:!@note-placeholder%'"></textarea>
<x-draggable class="files" :list="files" :options="{ animation: 150 }">
<div class="file" v-for="file in files" :key="file.id">
<div class="img" :style="`background-image: url(${file.url}?thumbnail&size=128)`" @click="detachMedia(file)"></div>
</div>
</x-draggable>
<mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/>
<footer>
<button class="upload" @click="chooseFile">%fa:upload%</button>
<button class="drive" @click="chooseFileFromDrive">%fa:cloud%</button>
<button class="kao" @click="kao">%fa:R smile%</button>
<button class="poll" @click="poll = true">%fa:chart-pie%</button>
<button class="poll" @click="useCw = !useCw">%fa:eye-slash%</button>
<button class="geo" @click="geo ? removeGeo() : setGeo()">%fa:map-marker-alt%</button>
<button class="visibility" @click="setVisibility" ref="visibilityButton">%fa:lock%</button>
</footer>
<input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/>
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
data() {
return {
posting: false,
text: '',
uploadings: [],
files: [],
if (this.reply && this.reply.user.host != null) {
this.text = `@${this.reply.user.username}@${this.reply.user.host} `;
}
chooseFileFromDrive() {
(this as any).apis.chooseDriveFile({
multiple: true
}).then(files => {
files.forEach(this.attachMedia);
});
},
attachMedia(driveFile) {
this.files.push(driveFile);
this.$emit('change-attached-media', this.files);
},
detachMedia(file) {
this.files = this.files.filter(x => x.id != file.id);
onChangeFile() {
Array.from((this.$refs.file as any).files).forEach(this.upload);
},
onChangeUploadings(uploads) {
this.$emit('change-uploadings', uploads);
},
setGeo() {
if (navigator.geolocation == null) {
alert('お使いの端末は位置情報に対応していません');
return;
}
navigator.geolocation.getCurrentPosition(pos => {
this.geo = pos.coords;
}, err => {
alert('エラー: ' + err.message);
}, {
enableHighAccuracy: true
});
},
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
setVisibility() {
const w = (this as any).os.new(MkVisibilityChooser, {
source: this.$refs.visibilityButton,
compact: true,
v: this.visibility
});
w.$once('chosen', v => {
this.visibility = v;
});
},
addVisibleUser() {
(this as any).apis.input({
title: 'ユーザー名を入力してください'
}).then(username => {
(this as any).api('users/show', {
username
}).then(user => {
this.visibleUsers.push(user);
});
});
},
removeVisibleUser(user) {
this.visibleUsers = this.visibleUsers.filter(u => u != user);
},
clear() {
this.text = '';
this.files = [];
this.poll = false;
this.$emit('change-attached-media');
},
const viaMobile = (this as any).clientSettings.disableViaMobile !== true;
mediaIds: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
replyId: this.reply ? this.reply.id : undefined,
altitude: this.geo.altitude,
accuracy: this.geo.accuracy,
altitudeAccuracy: this.geo.altitudeAccuracy,
heading: isNaN(this.geo.heading) ? null : this.geo.heading,
speed: this.geo.speed,
} : null,
visibility: this.visibility,
visibleUserIds: this.visibility == 'specified' ? this.visibleUsers.map(u => u.id) : undefined,
this.$destroy();
}).catch(err => {
this.posting = false;
});
},
@media (min-width 500px)
margin 16px auto
width calc(100% - 32px)
color $theme-color-foreground
background $theme-color
border-radius 4px
&:disabled
opacity 0.7
> .form
max-width 500px
margin 0 auto
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
> .visibleUsers
margin-bottom 8px
font-size 14px
> span
margin-right 16px
color isDark ? #fff : #666
> input
z-index 1
> input
> textarea
display block
padding 12px
margin 0
width 100%
font-size 16px
color isDark ? #fff : #333
background isDark ? #191d23 : #fff
border none
border-radius 0
box-shadow 0 1px 0 0 isDark ? rgba(#000, 0.2) : rgba(#000, 0.1)
&:disabled
opacity 0.5
> textarea
max-width 100%
min-width 100%
min-height 80px
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
> .attaches
> .files
display block
margin 0
padding 4px
list-style none
&:after
content ""
display block
clear both
> .file
display block
float left
margin 0
padding 0
border solid 4px transparent
> .img
width 64px
height 64px
background-size cover
background-position center center
> footer
white-space nowrap
overflow auto
-webkit-overflow-scrolling touch
overflow-scrolling touch
> *
display inline-block
padding 0
margin 0
width 48px
height 48px
font-size 20px
color #657786
background transparent
outline none
border none
border-radius 0
box-shadow none
.mk-post-form[data-darkmode]
root(true)
.mk-post-form:not([data-darkmode])
root(false)