change new folder and file permissions #190

progresses on sharing #192

Progresses on #192

Progresses on #192

Little API update

Build assets


Former-commit-id: 68e70132ea857eb65638c0496c030be1c181ed1c [formerly d67b74280b7f12c3e20de6abe31fcfc26e8f43ef] [formerly 8fe91e003c9616da23f0e673ad4bb89d792a41c8 [formerly 868434360592aa0280e0d631840750d53a564cd3]]
Former-commit-id: 7d22ff468e580601d0c3e0921734b587b92484f8 [formerly 55f9d830636f9bbf15e0453d1ee7de6ee5d5191e]
Former-commit-id: ad411a5979521dda9ea9683d86e4c8ae7b3c9e6f
This commit is contained in:
Henrique Dias
2017-08-11 09:33:47 +01:00
parent 25a86a9382
commit 8d715bb433
38 changed files with 736 additions and 67 deletions

View File

@@ -29,6 +29,7 @@
<!-- Menu that shows on listing AND mobile when there are files selected -->
<div id="file-selection" v-if="isMobile && req.kind === 'listing'">
<span v-if="selectedCount > 0">{{ selectedCount }} selected</span>
<share-button v-show="showRenameButton"></share-button>
<rename-button v-show="showRenameButton"></rename-button>
<copy-button v-show="showMoveButton"></copy-button>
<move-button v-show="showMoveButton"></move-button>
@@ -38,6 +39,7 @@
<!-- This buttons are shown on a dropdown on mobile phones -->
<div id="dropdown" :class="{ active: showMore }">
<div v-if="!isListing || !isMobile">
<share-button v-show="showRenameButton"></share-button>
<rename-button v-show="showRenameButton"></rename-button>
<copy-button v-show="showMoveButton"></copy-button>
<move-button v-show="showMoveButton"></move-button>
@@ -74,6 +76,7 @@ import SwitchButton from './buttons/SwitchView'
import MoveButton from './buttons/Move'
import CopyButton from './buttons/Copy'
import ScheduleButton from './buttons/Schedule'
import ShareButton from './buttons/Share'
import {mapGetters, mapState} from 'vuex'
import * as api from '@/utils/api'
import buttons from '@/utils/buttons'
@@ -84,6 +87,7 @@ export default {
Search,
InfoButton,
DeleteButton,
ShareButton,
RenameButton,
DownloadButton,
CopyButton,

View File

@@ -82,7 +82,7 @@
<script>
import { mapState } from 'vuex'
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'search',

View File

@@ -8,7 +8,7 @@
<script>
import {mapGetters, mapState} from 'vuex'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'download-button',

View File

@@ -0,0 +1,17 @@
<template>
<button @click="show" :aria-label="$t('buttons.share')" :title="$t('buttons.share')" class="action">
<i class="material-icons">share</i>
<span>{{ $t('buttons.share') }}</span>
</button>
</template>
<script>
export default {
name: 'share-button',
methods: {
show (event) {
this.$store.commit('showHover', 'share')
}
}
}
</script>

View File

@@ -11,7 +11,7 @@
<script>
import { mapState } from 'vuex'
import CodeMirror from '@/utils/codemirror'
import api from '@/utils/api'
import * as api from '@/utils/api'
import buttons from '@/utils/buttons'
export default {
@@ -129,7 +129,7 @@ export default {
api.put(this.$route.path, content, regenerate, this.schedule)
.then(() => {
buttons.done(button)
buttons.success(button)
this.$store.commit('setSchedule', '')
})
.catch(error => {

View File

@@ -91,7 +91,7 @@
import {mapState} from 'vuex'
import Item from './ListingItem'
import css from '@/utils/css'
import api from '@/utils/api'
import * as api from '@/utils/api'
import buttons from '@/utils/buttons'
export default {
@@ -325,7 +325,7 @@ export default {
Promise.all(promises)
.then(() => {
buttons.done('upload')
buttons.success('upload')
this.$store.commit('setReload', true)
})
.catch(error => {

View File

@@ -33,7 +33,7 @@
import { mapMutations, mapGetters, mapState } from 'vuex'
import filesize from 'filesize'
import moment from 'moment'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'item',

View File

@@ -38,7 +38,7 @@
<script>
import { mapState } from 'vuex'
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
import InfoButton from '@/components/buttons/Info'
import DeleteButton from '@/components/buttons/Delete'
import RenameButton from '@/components/buttons/Rename'

View File

@@ -21,7 +21,7 @@
<script>
import { mapState } from 'vuex'
import FileList from './FileList'
import api from '@/utils/api'
import * as api from '@/utils/api'
import buttons from '@/utils/buttons'
export default {
@@ -51,7 +51,7 @@ export default {
// Execute the promises.
api.copy(items)
.then(() => {
buttons.done('copy')
buttons.success('copy')
this.$router.push({ path: this.dest })
})
.catch(error => {

View File

@@ -17,7 +17,7 @@
<script>
import {mapGetters, mapMutations, mapState} from 'vuex'
import api from '@/utils/api'
import { remove } from '@/utils/api'
import url from '@/utils/url'
import buttons from '@/utils/buttons'
@@ -36,9 +36,9 @@ export default {
// If we are not on a listing, delete the current
// opened file.
if (this.req.kind !== 'listing') {
api.delete(this.$route.path)
remove(this.$route.path)
.then(() => {
buttons.done('delete')
buttons.success('delete')
this.$router.push({ path: url.removeLastDir(this.$route.path) + '/' })
})
.catch(error => {
@@ -59,12 +59,12 @@ export default {
let promises = []
for (let index of this.selected) {
promises.push(api.delete(this.req.items[index].url))
promises.push(remove(this.req.items[index].url))
}
Promise.all(promises)
.then(() => {
buttons.done('delete')
buttons.success('delete')
this.$store.commit('setReload', true)
})
.catch(error => {

View File

@@ -13,7 +13,7 @@
<script>
import {mapGetters, mapState} from 'vuex'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'download',

View File

@@ -19,7 +19,7 @@
<script>
import { mapState } from 'vuex'
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'file-list',

View File

@@ -34,7 +34,7 @@
import {mapState, mapGetters} from 'vuex'
import filesize from 'filesize'
import moment from 'moment'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'info',

View File

@@ -21,7 +21,7 @@
<script>
import { mapState } from 'vuex'
import FileList from './FileList'
import api from '@/utils/api'
import * as api from '@/utils/api'
import buttons from '@/utils/buttons'
export default {
@@ -51,7 +51,7 @@ export default {
// Execute the promises.
api.move(items)
.then(() => {
buttons.done('move')
buttons.success('move')
this.$router.push({ path: this.dest })
})
.catch(error => {

View File

@@ -18,7 +18,7 @@
<script>
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'new-dir',

View File

@@ -18,7 +18,7 @@
<script>
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'new-file',

View File

@@ -14,6 +14,7 @@
<replace v-else-if="showReplace"></replace>
<schedule v-else-if="show === 'schedule'"></schedule>
<new-archetype v-else-if="show === 'new-archetype'"></new-archetype>
<share v-else-if="show === 'share'"></share>
<div v-show="showOverlay" @click="resetPrompts" class="overlay"></div>
</div>
</template>
@@ -33,9 +34,10 @@ import NewDir from './NewDir'
import NewArchetype from './NewArchetype'
import Replace from './Replace'
import Schedule from './Schedule'
import Share from './Share'
import { mapState } from 'vuex'
import buttons from '@/utils/buttons'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'prompts',
@@ -50,6 +52,7 @@ export default {
Success,
Move,
Copy,
Share,
NewFile,
NewDir,
Help,

View File

@@ -20,7 +20,7 @@
<script>
import { mapState } from 'vuex'
import url from '@/utils/url'
import api from '@/utils/api'
import * as api from '@/utils/api'
export default {
name: 'rename',

View File

@@ -0,0 +1,153 @@
<template>
<div class="prompt" id="share">
<h3>{{ $t('buttons.share') }}</h3>
<p></p>
<ul>
<li v-if="!hasPermanent">
<a @click="getPermalink" :aria-label="$t('buttons.permalink')">{{ $t('buttons.permalink') }}</a>
</li>
<li v-for="link in links" :key="link.hash">
<a :href="buildLink(link.hash)" target="_blank">
<template v-if="link.expires">{{ humanTime(link.expireDate) }}</template>
<template v-else>{{ $t('permanent') }}</template>
</a>
<button class="action"
@click="deleteLink($event, link)"
:aria-label="$t('buttons.delete')"
:title="$t('buttons.delete')"><i class="material-icons">delete</i></button>
<button class="action copy"
:data-clipboard-text="buildLink(link.hash)"
:aria-label="$t('buttons.copyToClipboard')"
:title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button>
</li>
<li>
<input autofocus
type="number"
max="2147483647"
min="0"
@keyup.enter="submit"
v-model.trim="time">
<select v-model="unit" :aria-label="$t('time.unit')">
<option value="seconds">{{ $t('time.seconds') }}</option>
<option value="minutes">{{ $t('time.minutes') }}</option>
<option value="hours">{{ $t('time.hours') }}</option>
<option value="days">{{ $t('time.days') }}</option>
</select>
<button class="action"
@click="submit"
:aria-label="$t('buttons.create')"
:title="$t('buttons.create')"><i class="material-icons">add</i></button>
</li>
</ul>
<div>
<button class="cancel"
@click="$store.commit('closeHovers')"
:aria-label="$t('buttons.close')"
:title="$t('buttons.close')">{{ $t('buttons.close') }}</button>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import { getShare, deleteShare, share } from '@/utils/api'
import moment from 'moment'
import Clipboard from 'clipboard'
export default {
name: 'share',
data: function () {
return {
time: '',
unit: 'hours',
hasPermanent: false,
links: [],
clip: null
}
},
computed: {
...mapState([ 'baseURL', 'req', 'selected', 'selectedCount' ]),
url () {
// Get the current name of the file we are editing.
if (this.req.kind !== 'listing') {
return this.$route.path
}
if (this.selectedCount === 0 || this.selectedCount > 1) {
// This shouldn't happen.
return
}
return this.req.items[this.selected[0]].url
}
},
beforeMount () {
getShare(this.url)
.then(links => {
this.links = links
this.sort()
for (let link of this.links) {
if (!link.expires) {
this.hasPermanent = true
break
}
}
})
.catch(error => {
if (error === 404) return
this.showError(error)
})
},
mounted () {
this.clip = new Clipboard('.copy')
},
methods: {
...mapMutations([ 'showError' ]),
submit: function (event) {
if (!this.time) return
share(this.url, this.time, this.unit)
.then(result => { this.links.push(result); this.sort() })
.catch(error => { this.showError(error) })
},
getPermalink (event) {
share(this.url)
.then(result => {
this.links.push(result)
this.sort()
this.hasPermanent = true
})
.catch(error => { this.showError(error) })
},
deleteLink (event, link) {
event.preventDefault()
deleteShare(link.hash)
.then(() => {
if (!link.expires) this.hasPermanent = false
this.links = this.links.filter(item => item.hash !== link.hash)
})
.catch(error => { this.showError(error) })
},
humanTime (time) {
return moment(time).fromNow()
},
buildLink (hash) {
return `${window.location.origin}${this.baseURL}/share/${hash}`
},
sort () {
this.links = this.links.sort((a, b) => {
if (!a.expires) return -1
if (!b.expires) return 1
return new Date(a.expireDate) - new Date(b.expireDate)
})
}
}
}
</script>