diff options
| author | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-14 20:58:48 +0900 |
|---|---|---|
| committer | こぴなたみぽ <syuilotan@yahoo.co.jp> | 2018-02-14 20:58:48 +0900 |
| commit | 484d5c0622bc39546d9dabfb5208c3fd76111ac4 (patch) | |
| tree | a049113423f738be34f36ee160f4199ccc6cd9d3 /src/web/app/common/views | |
| parent | wip (diff) | |
| download | misskey-484d5c0622bc39546d9dabfb5208c3fd76111ac4.tar.gz misskey-484d5c0622bc39546d9dabfb5208c3fd76111ac4.tar.bz2 misskey-484d5c0622bc39546d9dabfb5208c3fd76111ac4.zip | |
wip
Diffstat (limited to 'src/web/app/common/views')
| -rw-r--r-- | src/web/app/common/views/components/uploader.vue | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/web/app/common/views/components/uploader.vue b/src/web/app/common/views/components/uploader.vue new file mode 100644 index 0000000000..1239bec55f --- /dev/null +++ b/src/web/app/common/views/components/uploader.vue @@ -0,0 +1,207 @@ +<template> +<div class="mk-uploader"> + <ol v-if="uploads.length > 0"> + <li v-for="ctx in uploads" :key="ctx.id"> + <div class="img" :style="{ backgroundImage: `url(${ ctx.img })` }"></div> + <p class="name">%fa:spinner .pulse%{{ ctx.name }}</p> + <p class="status"> + <span class="initing" v-if="ctx.progress == undefined">%i18n:common.tags.mk-uploader.waiting%<mk-ellipsis/></span> + <span class="kb" v-if="ctx.progress != undefined">{{ String(Math.floor(ctx.progress.value / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }}<i>KB</i> / {{ String(Math.floor(ctx.progress.max / 1024)).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') }<i>KB</i></span> + <span class="percentage" v-if="ctx.progress != undefined">{{ Math.floor((ctx.progress.value / ctx.progress.max) * 100) }}</span> + </p> + <progress v-if="ctx.progress != undefined && ctx.progress.value != ctx.progress.max" :value="ctx.progress.value" :max="ctx.progress.max"></progress> + <div class="progress initing" v-if="ctx.progress == undefined"></div> + <div class="progress waiting" v-if="ctx.progress != undefined && ctx.progress.value == ctx.progress.max"></div> + </li> + </ol> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +export default Vue.extend({ + data() { + return { + uploads: [] + }; + }, + methods: { + upload(file, folder) { + if (folder && typeof folder == 'object') folder = folder.id; + + const id = Math.random(); + + const ctx = { + id: id, + name: file.name || 'untitled', + progress: undefined + }; + + this.uploads.push(ctx); + this.$emit('change', this.uploads); + + const reader = new FileReader(); + reader.onload = e => { + ctx.img = e.target.result; + }; + reader.readAsDataURL(file); + + const data = new FormData(); + data.append('i', this.$root.$data.os.i.token); + data.append('file', file); + + if (folder) data.append('folder_id', folder); + + const xhr = new XMLHttpRequest(); + xhr.open('POST', _API_URL_ + '/drive/files/create', true); + xhr.onload = e => { + const driveFile = JSON.parse(e.target.response); + + this.$emit('uploaded', driveFile); + + this.uploads = this.uploads.filter(x => x.id != id); + this.$emit('change', this.uploads); + }; + + xhr.upload.onprogress = e => { + if (e.lengthComputable) { + if (ctx.progress == undefined) ctx.progress = {}; + ctx.progress.max = e.total; + ctx.progress.value = e.loaded; + } + }; + + xhr.send(data); + } + } +}); +</script> + +<style lang="stylus" scoped> +.mk-uploader + overflow auto + + &:empty + display none + + > ol + display block + margin 0 + padding 0 + list-style none + + > li + display block + margin 8px 0 0 0 + padding 0 + height 36px + box-shadow 0 -1px 0 rgba($theme-color, 0.1) + border-top solid 8px transparent + + &:first-child + margin 0 + box-shadow none + border-top none + + > .img + display block + position absolute + top 0 + left 0 + width 36px + height 36px + background-size cover + background-position center center + + > .name + display block + position absolute + top 0 + left 44px + margin 0 + padding 0 + max-width 256px + font-size 0.8em + color rgba($theme-color, 0.7) + white-space nowrap + text-overflow ellipsis + overflow hidden + + > [data-fa] + margin-right 4px + + > .status + display block + position absolute + top 0 + right 0 + margin 0 + padding 0 + font-size 0.8em + + > .initing + color rgba($theme-color, 0.5) + + > .kb + color rgba($theme-color, 0.5) + + > .percentage + display inline-block + width 48px + text-align right + + color rgba($theme-color, 0.7) + + &:after + content '%' + + > progress + display block + position absolute + bottom 0 + right 0 + margin 0 + width calc(100% - 44px) + height 8px + background transparent + border none + border-radius 4px + overflow hidden + + &::-webkit-progress-value + background $theme-color + + &::-webkit-progress-bar + background rgba($theme-color, 0.1) + + > .progress + display block + position absolute + bottom 0 + right 0 + margin 0 + width calc(100% - 44px) + height 8px + border none + border-radius 4px + background linear-gradient( + 45deg, + lighten($theme-color, 30%) 25%, + $theme-color 25%, + $theme-color 50%, + lighten($theme-color, 30%) 50%, + lighten($theme-color, 30%) 75%, + $theme-color 75%, + $theme-color + ) + background-size 32px 32px + animation bg 1.5s linear infinite + + &.initing + opacity 0.3 + + @keyframes bg + from {background-position: 0 0;} + to {background-position: -64px 32px;} + +</style> |