So much has happend. A lot of cleanup, now popover gets the full album list and can iterate over it manually. We have a store. Images on upload have popover and are previewed under upload button.

This commit is contained in:
2019-02-20 21:46:06 +01:00
parent 0bcf2e92f5
commit 73f51f43bd
21 changed files with 435 additions and 453 deletions

View File

@@ -1,28 +1,26 @@
<template>
<div id="app" class="container">
<router-view />
<Popover class="popup" v-if="popoverState"></Popover>
</div>
</template>
<script>
import Vue from 'vue'
import Home from '@/components/Home.vue'
import routes from '@/routes'
import Vue from 'vue'
import Popover from '@/components/Popover'
import routes from '@/routes'
import { mapGetters, mapActions } from 'vuex'
export default {
name: 'App',
components: {
Home
},
data() {
return {
loaded: false
}
},
methods: {
}
}
export default {
name: 'App',
components: { Popover },
computed: mapGetters([
'popoverState',
]),
}
</script>
<style lang="scss">

View File

@@ -31,11 +31,8 @@
<textarea v-model="subtext"></textarea>
</div>
<div class="form-item">
<label class="title">last opp bilder</label>
<input id="file-upload" type="file" @change="processFile" multiple>
{{ files.length }}
</div>
<form-element-upload @newFiles="setFiles"></form-element-upload>
<div>
<button class="button" type="submit">Legg til</button>
@@ -57,10 +54,12 @@
import axios from 'axios'
import ClickOutside from 'vue-click-outside'
import FormElementLocation from './form/FormElementLocation'
import FormElementUpload from './form/FormElementUpload'
export default {
components: {
FormElementLocation
FormElementLocation,
FormElementUpload
},
data() {
return {
@@ -68,8 +67,8 @@ export default {
dateStart: '',
dateEnd: '',
chosenLocation: undefined,
chosenFiles: undefined,
subtext: '',
files: [],
}
},
computed: {
@@ -81,10 +80,13 @@ export default {
}
},
methods: {
setLocation(inputLocation) {
setLocation(location) {
console.log('detected location changed')
console.log('inputLocation', inputLocation)
this.chosenLocation = inputLocation;
console.log('inputLocation', location)
this.chosenLocation = location;
},
setFiles(files) {
this.chosenFiles = files;
},
processForm: function() {
let data = {
@@ -111,177 +113,12 @@ export default {
.then((resp) => console.log('response from posting to server:', resp))
.catch((error) => console.error('error from post request:', error))
},
processFile(event) {
this.files = event.target.files;
console.log('files', this.files)
},
}
}
</script>
<style lang="scss" scoped>
.form {
box-shadow: rgba(128, 128, 128, 0) 0px 0px 0px 1px inset;
clear: both;
color: rgba(0, 0, 0, 0.701961);
letter-spacing: normal;
line-height: 22.399999618530273px;
outline-color: rgba(0, 0, 0, 0.701961);
outline-style: none;
outline-width: 0px;
padding: 0px 15px 17px;
position: relative;
transition-delay: 0s;
transition-duration: 0.2s;
transition-property: box-shadow;
transition-timing-function: ease-in-out;
&-item {
border-width: 0px;
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
line-height: 17px;
margin: 0 0 1rem -12px;
min-width: min-content;
padding: 0px;
& .title {
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
font-style: normal;
font-weight: 300;
height: 17px;
letter-spacing: normal;
line-height: 17px;
}
& .field {
display: block;
float: left;
// margin-bottom: 24px;
position: relative;
width: 290.9375px;
@media screen and (max-width: 650px) {
max-width: 40vw;
min-width: 120px;
}
&:last-of-type {
margin-left: 11px;
}
& .caption {
cursor: pointer;
display: inline;
font-family: 'Proxima Nova';
font-size: 12px;
font-style: normal;
font-weight: 300;
height: auto;
letter-spacing: normal;
line-height: 14px;
}
}
}
& input {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
background-color: rgb(250, 250, 250);
border: 1px solid rgb(204, 204, 204);
border-radius: 3px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
box-sizing: border-box;
cursor: auto;
display: inline-block;
height: 42px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
line-height: 16px;
margin: 6px 0 4px;
padding: 12px;
width: 100%;
}
& textarea {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
border-color: rgb(204, 204, 204);
border-left-radius: 2px;
border-right-radius: 2px;
border-style: solid;
border-width: 1px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
box-sizing: border-box;
line-height: 14px;
margin: 6px 0px 4px;
min-height: 100px;
overflow-x: auto;
overflow-y: auto;
padding: 12px;
resize: vertical;
text-align: start;
text-indent: 0px;
text-shadow: none;
text-transform: none;
vertical-align: top;
white-space: pre-wrap;
width: 100%;
word-spacing: 0px;
word-wrap: break-word;
writing-mode: horizontal-tb;
}
}
.field-autocompleted {
width: calc(100% - 1.26rem);
position: absolute;
padding: 0;
margin: 0;
margin-top: -6px;
background-color: white;
li {
list-style: none;
height: 2.3rem;
line-height: 2.3rem;
padding-left: 0.5rem;
white-space: nowrap;
overflow: hidden;
&:hover {
background-color: #e6e6e6;
cursor: pointer;
}
}
border-color: rgb(204, 204, 204);
border-radius: 2px;
border-style: solid;
border-width: 1px;
}
.button {

View File

@@ -2,7 +2,7 @@
<div class="gallery-container">
<div v-for="(item, key) in gallery">
<gallery-image v-if="item.type === 'image'" :image="item" @click="imageSelected"></gallery-image>
<gallery-image v-if="item.type === 'image'" :image="item" :index="key" @click="imageSelected"></gallery-image>
<gallery-text v-if="item.type === 'text'" :text="item"></gallery-text>
</div>
</div>
@@ -12,6 +12,9 @@
import GalleryImage from '@/components/GalleryImage'
import GalleryText from '@/components/GalleryText'
import { mapGetters } from 'vuex'
import store from '@/store'
export default {
name: 'Gallery-Item',
components: { GalleryImage, GalleryText },
@@ -64,12 +67,20 @@ export default {
}
},
created() {
eventHub.$on('iteratePopoverImage', this.iteratePopoverImage)
this.setPopoverAlbum(this.gallery)
},
methods: {
watch: {
gallery: function (val) {
this.setPopoverAlbum(val)
}
},
methods: {
setPopoverAlbum: (album) => store.dispatch('setPopoverAlbum', album),
imageSelected(image) {
console.log('selected image', image)
this.selected = image;
console.log(this.selected.name)
// store.dispatch('incrementPopoverImage', this.selectedIndexInGallery())
},
selectedIndexInGallery() {
const gallery = this.gallery;
@@ -82,20 +93,6 @@ export default {
}
return -1;
},
iteratePopoverImage(direction) {
let i = this.selectedIndexInGallery() + direction;
// Overflow handler
if (i >= this.gallery.length) {
i = 0;
} else if (i == -1) {
i = this.gallery.length - 1;
}
let image = this.gallery[i];
eventHub.$emit('openPopover', image);
this.selected = image;
}
}
}
</script>

View File

@@ -1,31 +1,31 @@
<template>
<div>
<img :src="image.url" @click="popOver(image)"/>
{{ index }}
<img :src="image.url" @click="popover(image)"/>
<p>{{ image.name }}</p>
</div>
</template>
<script>
import store from '@/store'
export default {
components: {
},
props: {
image: {
type: Object,
required: true
},
index: {
type: Number,
}
},
data() {
return {
}
},
created() {},
beforeMount() {},
methods: {
popOver(image) {
eventHub.$emit('openPopover', image);
showPopover: () => store.dispatch('showPopover'),
setPopoverAlbumIndex: (index) => store.dispatch('setPopoverAlbumIndex', index),
popover(image) {
this.setPopoverAlbumIndex(this.index)
this.showPopover()
this.$emit('click', image)
}
}

View File

@@ -6,10 +6,6 @@
{{ date }} -->
<!-- <Header></Header> -->
<Popover class="popup" v-if="popoverShow" :image="popoverImage"></Popover>
<div class="container">
<h1 class="header">leifs opplevelser</h1>
<event-page style="height: 100%; overflow: auto;"></event-page>
@@ -18,42 +14,37 @@
</template>
<script>
import Header from '@/components/Header'
import EventPage from '@/components/EventPage'
import Popover from '@/components/Popover'
import Header from '@/components/Header'
import EventPage from '@/components/EventPage'
export default {
components: { Header, EventPage, Popover },
data() {
return {
title: 'Leifs opplevelser',
date: undefined,
bool: false,
popoverImage: undefined,
popoverShow: false
}
},
created() {
this.date = new Date();
eventHub.$on('openPopover', this.openPopover)
eventHub.$on('closePopover', this.closePopover)
},
methods: {
openPopover(image) {
this.popoverImage = image;
this.popoverShow = true;
document.body.classList.add('disableScroll');
},
closePopover(image) {
this.popoverShow = false;
document.body.classList.remove('disableScroll');
},
navigate: function() {
console.log(this.$router)
this.$router.push('/edit');
}
export default {
components: { Header, EventPage },
data() {
return {
title: 'Leifs opplevelser',
date: undefined,
bool: false,
}
},
methods: {
// openPopover(url) {
// console.log('popover received with', url)
// this.popoverImage = url;
// this.popoverShow = true;
// document.body.classList.add('disableScroll');
// },
// closePopover(url) {
// this.popoverShow = false;
// document.body.classList.remove('disableScroll');
// },
navigate: function() {
console.log(this.$router)
this.$router.push('/edit');
}
}
}
</script>
<style language="scss" scoped>

View File

@@ -1,8 +1,8 @@
<template>
<div class="popover" @click="close" v-touch:swipe.left="backwards" v-touch:swipe.right="forwards">
<div class="popover" @click="hidePopover" v-touch:swipe.left="backwards" v-touch:swipe.right="forwards">
<div class="popover-content">
<div class="image-container">
<img :src="image.url" />
<img :src="album[index].url" />
<div class="other-elements">
<p>There is something here</p>
@@ -21,37 +21,31 @@
</template>
<script>
import { mapGetters } from 'vuex'
import store from '@/store'
export default {
components: {
},
props: {
image: {
type: Object,
required: true,
}
computed: {
album: () => store.getters.popoverAlbum,
index: () => store.getters.popoverAlbumIndex,
},
created() {
window.addEventListener('keyup', this.arrowNavigation)
},
methods: {
forwards() {
eventHub.$emit('iteratePopoverImage', 1)
},
backwards() {
eventHub.$emit('iteratePopoverImage', -1)
},
hidePopover: () => store.dispatch('hidePopover'),
forwards: () => store.dispatch('incrementPopoverImage'),
backwards: () => store.dispatch('decrementPopoverImage'),
arrowNavigation(event) {
if (event.key === 'ArrowLeft') {
this.backwards()
} else if (event.key === 'ArrowRight') {
this.forwards()
} else if (event.key === 'Escape') {
this.hidePopover()
}
},
close() {
eventHub.$emit('closePopover')
},
beforeDestroy() {
window.removeEventListener('keyup')
}

View File

@@ -141,139 +141,6 @@ export default {
</script>
<style lang="scss" scoped>
.form {
box-shadow: rgba(128, 128, 128, 0) 0px 0px 0px 1px inset;
clear: both;
color: rgba(0, 0, 0, 0.701961);
letter-spacing: normal;
line-height: 22.399999618530273px;
outline-color: rgba(0, 0, 0, 0.701961);
outline-style: none;
outline-width: 0px;
padding: 0px 15px 17px;
position: relative;
transition-delay: 0s;
transition-duration: 0.2s;
transition-property: box-shadow;
transition-timing-function: ease-in-out;
&-item {
border-width: 0px;
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
line-height: 17px;
margin: 0 0 1rem -12px;
min-width: min-content;
padding: 0px;
& .title {
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
font-style: normal;
font-weight: 300;
height: 17px;
letter-spacing: normal;
line-height: 17px;
}
& .field {
display: block;
float: left;
// margin-bottom: 24px;
position: relative;
width: 290.9375px;
@media screen and (max-width: 650px) {
max-width: 40vw;
min-width: 120px;
}
&:last-of-type {
margin-left: 11px;
}
& .caption {
cursor: pointer;
display: inline;
font-family: 'Proxima Nova';
font-size: 12px;
font-style: normal;
font-weight: 300;
height: auto;
letter-spacing: normal;
line-height: 14px;
}
}
}
& input {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
background-color: rgb(250, 250, 250);
border: 1px solid rgb(204, 204, 204);
border-radius: 3px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
box-sizing: border-box;
cursor: auto;
display: inline-block;
height: 42px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
line-height: 16px;
margin: 6px 0 4px;
padding: 12px;
width: 100%;
}
& textarea {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
border-color: rgb(204, 204, 204);
border-left-radius: 2px;
border-right-radius: 2px;
border-style: solid;
border-width: 1px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
box-sizing: border-box;
line-height: 14px;
margin: 6px 0px 4px;
min-height: 100px;
overflow-x: auto;
overflow-y: auto;
padding: 12px;
resize: vertical;
text-align: start;
text-indent: 0px;
text-shadow: none;
text-transform: none;
vertical-align: top;
white-space: pre-wrap;
width: 100%;
word-spacing: 0px;
word-wrap: break-word;
writing-mode: horizontal-tb;
}
}
.field-autocompleted {
width: calc(100% - 1.26rem);
@@ -307,36 +174,4 @@ export default {
}
}
.button {
-webkit-appearance: none;
-webkit-backface-visibility: none;
background-color: rgb(39, 39, 39);
border-color: rgb(39, 39, 39);
border-style: outset;
border-width: 0px;
border-radius: 3px;
color: rgb(255, 255, 255);
cursor: pointer;
font-size: 14px;
font-weight: 600;
height: 42px;
letter-spacing: 1px;
line-height: 14px;
margin-left: -10px;
padding: 0 1rem;
text-align: center;
text-decoration: none;
text-shadow: none;
text-transform: uppercase;
transition-delay: 0s;
transition-duration: 0.1s;
transition-property: opacity;
transition-timing-function: linear;
vertical-align: baseline;
white-space: pre;
writing-mode: horizontal-tb;
}
</style>

View File

@@ -0,0 +1,111 @@
<template>
<div class="form-item">
<label class="title">last opp bilder</label>
<input id="file-upload" type="file" @change="processFile" multiple>
<div class="previewWindow" v-if="files.length">
<p class="previewWindow--title">{{ files.length }} bilder lagt til</p>
<div class="previewWindow--image">
<img v-for="file in files" :src="file.url" @click="popOver(file)"/>
</div>
</div>
</div>
</template>
<script>
import store from '@/store'
export default {
data() {
return {
files: [],
previewFiles: []
}
},
watch: {
files() {
this.$emit('newFiles', this.files)
}
},
methods: {
setPopoverAlbum: (album) => store.dispatch('setPopoverAlbum', album),
setPopoverAlbumIndex: (index) => store.dispatch('setPopoverAlbumIndex', index),
showPopover: () => store.dispatch('showPopover'),
processFile(event) {
const files = event.target.files;
let album = []
for (var i = files.length - 1; i >= 0; i--) {
album.push({
url: URL.createObjectURL(files[i]),
index: i,
})
}
album.reverse()
this.setPopoverAlbum(album)
this.files = album;
},
popOver(image) {
console.log('popover called')
this.setPopoverAlbumIndex(image.index)
this.showPopover()
// EventBus.$emit('openPopover', image);
}
}
}
</script>
<style lang="scss" scoped>
.previewWindow {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
background-color: #fafafa;
border: 1px solid #cccccc;
border-radius: 3px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
-webkit-box-sizing: border-box;
box-sizing: border-box;
cursor: auto;
display: inline-block;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
line-height: 16px;
width: 100%;
margin-top: -6px;
border-top: unset;
border-top-left-radius: 0px;
border-top-right-radius: 0px;
&--title {
padding-left: 0.6rem;
padding-top: 0.8rem;
padding-bottom: 0.8rem;
margin-bottom: 0.8rem;
width: calc(100% - 0.6rem);
font-size: 1rem;
border-bottom: 1px solid #cccccc;
}
&--image {
width: 100%;
& img {
padding: 0.2rem;
width: calc(25% - 0.4rem);
height: auto;
}
vertical-align: middle;
// max-width: 250px;
}
}
</style>

View File

@@ -6,6 +6,7 @@ import router from './routes'
import axios from 'axios'
import BootstrapVue from 'bootstrap-vue'
import Vue2TouchEvents from 'vue2-touch-events'
import store from './store'
Vue.config.productionTip = false
@@ -16,6 +17,7 @@ new Vue({
el: '#app',
axios,
router,
store,
BootstrapVue,
components: { App },
template: '<App/>'

133
src/scss/form.scss Normal file
View File

@@ -0,0 +1,133 @@
.form {
box-shadow: rgba(128, 128, 128, 0) 0px 0px 0px 1px inset;
clear: both;
color: rgba(0, 0, 0, 0.701961);
letter-spacing: normal;
line-height: 22.399999618530273px;
outline-color: rgba(0, 0, 0, 0.701961);
outline-style: none;
outline-width: 0px;
padding: 0px 15px 17px;
position: relative;
transition-delay: 0s;
transition-duration: 0.2s;
transition-property: box-shadow;
transition-timing-function: ease-in-out;
&-item {
border-width: 0px;
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
line-height: 17px;
margin: 0 0 1rem -12px;
min-width: min-content;
padding: 0px;
& .title {
color: rgba(0, 0, 0, 0.701961);
display: block;
font-family: 'Proxima Nova';
font-size: 14px;
font-style: normal;
font-weight: 300;
height: 17px;
letter-spacing: normal;
line-height: 17px;
}
& .field {
display: block;
float: left;
// margin-bottom: 24px;
position: relative;
width: 290.9375px;
@media screen and (max-width: 650px) {
max-width: 40vw;
min-width: 120px;
}
&:last-of-type {
margin-left: 11px;
}
& .caption {
cursor: pointer;
display: inline;
font-family: 'Proxima Nova';
font-size: 12px;
font-style: normal;
font-weight: 300;
height: auto;
letter-spacing: normal;
line-height: 14px;
}
}
}
& input {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
background-color: rgb(250, 250, 250);
border: 1px solid rgb(204, 204, 204);
border-radius: 3px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
box-sizing: border-box;
cursor: auto;
display: inline-block;
height: 42px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
line-height: 16px;
margin: 6px 0 4px;
padding: 12px;
width: 100%;
}
& textarea {
-webkit-appearance: none;
-webkit-rtl-ordering: logical;
-webkit-user-select: text;
border-color: rgb(204, 204, 204);
border-left-radius: 2px;
border-right-radius: 2px;
border-style: solid;
border-width: 1px;
font-family: 'Proxima Nova';
letter-spacing: normal;
font-size: 14px;
box-sizing: border-box;
line-height: 14px;
margin: 6px 0px 4px;
min-height: 100px;
overflow-x: auto;
overflow-y: auto;
padding: 12px;
resize: vertical;
text-align: start;
text-indent: 0px;
text-shadow: none;
text-transform: none;
vertical-align: top;
white-space: pre-wrap;
width: 100%;
word-spacing: 0px;
word-wrap: break-word;
writing-mode: horizontal-tb;
}
}

View File

@@ -1,4 +1,5 @@
@import './typography.scss';
@import './form.scss';
// @import 'bootstrap/dist/css/bootstrap.css';
// @import 'bootstrap-vue/dist/bootstrap-vue.css';

77
src/store.js Normal file
View File

@@ -0,0 +1,77 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const state = {
popover: false,
popoverAlbum: [],
popoverAlbumIndex: 0,
}
const mutations = {
showPopover (state) {
state.popover = true;
},
hidePopover (state) {
state.popover = false;
},
setPopoverAlbum (state, album) {
state.popoverAlbum = album;
},
setPopoverAlbumIndex (state, index) {
state.popoverAlbumIndex = index;
},
incrementPopoverImage (state) {
let index = state.popoverAlbumIndex;
index++
console.log('Setting popover index:', index)
if (index > state.popoverAlbum.length - 1) {
index = 0;
}
state.popoverAlbumIndex = index;
},
decrementPopoverImage (state) {
let index = state.popoverAlbumIndex;
index--
console.log('Setting popover index:', index)
if (index < 0) {
index = state.popoverAlbum.length - 1;
}
state.popoverAlbumIndex = index;
}
}
const actions = {
showPopover: ({ commit }) => commit('showPopover'),
hidePopover: ({ commit }) => commit('hidePopover'),
setPopoverAlbum: ({ commit }, payload) => commit('setPopoverAlbum', payload),
setPopoverAlbumIndex: ({ commit }, payload) => commit('setPopoverAlbumIndex', payload),
incrementPopoverImage: ({ commit }) => commit('incrementPopoverImage'),
decrementPopoverImage: ({ commit }) => commit('decrementPopoverImage'),
}
const getters = {
popoverState: state => state.popover,
popoverAlbum: state => state.popoverAlbum,
popoverAlbumIndex: state => state.popoverAlbumIndex,
}
export default new Vuex.Store({
state,
getters,
actions,
mutations
})