Merge pull request #427 from h3poteto/iss-417

closes #417 Allow drop file to upload the media to mastodon
This commit is contained in:
AkiraFukushima 2018-07-05 22:24:40 +09:00 committed by GitHub
commit 99c6f7d0b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 33 deletions

View File

@ -4,7 +4,8 @@
v-loading="loading" v-loading="loading"
element-loading-text="Loading..." element-loading-text="Loading..."
element-loading-spinner="el-icon-loading" element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"> element-loading-background="rgba(0, 0, 0, 0.8)"
>
<side-menu></side-menu> <side-menu></side-menu>
<div :class="collapse ? 'page-narrow':'page'"> <div :class="collapse ? 'page-narrow':'page'">
<header class="header" style="-webkit-app-region: drag;"> <header class="header" style="-webkit-app-region: drag;">
@ -13,6 +14,7 @@
<contents></contents> <contents></contents>
</div> </div>
<modals></modals> <modals></modals>
<receive-drop v-show="droppableVisible"></receive-drop>
</div> </div>
</template> </template>
@ -23,10 +25,17 @@ import HeaderMenu from './TimelineSpace/HeaderMenu'
import Contents from './TimelineSpace/Contents' import Contents from './TimelineSpace/Contents'
import Modals from './TimelineSpace/Modals' import Modals from './TimelineSpace/Modals'
import Mousetrap from 'mousetrap' import Mousetrap from 'mousetrap'
import ReceiveDrop from './TimelineSpace/ReceiveDrop'
export default { export default {
name: 'timeline-space', name: 'timeline-space',
components: { SideMenu, HeaderMenu, Modals, Contents }, components: { SideMenu, HeaderMenu, Modals, Contents, ReceiveDrop },
data () {
return {
dropTarget: null,
droppableVisible: false
}
},
computed: { computed: {
...mapState({ ...mapState({
loading: state => state.TimelineSpace.loading, loading: state => state.TimelineSpace.loading,
@ -42,11 +51,19 @@ export default {
}) })
}, },
mounted () { mounted () {
window.addEventListener('dragenter', this.onDragEnter)
window.addEventListener('dragleave', this.onDragLeave)
window.addEventListener('dragover', this.onDragOver)
window.addEventListener('drop', this.handleDrop)
Mousetrap.bind(['command+t', 'ctrl+t'], () => { Mousetrap.bind(['command+t', 'ctrl+t'], () => {
this.$store.commit('TimelineSpace/Modals/Jump/changeModal', true) this.$store.commit('TimelineSpace/Modals/Jump/changeModal', true)
}) })
}, },
beforeDestroy () { beforeDestroy () {
window.removeEventListener('dragenter', this.onDragEnter)
window.removeEventListener('dragleave', this.onDragLeave)
window.removeEventListener('dragover', this.onDragOver)
window.removeEventListener('drop', this.handleDrop)
this.$store.dispatch('TimelineSpace/stopUserStreaming') this.$store.dispatch('TimelineSpace/stopUserStreaming')
this.$store.dispatch('TimelineSpace/stopLocalStreaming') this.$store.dispatch('TimelineSpace/stopLocalStreaming')
}, },
@ -103,6 +120,44 @@ export default {
}) })
}) })
this.$store.dispatch('TimelineSpace/startLocalStreaming', account) this.$store.dispatch('TimelineSpace/startLocalStreaming', account)
},
handleDrop (e) {
e.preventDefault()
e.stopPropagation()
this.droppableVisible = false
if (e.dataTransfer.files.item(0) === null || e.dataTransfer.files.item(0) === undefined) {
return false
}
const file = e.dataTransfer.files.item(0)
if (!file.type.includes('image') && !file.type.includes('video')) {
this.$message({
message: 'You can only attach images or videos',
type: 'error'
})
return false
}
this.$store.dispatch('TimelineSpace/Modals/NewToot/openModal')
this.$store.dispatch('TimelineSpace/Modals/NewToot/incrementMediaId')
this.$store.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file)
.catch(() => {
this.$message({
message: 'Could not attach the file',
type: 'error'
})
})
return false
},
onDragEnter (e) {
this.dropTarget = e.target
this.droppableVisible = true
},
onDragLeave (e) {
if (e.target === this.dropTarget) {
this.droppableVisible = false
}
},
onDragOver (e) {
e.preventDefault()
} }
} }
} }

View File

@ -21,7 +21,7 @@
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<div class="upload-image"> <div class="upload-image">
<el-button size="small" type="text" @click="selectImage"><icon name="camera"></icon></el-button> <el-button size="small" type="text" @click="selectImage"><icon name="camera"></icon></el-button>
<input name="image" type="file" class="image-input" ref="image" @change="onChangeImage" :key="attachedImageId"/> <input name="image" type="file" class="image-input" ref="image" @change="onChangeImage" :key="attachedMediaId"/>
</div> </div>
<div class="privacy"> <div class="privacy">
<el-dropdown trigger="click" @command="changeVisibility"> <el-dropdown trigger="click" @command="changeVisibility">
@ -60,7 +60,6 @@ export default {
name: 'new-toot', name: 'new-toot',
data () { data () {
return { return {
attachedImageId: 0,
showContentWarning: false showContentWarning: false
} }
}, },
@ -74,6 +73,7 @@ export default {
} }
}, },
attachedMedias: state => state.TimelineSpace.Modals.NewToot.attachedMedias, attachedMedias: state => state.TimelineSpace.Modals.NewToot.attachedMedias,
attachedMediaId: state => state.TimelineSpace.Modals.NewToot.attachedMediaId,
blockSubmit: state => state.TimelineSpace.Modals.NewToot.blockSubmit, blockSubmit: state => state.TimelineSpace.Modals.NewToot.blockSubmit,
visibility: state => state.TimelineSpace.Modals.NewToot.visibility, visibility: state => state.TimelineSpace.Modals.NewToot.visibility,
sensitive: state => state.TimelineSpace.Modals.NewToot.sensitive, sensitive: state => state.TimelineSpace.Modals.NewToot.sensitive,
@ -131,15 +131,9 @@ export default {
} }
} }
}, },
mounted () {
document.addEventListener('drop', this.onDrop)
},
destroyed () {
document.removeEventListener('drop', this.onDrop)
},
methods: { methods: {
close () { close () {
this.resetImage() this.$store.dispatch('TimelineSpace/Modals/NewToot/resetMediaId')
this.$store.dispatch('TimelineSpace/Modals/NewToot/closeModal') this.$store.dispatch('TimelineSpace/Modals/NewToot/closeModal')
}, },
toot () { toot () {
@ -217,7 +211,7 @@ export default {
this.updateImage(file) this.updateImage(file)
}, },
updateImage (file) { updateImage (file) {
this.resetImage() this.$store.dispatch('TimelineSpace/Modals/NewToot/incrementMediaId')
this.$store.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file) this.$store.dispatch('TimelineSpace/Modals/NewToot/uploadImage', file)
.catch(() => { .catch(() => {
this.$message({ this.$message({
@ -229,31 +223,11 @@ export default {
removeAttachment (media) { removeAttachment (media) {
this.$store.commit('TimelineSpace/Modals/NewToot/removeMedia', media) this.$store.commit('TimelineSpace/Modals/NewToot/removeMedia', media)
}, },
resetImage () {
++this.attachedImageId
},
changeVisibility (level) { changeVisibility (level) {
this.$store.commit('TimelineSpace/Modals/NewToot/changeVisibility', level) this.$store.commit('TimelineSpace/Modals/NewToot/changeVisibility', level)
}, },
changeSensitive () { changeSensitive () {
this.$store.commit('TimelineSpace/Modals/NewToot/changeSensitive', !this.sensitive) this.$store.commit('TimelineSpace/Modals/NewToot/changeSensitive', !this.sensitive)
},
onDrop (e) {
e.preventDefault()
e.stopPropagation()
if (e.dataTransfer.files.item(0) === null || e.dataTransfer.files.item(0) === undefined) {
return false
}
const file = e.dataTransfer.files.item(0)
if (!file.type.includes('image') && !file.type.includes('video')) {
this.$message({
message: 'You can only attach images or videos',
type: 'error'
})
return false
}
this.updateImage(file)
return false
} }
} }
} }

View File

@ -0,0 +1,48 @@
<template>
<div id="receive_drop">
<div class="drop-area">
<div class="drop-message">
<h1>Drop to Upload to Mastodon</h1>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'receive-drop'
}
</script>
<style lang="scss" scoped>
#receive_drop {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 4000;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
.drop-area {
width: 80%;
height: 80%;
border: 4px dotted #ffffff;
border-radius: 12px;
display: flex;
justify-content: center;
align-items: center;
.drop-message {
text-align: center;
h1 {
font-size: 42px;
}
}
}
}
</style>

View File

@ -11,7 +11,8 @@ const NewToot = {
attachedMedias: [], attachedMedias: [],
visibility: 'public', visibility: 'public',
sensitive: false, sensitive: false,
spoiler: '' spoiler: '',
attachedMediaId: 0
}, },
mutations: { mutations: {
changeModal (state, value) { changeModal (state, value) {
@ -43,6 +44,9 @@ const NewToot = {
}, },
updateSpoiler (state, value) { updateSpoiler (state, value) {
state.spoiler = value state.spoiler = value
},
updateMediaId (state, value) {
state.attachedMediaId = value
} }
}, },
actions: { actions: {
@ -105,6 +109,12 @@ const NewToot = {
console.error(err) console.error(err)
throw err throw err
}) })
},
incrementMediaId ({ commit, state }) {
commit('updateMediaId', state.attachedMediaId + 1)
},
resetMediaId ({ commit }) {
commit('updateMediaId', 0)
} }
} }
} }