Mobile interface :)

This commit is contained in:
Henrique Dias 2017-07-10 10:30:51 +01:00
parent cacca2e6f2
commit 1645a8830e
No known key found for this signature in database
GPG Key ID: 936F5EB68D786730
8 changed files with 206 additions and 57 deletions

View File

@ -1,16 +1,28 @@
<template>
<div v-if="error">
<not-found v-if="error === 404"></not-found>
<forbidden v-else-if="error === 403"></forbidden>
<internal-error v-else></internal-error>
</div>
<editor v-else-if="isEditor"></editor>
<listing :class="{ multiple }" v-else-if="isListing"></listing>
<preview v-else-if="isPreview"></preview>
<div v-else>
<h2 class="message">
<span>Loading...</span>
</h2>
<div>
<div id="breadcrumbs">
<router-link to="/files/">
<i class="material-icons">home</i>
</router-link>
<span v-for="link in breadcrumbs" :key="link.name">
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
<router-link :to="link.url">{{ link.name }}</router-link>
</span>
</div>
<div v-if="error">
<not-found v-if="error === 404"></not-found>
<forbidden v-else-if="error === 403"></forbidden>
<internal-error v-else></internal-error>
</div>
<editor v-else-if="isEditor"></editor>
<listing :class="{ multiple }" v-else-if="isListing"></listing>
<preview v-else-if="isPreview"></preview>
<div v-else>
<h2 class="message">
<span>Loading...</span>
</h2>
</div>
</div>
</template>
@ -53,6 +65,30 @@ export default {
},
isEditor () {
return this.req.kind === 'editor' && !this.loading
},
breadcrumbs () {
let parts = this.$route.path.split('/')
if (parts[0] === '') {
parts.shift()
}
if (parts[parts.length - 1] === '') {
parts.pop()
}
let breadcrumbs = []
for (let i = 0; i < parts.length; i++) {
if (i === 0) {
breadcrumbs.push({ name: parts[i], url: '/' + parts[i] + '/' })
} else {
breadcrumbs.push({ name: parts[i], url: breadcrumbs[i - 1].url + parts[i] + '/' })
}
}
breadcrumbs.shift()
return breadcrumbs
}
},
data: function () {

View File

@ -15,18 +15,38 @@
<button v-show="showSaveButton" aria-label="Save" class="action" id="save-button">
<i class="material-icons" title="Save">save</i>
</button>
<rename-button v-show="showRenameButton"></rename-button>
<move-button v-show="showMoveButton"></move-button>
<delete-button v-show="showDeleteButton"></delete-button>
<switch-button v-show="showSwitchButton"></switch-button>
<download-button v-show="showCommonButton"></download-button>
<upload-button v-show="showUpload"></upload-button>
<info-button v-show="showCommonButton"></info-button>
<button v-show="showSelectButton" @click="$store.commit('multiple', true)" aria-label="Select multiple" class="action">
<i class="material-icons">check_circle</i>
<span>Select</span>
<button @click="openMore" id="more" aria-label="More" title="More" class="action">
<i class="material-icons">more_vert</i>
</button>
<!-- 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>
<rename-button v-show="showRenameButton"></rename-button>
<move-button v-show="showMoveButton"></move-button>
<delete-button v-show="showDeleteButton"></delete-button>
</div>
<!-- This buttons are shown on a dropdown on mobile phones -->
<div id="dropdown" :class="{ active: showMore }">
<div v-if="!isListing || !isMobile">
<rename-button v-show="showRenameButton"></rename-button>
<move-button v-show="showMoveButton"></move-button>
<delete-button v-show="showDeleteButton"></delete-button>
</div>
<switch-button v-show="showSwitchButton"></switch-button>
<download-button v-show="showCommonButton"></download-button>
<upload-button v-show="showUpload"></upload-button>
<info-button v-show="showCommonButton"></info-button>
<button v-show="showSelectButton" @click="openSelect" aria-label="Select multiple" class="action">
<i class="material-icons">check_circle</i>
<span>Select</span>
</button>
</div>
<div v-show="showOverlay" @click="resetPrompts" class="overlay"></div>
</div>
</header>
</template>
@ -54,6 +74,16 @@ export default {
SwitchButton,
MoveButton
},
data: function () {
return {
width: window.innerWidth
}
},
created () {
window.addEventListener('resize', () => {
this.width = window.innerWidth
})
},
computed: {
...mapGetters([
'selectedCount'
@ -65,6 +95,12 @@ export default {
'reload',
'multiple'
]),
isMobile () {
return this.width <= 736
},
isListing () {
return this.req.kind === 'listing'
},
showSelectButton () {
return this.req.kind === 'listing' && !this.loading && this.$route.name === 'Files'
},
@ -121,14 +157,31 @@ export default {
}
return false
},
showMore () {
if (this.$route.name !== 'Files' || this.loading) return false
return (this.$store.state.show === 'more')
},
showOverlay () {
return (this.$store.state.show === 'more')
}
},
methods: {
openSidebar () {
this.$store.commit('showHover', 'sidebar')
},
openMore () {
this.$store.commit('showHover', 'more')
},
openSearch () {
this.$store.commit('showHover', 'search')
},
openSelect () {
this.$store.commit('multiple', true)
this.resetPrompts()
},
resetPrompts () {
this.$store.commit('closeHovers')
}
}
}

View File

@ -23,6 +23,13 @@ export default {
SiteHeader,
Prompts
},
watch: {
'$route': function () {
this.$store.commit('resetSelected')
this.$store.commit('multiple', false)
if (this.$store.state.show !== 'success') this.$store.commit('closeHovers')
}
},
mounted () {
this.updateCSS()
},

View File

@ -10,6 +10,9 @@ export default {
name: 'switch-button',
methods: {
change: function (event) {
// If we are on mobile we should close the dropdown.
this.$store.commit('closeHovers')
let display = 'mosaic'
if (this.$store.state.req.display === 'mosaic') {

View File

@ -55,7 +55,7 @@ export default {
showNewDir: function () { return this.show === 'newDir' },
showDownload: function () { return this.show === 'download' },
showOverlay: function () {
return (this.show !== null && this.show !== 'search')
return (this.show !== null && this.show !== 'search' && this.show !== 'more')
}
},
methods: {

View File

@ -116,3 +116,18 @@ main {
margin: 0 1em 1em auto;
width: calc(100% - 19em);
}
#breadcrumbs span,
#breadcrumbs {
display: flex;
align-items: center;
color: #6f6f6f;
}
#breadcrumbs .chevron {
}
#breadcrumbs a {
color: inherit
}

View File

@ -11,6 +11,11 @@ header {
display: flex;
}
header .overlay {
width: 0;
height: 0;
}
header a,
header a:hover {
color: inherit;
@ -45,6 +50,10 @@ header>div div {
position: relative;
}
header > div:last-child div {
display: flex;
}
header>div:first-child {
height: 4em;
}
@ -57,44 +66,10 @@ header .search-button {
display: none;
}
/* * * * * * * * * * * * * * * *
* MORE?? *
* * * * * * * * * * * * * * * */
#more {
display: none;
}
#file-only {
display: inline-block;
border-right: 1px solid rgba(0, 0, 0, 0.075);
padding-right: .3em;
margin-right: .3em;
transition: .2s ease opacity, visibility;
visibility: visible;
}
#file-only.disabled {
opacity: 0;
visibility: hidden;
}
#download ul.active {
top: 0;
right: 0;
}
#more ul.active {
right: .5em;
top: 4.5em;
}
/* * * * * * * * * * * * * * * *
* SEARCH BAR *
* * * * * * * * * * * * * * * */
#search {
position: relative;
height: 100%;

View File

@ -12,6 +12,66 @@
}
@media (max-width: 736px) {
#more {
display: inherit
}
header .overlay {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.1);
}
#dropdown {
position: fixed;
top: 1em;
right: 1em;
display: block;
background-color: #fff;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
transform: scale(0);
transition: .1s ease-in-out transform;
z-index: 99999;
}
#dropdown > div {
display: block;
}
#dropdown.active {
transform: scale(1);
}
#dropdown .action {
display: flex;
align-items: center;
border-radius: 0;
width: 100%;
}
#dropdown .action span:not(.counter) {
display: inline-block;
padding: .4em;
}
#dropdown .counter {
left: 2.25em;
}
#file-selection {
position: fixed;
bottom: 1em;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
background: #fff;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
width: 95%;
max-width: 16em;
}
#file-selection .action {
border-radius: 50%;
width: auto;
}
#file-selection > span {
display: inline-block;
margin-left: 1em;
color: #6f6f6f;
margin-right: auto;
}
nav {
top: 0;
z-index: 99999;