diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-02-14 19:03:48 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-02-14 19:03:48 +0900 |
| commit | 9a722898d2a49b935c70f1b1c9dcff11e0464be3 (patch) | |
| tree | a08d9302e083c2b1d4a5cba69ff1bb2a4c41ae69 /src | |
| parent | wip (diff) | |
| download | misskey-9a722898d2a49b935c70f1b1c9dcff11e0464be3.tar.gz misskey-9a722898d2a49b935c70f1b1c9dcff11e0464be3.tar.bz2 misskey-9a722898d2a49b935c70f1b1c9dcff11e0464be3.zip | |
wip
Diffstat (limited to 'src')
| -rw-r--r-- | src/web/app/desktop/-tags/drive/file.tag | 217 | ||||
| -rw-r--r-- | src/web/app/desktop/-tags/drive/folder.tag | 202 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/drive-file.vue | 232 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/drive-folder.vue | 220 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/post-form-window.vue | 4 | ||||
| -rw-r--r-- | src/web/app/desktop/views/components/post-form.vue | 4 |
6 files changed, 457 insertions, 422 deletions
diff --git a/src/web/app/desktop/-tags/drive/file.tag b/src/web/app/desktop/-tags/drive/file.tag deleted file mode 100644 index 153a038f47..0000000000 --- a/src/web/app/desktop/-tags/drive/file.tag +++ /dev/null @@ -1,217 +0,0 @@ -<mk-drive-browser-file data-is-selected={ isSelected } data-is-contextmenu-showing={ isContextmenuShowing.toString() } @click="onclick" oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }> - <div class="label" v-if="I.avatar_id == file.id"><img src="/assets/label.svg"/> - <p>%i18n:desktop.tags.mk-drive-browser-file.avatar%</p> - </div> - <div class="label" v-if="I.banner_id == file.id"><img src="/assets/label.svg"/> - <p>%i18n:desktop.tags.mk-drive-browser-file.banner%</p> - </div> - <div class="thumbnail" ref="thumbnail" style="background-color:{ file.properties.average_color ? 'rgb(' + file.properties.average_color.join(',') + ')' : 'transparent' }"> - <img src={ file.url + '?thumbnail&size=128' } alt="" onload={ onload }/> - </div> - <p class="name"><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></p> - <style lang="stylus" scoped> - :scope - display block - padding 8px 0 0 0 - height 180px - border-radius 4px - - &, * - cursor pointer - - &:hover - background rgba(0, 0, 0, 0.05) - - > .label - &:before - &:after - background #0b65a5 - - &:active - background rgba(0, 0, 0, 0.1) - - > .label - &:before - &:after - background #0b588c - - &[data-is-selected] - background $theme-color - - &:hover - background lighten($theme-color, 10%) - - &:active - background darken($theme-color, 10%) - - > .label - &:before - &:after - display none - - > .name - color $theme-color-foreground - - &[data-is-contextmenu-showing='true'] - &:after - content "" - pointer-events none - position absolute - top -4px - right -4px - bottom -4px - left -4px - border 2px dashed rgba($theme-color, 0.3) - border-radius 4px - - > .label - position absolute - top 0 - left 0 - pointer-events none - - &:before - content "" - display block - position absolute - z-index 1 - top 0 - left 57px - width 28px - height 8px - background #0c7ac9 - - &:after - content "" - display block - position absolute - z-index 1 - top 57px - left 0 - width 8px - height 28px - background #0c7ac9 - - > 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 - color #444 - overflow hidden - - > .ext - opacity 0.5 - - </style> - <script lang="typescript"> - import * as anime from 'animejs'; - import bytesToSize from '../../../common/scripts/bytes-to-size'; - - this.mixin('i'); - - this.file = this.opts.file; - this.browser = this.parent; - this.title = `${this.file.name}\n${this.file.type} ${bytesToSize(this.file.datasize)}`; - this.isContextmenuShowing = false; - this.isSelected = this.browser.selectedFiles.some(f => f.id == this.file.id); - - this.browser.on('change-selection', selections => { - this.isSelected = selections.some(f => f.id == this.file.id); - this.update(); - }); - - this.onclick = () => { - this.browser.chooseFile(this.file); - }; - - this.oncontextmenu = e => { - e.preventDefault(); - e.stopImmediatePropagation(); - - this.update({ - isContextmenuShowing: true - }); - const ctx = riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-file-contextmenu')), { - browser: this.browser, - file: this.file - })[0]; - ctx.open({ - x: e.pageX - window.pageXOffset, - y: e.pageY - window.pageYOffset - }); - ctx.on('closed', () => { - this.update({ - isContextmenuShowing: false - }); - }); - return false; - }; - - this.ondragstart = e => { - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.setData('text', JSON.stringify({ - type: 'file', - id: this.file.id, - file: this.file - })); - this.isDragging = true; - - // 親ブラウザに対して、ドラッグが開始されたフラグを立てる - // (=あなたの子供が、ドラッグを開始しましたよ) - this.browser.isDragSource = true; - }; - - this.ondragend = e => { - this.isDragging = false; - this.browser.isDragSource = false; - }; - - this.onload = () => { - if (this.file.properties.average_color) { - anime({ - targets: this.$refs.thumbnail, - backgroundColor: `rgba(${this.file.properties.average_color.join(',')}, 0)`, - duration: 100, - easing: 'linear' - }); - } - }; - </script> -</mk-drive-browser-file> diff --git a/src/web/app/desktop/-tags/drive/folder.tag b/src/web/app/desktop/-tags/drive/folder.tag deleted file mode 100644 index ed16bfb0d7..0000000000 --- a/src/web/app/desktop/-tags/drive/folder.tag +++ /dev/null @@ -1,202 +0,0 @@ -<mk-drive-browser-folder data-is-contextmenu-showing={ isContextmenuShowing.toString() } data-draghover={ draghover.toString() } @click="onclick" onmouseover={ onmouseover } onmouseout={ onmouseout } ondragover={ ondragover } ondragenter={ ondragenter } ondragleave={ ondragleave } ondrop={ ondrop } oncontextmenu={ oncontextmenu } draggable="true" ondragstart={ ondragstart } ondragend={ ondragend } title={ title }> - <p class="name"><template v-if="hover">%fa:R folder-open .fw%</template><template v-if="!hover">%fa:R folder .fw%</template>{ folder.name }</p> - <style lang="stylus" scoped> - :scope - display block - padding 8px - height 64px - background lighten($theme-color, 95%) - border-radius 4px - - &, * - cursor pointer - - * - pointer-events none - - &:hover - background lighten($theme-color, 90%) - - &:active - background lighten($theme-color, 85%) - - &[data-is-contextmenu-showing='true'] - &[data-draghover='true'] - &:after - content "" - pointer-events none - position absolute - top -4px - right -4px - bottom -4px - left -4px - border 2px dashed rgba($theme-color, 0.3) - border-radius 4px - - &[data-draghover='true'] - background lighten($theme-color, 90%) - - > .name - margin 0 - font-size 0.9em - color darken($theme-color, 30%) - - > [data-fa] - margin-right 4px - margin-left 2px - text-align left - - </style> - <script lang="typescript"> - import dialog from '../../scripts/dialog'; - - this.mixin('api'); - - this.folder = this.opts.folder; - this.browser = this.parent; - - this.title = this.folder.name; - this.hover = false; - this.draghover = false; - this.isContextmenuShowing = false; - - this.onclick = () => { - this.browser.move(this.folder); - }; - - this.onmouseover = () => { - this.hover = true; - }; - - this.onmouseout = () => { - this.hover = false - }; - - this.ondragover = e => { - e.preventDefault(); - e.stopPropagation(); - - // 自分自身がドラッグされていない場合 - if (!this.isDragging) { - // ドラッグされてきたものがファイルだったら - if (e.dataTransfer.effectAllowed === 'all') { - e.dataTransfer.dropEffect = 'copy'; - } else { - e.dataTransfer.dropEffect = 'move'; - } - } else { - // 自分自身にはドロップさせない - e.dataTransfer.dropEffect = 'none'; - } - return false; - }; - - this.ondragenter = e => { - e.preventDefault(); - if (!this.isDragging) this.draghover = true; - }; - - this.ondragleave = () => { - this.draghover = false; - }; - - this.ondrop = e => { - e.preventDefault(); - e.stopPropagation(); - this.draghover = false; - - // ファイルだったら - if (e.dataTransfer.files.length > 0) { - Array.from(e.dataTransfer.files).forEach(file => { - this.browser.upload(file, this.folder); - }); - return false; - }; - - // データ取得 - const data = e.dataTransfer.getData('text'); - if (data == null) return false; - - // パース - // TODO: Validate JSON - const obj = JSON.parse(data); - - // (ドライブの)ファイルだったら - if (obj.type == 'file') { - const file = obj.id; - this.browser.removeFile(file); - this.api('drive/files/update', { - file_id: file, - folder_id: this.folder.id - }); - // (ドライブの)フォルダーだったら - } else if (obj.type == 'folder') { - const folder = obj.id; - // 移動先が自分自身ならreject - if (folder == this.folder.id) return false; - this.browser.removeFolder(folder); - this.api('drive/folders/update', { - folder_id: folder, - parent_id: this.folder.id - }).then(() => { - // something - }).catch(err => { - switch (err) { - case 'detected-circular-definition': - dialog('%fa:exclamation-triangle%%i18n:desktop.tags.mk-drive-browser-folder.unable-to-process%', - '%i18n:desktop.tags.mk-drive-browser-folder.circular-reference-detected%', [{ - text: '%i18n:common.ok%' - }]); - break; - default: - alert('%i18n:desktop.tags.mk-drive-browser-folder.unhandled-error% ' + err); - } - }); - } - - return false; - }; - - this.ondragstart = e => { - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.setData('text', JSON.stringify({ - type: 'folder', - id: this.folder.id - })); - this.isDragging = true; - - // 親ブラウザに対して、ドラッグが開始されたフラグを立てる - // (=あなたの子供が、ドラッグを開始しましたよ) - this.browser.isDragSource = true; - }; - - this.ondragend = e => { - this.isDragging = false; - this.browser.isDragSource = false; - }; - - this.oncontextmenu = e => { - e.preventDefault(); - e.stopImmediatePropagation(); - - this.update({ - isContextmenuShowing: true - }); - const ctx = riot.mount(document.body.appendChild(document.createElement('mk-drive-browser-folder-contextmenu')), { - browser: this.browser, - folder: this.folder - })[0]; - ctx.open({ - x: e.pageX - window.pageXOffset, - y: e.pageY - window.pageYOffset - }); - ctx.on('closed', () => { - this.update({ - isContextmenuShowing: false - }); - }); - - return false; - }; - </script> -</mk-drive-browser-folder> diff --git a/src/web/app/desktop/views/components/drive-file.vue b/src/web/app/desktop/views/components/drive-file.vue new file mode 100644 index 0000000000..cda561d31b --- /dev/null +++ b/src/web/app/desktop/views/components/drive-file.vue @@ -0,0 +1,232 @@ +<template> +<div class="mk-drive-file" + :data-is-selected="isSelected" + :data-is-contextmenu-showing="isContextmenuShowing" + @click="onClick" + @contextmenu.prevent.stop="onContextmenu" + draggable="true" + @dragstart="onDragstart" + @dragend="onDragend" + :title="title" +> + <div class="label" v-if="I.avatar_id == file.id"><img src="/assets/label.svg"/> + <p>%i18n:desktop.tags.mk-drive-browser-file.avatar%</p> + </div> + <div class="label" v-if="I.banner_id == file.id"><img src="/assets/label.svg"/> + <p>%i18n:desktop.tags.mk-drive-browser-file.banner%</p> + </div> + <div class="thumbnail" ref="thumbnail" style="background-color:{ file.properties.average_color ? 'rgb(' + file.properties.average_color.join(',') + ')' : 'transparent' }"> + <img src={ file.url + '?thumbnail&size=128' } alt="" @load="onThumbnailLoaded"/> + </div> + <p class="name"> + <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> + </p> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import * as anime from 'animejs'; +import bytesToSize from '../../../common/scripts/bytes-to-size'; + +export default Vue.extend({ + props: ['file', 'browser'], + data() { + return { + isContextmenuShowing: false, + isDragging: false + }; + }, + computed: { + isSelected(): boolean { + return this.browser.selectedFiles.some(f => f.id == this.file.id); + }, + title(): string { + return `${this.file.name}\n${this.file.type} ${bytesToSize(this.file.datasize)}`; + } + }, + methods: { + onClick() { + this.browser.chooseFile(this.file); + }, + + onContextmenu(e) { + this.isContextmenuShowing = true; + const ctx = new MkDriveFileContextmenu({ + parent: this, + propsData: { + browser: this.browser, + x: e.pageX - window.pageXOffset, + y: e.pageY - window.pageYOffset + } + }).$mount(); + ctx.$once('closed', () => { + this.isContextmenuShowing = false; + }); + document.body.appendChild(ctx.$el); + }, + + onDragstart(e) { + e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.setData('text', JSON.stringify({ + type: 'file', + id: this.file.id, + file: this.file + })); + this.isDragging = true; + + // 親ブラウザに対して、ドラッグが開始されたフラグを立てる + // (=あなたの子供が、ドラッグを開始しましたよ) + this.browser.isDragSource = true; + }, + + onDragend(e) { + this.isDragging = false; + this.browser.isDragSource = false; + }, + + onThumbnailLoaded() { + if (this.file.properties.average_color) { + anime({ + targets: this.$refs.thumbnail, + backgroundColor: `rgba(${this.file.properties.average_color.join(',')}, 0)`, + duration: 100, + easing: 'linear' + }); + } + } + } +}); +</script> + +<style lang="stylus" scoped> +.mk-drive-file + padding 8px 0 0 0 + height 180px + border-radius 4px + + &, * + cursor pointer + + &:hover + background rgba(0, 0, 0, 0.05) + + > .label + &:before + &:after + background #0b65a5 + + &:active + background rgba(0, 0, 0, 0.1) + + > .label + &:before + &:after + background #0b588c + + &[data-is-selected] + background $theme-color + + &:hover + background lighten($theme-color, 10%) + + &:active + background darken($theme-color, 10%) + + > .label + &:before + &:after + display none + + > .name + color $theme-color-foreground + + &[data-is-contextmenu-showing] + &:after + content "" + pointer-events none + position absolute + top -4px + right -4px + bottom -4px + left -4px + border 2px dashed rgba($theme-color, 0.3) + border-radius 4px + + > .label + position absolute + top 0 + left 0 + pointer-events none + + &:before + content "" + display block + position absolute + z-index 1 + top 0 + left 57px + width 28px + height 8px + background #0c7ac9 + + &:after + content "" + display block + position absolute + z-index 1 + top 57px + left 0 + width 8px + height 28px + background #0c7ac9 + + > 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 + color #444 + overflow hidden + + > .ext + opacity 0.5 + +</style> diff --git a/src/web/app/desktop/views/components/drive-folder.vue b/src/web/app/desktop/views/components/drive-folder.vue new file mode 100644 index 0000000000..e9e4f1de2c --- /dev/null +++ b/src/web/app/desktop/views/components/drive-folder.vue @@ -0,0 +1,220 @@ +<template> +<div class="mk-drive-folder" + :data-is-contextmenu-showing="isContextmenuShowing" + :data-draghover="draghover" + @click="onClick" + @mouseover="onMouseover" + @mouseout="onMouseout" + @dragover.prevent.stop="onDragover" + @dragenter.prevent="onDragenter" + @dragleave="onDragleave" + @drop.prevent.stop="onDrop" + @contextmenu.prevent.stop="onContextmenu" + draggable="true" + @dragstart="onDragstart" + @dragend="onDragend" + :title="title" +> + <p class="name"> + <template v-if="hover">%fa:R folder-open .fw%</template> + <template v-if="!hover">%fa:R folder .fw%</template> + {{ folder.name }} + </p> +</div> +</template> + +<script lang="ts"> +import Vue from 'vue'; +import dialog from '../../scripts/dialog'; + +export default Vue.extend({ + props: ['folder', 'browser'], + data() { + return { + hover: false, + draghover: false, + isDragging: false, + isContextmenuShowing: false + }; + }, + computed: { + title(): string { + return this.folder.name; + } + }, + methods: { + onClick() { + this.browser.move(this.folder); + }, + + onMouseover() { + this.hover = true; + }, + + onMouseout() { + this.hover = false + }, + + onDragover(e) { + // 自分自身がドラッグされていない場合 + if (!this.isDragging) { + // ドラッグされてきたものがファイルだったら + if (e.dataTransfer.effectAllowed === 'all') { + e.dataTransfer.dropEffect = 'copy'; + } else { + e.dataTransfer.dropEffect = 'move'; + } + } else { + // 自分自身にはドロップさせない + e.dataTransfer.dropEffect = 'none'; + } + return false; + }, + + onDragenter() { + if (!this.isDragging) this.draghover = true; + }, + + onDragleave() { + this.draghover = false; + }, + + onDrop(e) { + this.draghover = false; + + // ファイルだったら + if (e.dataTransfer.files.length > 0) { + Array.from(e.dataTransfer.files).forEach(file => { + this.browser.upload(file, this.folder); + }); + return false; + }; + + // データ取得 + const data = e.dataTransfer.getData('text'); + if (data == null) return false; + + // パース + // TODO: Validate JSON + const obj = JSON.parse(data); + + // (ドライブの)ファイルだったら + if (obj.type == 'file') { + const file = obj.id; + this.browser.removeFile(file); + this.$root.$data.os.api('drive/files/update', { + file_id: file, + folder_id: this.folder.id + }); + // (ドライブの)フォルダーだったら + } else if (obj.type == 'folder') { + const folder = obj.id; + // 移動先が自分自身ならreject + if (folder == this.folder.id) return false; + this.browser.removeFolder(folder); + this.$root.$data.os.api('drive/folders/update', { + folder_id: folder, + parent_id: this.folder.id + }).then(() => { + // something + }).catch(err => { + switch (err) { + case 'detected-circular-definition': + dialog('%fa:exclamation-triangle%%i18n:desktop.tags.mk-drive-browser-folder.unable-to-process%', + '%i18n:desktop.tags.mk-drive-browser-folder.circular-reference-detected%', [{ + text: '%i18n:common.ok%' + }]); + break; + default: + alert('%i18n:desktop.tags.mk-drive-browser-folder.unhandled-error% ' + err); + } + }); + } + + return false; + }, + + onDragstart(e) { + e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.setData('text', JSON.stringify({ + type: 'folder', + id: this.folder.id + })); + this.isDragging = true; + + // 親ブラウザに対して、ドラッグが開始されたフラグを立てる + // (=あなたの子供が、ドラッグを開始しましたよ) + this.browser.isDragSource = true; + }, + + onDragend() { + this.isDragging = false; + this.browser.isDragSource = false; + }, + + onContextmenu(e) { + this.isContextmenuShowing = true; + const ctx = new MkDriveFolderContextmenu({ + parent: this, + propsData: { + browser: this.browser, + x: e.pageX - window.pageXOffset, + y: e.pageY - window.pageYOffset + } + }).$mount(); + ctx.$once('closed', () => { + this.isContextmenuShowing = false; + }); + document.body.appendChild(ctx.$el); + return false; + } + } +}); +</script> + +<style lang="stylus" scoped> +.mk-drive-folder + padding 8px + height 64px + background lighten($theme-color, 95%) + border-radius 4px + + &, * + cursor pointer + + * + pointer-events none + + &:hover + background lighten($theme-color, 90%) + + &:active + background lighten($theme-color, 85%) + + &[data-is-contextmenu-showing] + &[data-draghover] + &:after + content "" + pointer-events none + position absolute + top -4px + right -4px + bottom -4px + left -4px + border 2px dashed rgba($theme-color, 0.3) + border-radius 4px + + &[data-draghover] + background lighten($theme-color, 90%) + + > .name + margin 0 + font-size 0.9em + color darken($theme-color, 30%) + + > [data-fa] + margin-right 4px + margin-left 2px + text-align left + +</style> diff --git a/src/web/app/desktop/views/components/post-form-window.vue b/src/web/app/desktop/views/components/post-form-window.vue index 90e694c922..39e89ca44b 100644 --- a/src/web/app/desktop/views/components/post-form-window.vue +++ b/src/web/app/desktop/views/components/post-form-window.vue @@ -29,7 +29,9 @@ export default Vue.extend({ }; }, mounted() { - (this.$refs.form as any).focus(); + Vue.nextTick(() => { + (this.$refs.form as any).focus(); + }); }, methods: { onChangeUploadings(media) { diff --git a/src/web/app/desktop/views/components/post-form.vue b/src/web/app/desktop/views/components/post-form.vue index 9efca5ddc8..c062c57e10 100644 --- a/src/web/app/desktop/views/components/post-form.vue +++ b/src/web/app/desktop/views/components/post-form.vue @@ -111,7 +111,7 @@ export default Vue.extend({ chooseFile() { (this.$refs.file as any).click(); }, - chooseFileFromDrive() { + chooseFileFromDrive() {/* const w = new MkDriveFileSelectorWindow({ propsData: { multiple: true @@ -122,7 +122,7 @@ export default Vue.extend({ w.$once('selected', files => { files.forEach(this.attachMedia); - }); + });*/ }, attachMedia(driveFile) { this.files.push(driveFile); |