Commit 58c025bf authored by Adam Procter's avatar Adam Procter
Browse files

Merge branch 'connectPouchDB' into main

parents 31991a98 ee51e416
VUE_APP_COUCH_HTTP=http
VUE_APP_COUCH_USER=auto-admin
VUE_APP_COUCH_PASS=testing@
VUE_APP_COUCH_URL=localhost:5984/
\ No newline at end of file
......@@ -8,7 +8,10 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.9.1",
"core-js": "^3.10.0",
"freeze-dry": "^0.2.4",
"marked": "^2.0.1",
"pouchdb": "^7.2.2",
"vue": "^3.0.9",
"vue-router": "^4.0.5",
"vuex": "^4.0.0-0"
......
/// this is from Vue 2 // check and rebuild
<template>
<div>
<div v-for="(nodes, index) in $options.myArray" v-bind:key="index">
<form
class="nodes"
:style="{
backgroundColor: nodes.color,
}"
>
<template v-if="nodes.read_mode == false">
<textarea
@focus="editTrue(true)"
@blur="editTrue(false)"
v-model="nodes.node_text"
@input="editNode"
:id="nodes.node_id"
v-focus
ref="textentry"
placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
></textarea>
<p class="info">*markdown supported &amp; autosaves</p>
</template>
<template v-else>
<p
class="readmode"
:id="nodes.node_id"
:inner-html.prop="nodes.node_text | marked"
></p>
</template>
<div class="btn-row">
<SvgButton
buttonClass="nodes"
@click.prevent="deleteFlag(nodes.node_id), updateNodes()"
/>
<SvgButton2
buttonClass="nodes"
@click.prevent="
readFlag(nodes.node_id, nodes.read_mode), updateNodes()
"
/>
<v-swatches
v-model="color"
@input="chooseColor(color, nodes.node_id)"
:swatches="swatches"
:shapes="shapes"
show-border
show-fallback
fallback-input-type="color"
>
<SvgButton3 buttonClass="nodes" @click.prevent slot="trigger" />
</v-swatches>
</div>
<div class="allemoji">
<div
class="eachemoji"
v-for="(emojis, index) in configEmoji"
:key="index"
>
<template v-if="emojis.node_id == nodes.node_id">{{
emojis.emoji_text
}}</template>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import marked from 'marked'
import SvgButton from '@/components/SvgButton'
import SvgButton2 from '@/components/SvgButton2'
import SvgButton3 from '@/components/SvgButton3'
import VSwatches from 'vue-swatches'
import 'vue-swatches/dist/vue-swatches.css'
var readmode
export default {
name: 'ListLayer',
props: {
added: Boolean,
},
data: function () {
return {
color: '#9bc2d8',
shapes: 'circles',
// swatches: [{ color: '#F493A7', showBorder: true }],
swatches: [
['#EB5757', '#F2994A', '#F2C94C'],
['#219653', '#27AE60', '#6FCF97'],
['#2F80ED', '#2D9CDB', '#56CCF2'],
['#9B51E0', '#BB6BD9', '#E9B7FC'],
],
localreadmode: false,
myArray: null,
update: false,
}
},
filters: {
marked: marked,
},
computed: {
...mapState({
myNodes: (state) => state.myNodes,
configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
// toolmode: (state) => state.ui.mode,
}),
nodes_filtered: function () {
return this.myNodes.filter((nodes) => {
return nodes.deleted == false
})
},
},
mounted() {
setTimeout(this.loadData, 500)
const unwatch = this.$watch('nodes_filtered', (value) => {
this.$options.myArray = this.nodes_filtered
this.$forceUpdate()
// this.focusInput()
// ignore falsy values
if (!value) return
// stop watching when nodes_filtered[] is not empty
if (value && value.length) unwatch()
// process value here
})
},
watch: {
added: {
deep: true,
handler() {
setTimeout(this.loadData, 200)
},
},
update: {
deep: true,
handler() {
setTimeout(this.loadData, 200)
},
},
},
methods: {
chooseColor(color, nodeid) {
this.$store.dispatch('colorNode', { nodeid, color })
this.$options.myArray = this.nodes_filtered
},
updateNodes() {
this.update = !this.update
},
loadData() {
this.$options.myArray = this.nodes_filtered
this.$forceUpdate()
},
editNode(e) {
var nodeid = e.target.id
var nodetext = e.target.value
this.$store.dispatch('editNode', { nodeid, nodetext })
},
editTrue(e) {
this.$emit('edit-true', e)
},
deleteFlag(e) {
if (confirm('Confirm discard?')) {
this.$store.dispatch('deleteFlag', { e })
} else {
// nothing happens
}
},
readFlag(e, f) {
readmode = f
readmode = !readmode
this.$store.dispatch('readFlag', { e, readmode })
if (readmode == true) {
this.mode = 'Read'
} else {
this.mode = 'Edit'
}
},
},
components: {
SvgButton,
SvgButton2,
SvgButton3,
VSwatches,
},
}
</script>
<style lang="css" scoped>
.nodes {
width: 95%;
border: 2px dashed black;
background-color: rgb(155, 194, 216);
margin-top: 1em;
margin-left: 0.5em;
}
.readmode {
margin-top: 1em;
margin-left: 1em;
}
textarea {
width: 100%;
height: 175px;
resize: none;
box-sizing: border-box;
font-size: 18px;
font-family: 'Inter var', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
border: none;
outline: none;
background-color: rgb(187, 227, 255);
scrollbar-color: yellow rgb(187, 227, 255);
}
.btn-row {
position: relative;
margin-bottom: 5px;
display: flex;
justify-content: center;
flex-wrap: wrap;
padding: 0 15px;
border-radius: 4px;
}
.allemoji {
font-size: 2em;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(0, auto));
/* float: left; */
}
.eachemoji p {
margin: 0em;
}
@media only screen and (max-width: 600px) {
.readmode >>> a {
font-size: 2em;
word-break: break-all;
padding-right: 0.5em;
}
}
</style>
<template>
<form>
<span class="arrow">⬇⬇</span>
<h1>What shall we call you ? 👩‍🚀</h1>
<p>
First we need to connect this device to your ideas. This name is what
allows you to create and edit your nodes and this name can be anything you
like, this name is always anonymous.
like, this name is always anonymous. <strong>This is required.</strong>
</p>
<div class="breaker-one">
<label for="name">Your Name: {{ nameFormatted }}</label>
......@@ -14,13 +15,12 @@
v-model.trim="name"
type="text"
id="name"
autocomplete="name"
ref="name"
placeholder="type name here!"
autocorrect="off"
autocapitalize="none"
@keyup.enter="setName()"
required
/>
<button type="button" @click="setName()">Store</button>
</div>
<h2>Next start or join a <span class="long">microcosm !</span> 🚀</h2>
......@@ -31,19 +31,85 @@
</p>
<div class="breaker-two">
<label for="microcosm">Microcosm:</label>
<input
v-model.trim="microcosm"
ref="microcosm"
type="text"
id="microcosm"
autocomplete="microcosm"
placeholder="type microcosm name here!"
autocorrect="off"
autocapitalize="none"
@keyup.enter="setMicrocosm()"
/>
<button type="button" @click="setMicrocosm()">Start or Join</button>
<router-link to="/collect">
<button type="button" @click="setName(), setMicrocosm()">
Start or Join
</button>
</router-link>
<button class="configButton" type="button" @click="settings = !settings">
Change CouchDB Configuration
</button>
</div>
<template v-if="settings">
<h2>Configure your own <span class="long">CouchDB !</span> 👩‍🔧</h2>
<p>
CouchDB is what allows you to sync nodes (your ideas) between your team.
You need to have your own CouchDB set up. Otherwise leave this empty and
you will continue to use the default cloud instance of CouchDB.
</p>
<div class="breaker-three">
<label for="protocol"> Protocol:</label>
<input
v-model.trim="protocol"
type="text"
id="protocol"
placeholder="type protocol here"
autocorrect="off"
autocapitalize="none"
/>
<label for="protocol"> CouchDB username:</label>
<input
v-model.trim="username"
type="text"
id="username"
placeholder="type CouchDB username here"
autocorrect="off"
autocapitalize="none"
/>
<label for="protocol"> password:</label>
<input
v-model="password"
type="password"
id="password"
placeholder="type password here"
autocorrect="off"
autocapitalize="none"
/>
<label for="protocol"> URL:</label>
<input
v-model.trim="url"
type="text"
id="url"
autocomplete="url"
placeholder="type url here"
autocorrect="off"
autocapitalize="none"
/>
<button
type="button"
@click="configureRemote(protocol, username, password, url)"
>
Save
</button>
</div>
</template>
</form>
</template>
......@@ -51,20 +117,63 @@
export default {
name: 'JoinMicrocosm',
data: function() {
created() {
window.addEventListener('keypress', this.keyCommand)
},
unmounted() {
window.removeEventListener('keypress', this.keyCommand)
},
props: {
isStart: Boolean,
},
data: function () {
return {
// what you are calling yourself / device
name: '',
nameSet: false,
nameFormatted: '',
// Next dataset related to microcosm
microcosm: '',
microcosmSet: false,
microcosmFormatted: ''
microcosmFormatted: '',
settings: false,
protocol: '',
username: '',
password: '',
url: '',
}
},
watch: {
// this doesnt run as isStart is in v-if component
isStart: {
deep: true,
handler: function (newVal, oldVal) {
console.log('Prop changed: ', newVal, ' | was: ', oldVal)
this.$refs.name.focus()
},
},
},
methods: {
microcosmField() {
this.$refs.microcosm.focus()
},
keyCommand(e) {
if (
(e.keyCode == 13 && this.nameSet == false) ||
(e.keyCode == 9 && this.nameSet == false)
) {
console.log('tabb')
this.setName()
} else if (e.keyCode == 13) {
this.setMicrocosm()
}
},
setName() {
// format name so no spaces or dashes PouchDB/ CouchDB dont like them
var lowercasename = this.name.toLowerCase()
......@@ -72,13 +181,10 @@ export default {
this.nameFormatted = spacesremoved.split('-').join('')
this.nameSet = true
localStorage.setItem('nogg_name', this.nameFormatted)
// focus on next input field for speed
this.focusInput()
// now we sent this same data set to the store
// this.$store.dispatch('setName', this.nameFormatted),
},
setMicrocosm() {
this.$router.push({ path: '/collect' })
// format microcosm so no spaces or dashes PouchDB/ CouchDB dont like them
var lowercasemicrocosm = this.microcosm.toLowerCase()
var spacesremoved = lowercasemicrocosm.split(' ').join('')
......@@ -86,13 +192,21 @@ export default {
this.microcosmSet = true
localStorage.setItem('nogg_microcosm', this.microcosmFormatted)
// now we sent this same data set to the store
// this.$store.dispatch('setMicrocosm', this.microcosmFormatted),
var devicename = this.nameFormatted
var microcosm = this.microcosmFormatted
this.$store.dispatch('setMicrocosm', { devicename, microcosm })
this.$store.dispatch('startDB')
},
focusInput() {
this.$refs.microcosm.focus()
}
}
configureRemote(protocol, username, password, url) {
// console.log(protocol, username, password, url)
this.$store.dispatch('configureRemote', {
protocol,
username,
password,
url,
})
},
},
}
</script>
......@@ -132,10 +246,18 @@ h2 {
padding: 1em;
margin-left: -1em;
margin-right: -0.4em;
margin-bottom: 1em;
margin-bottom: 2.5em;
background-color: rgba(37, 194, 194, 0.4);
}
.breaker-three {
padding: 1em;
margin-left: -1em;
margin-right: -0.4em;
margin-bottom: 1em;
background-color: rgba(196, 47, 152, 0.4);
}
label,
button {
display: block;
......@@ -148,6 +270,7 @@ input {
font-size: 1em;
}
button {
display: block;
cursor: pointer;
background-color: #1cc469;
border: none;
......@@ -155,4 +278,7 @@ button {
padding: 1em;
font-size: 1em;
}
.configButton {
background-color: rgba(196, 47, 152, 0.4);
}
</style>
<template
><div>
<template>
<div>
<h1>Messy mapping tool for multiplayer thinking</h1>
<p class="info">⚠️This is a non functional beta build of nodenogg.in⚠️</p>
<p>
......@@ -36,7 +36,7 @@
<script>
export default {
name: 'TellmeMore'
name: 'TellmeMore',
}
</script>
......
<template>
<div>
<button @click="addNode()">Add Node</button>
<button>Select Node</button>
<button>Make Connections</button>
<UploadMedia />
</div>
</template>
<script>
// @ is an alias to /src
import UploadMedia from '@/components/UploadMedia.vue'
export default {
name: 'ToolBar',
components: {
UploadMedia,
},
data() {
return {}
},
methods: {
addNode() {
this.$store.dispatch('addNode')
this.$emit('added-node')
},
},
}
</script>
<style scoped></style>
<template>
<div></div>
</template>
<script>
// @ is an alias to /src
export default {
name: 'UploadMedia',
components: {},
data() {
return {}
},
}
</script>
<style scoped></style>
<template>
<div v-for="(nodes, index) in myArray" v-bind:key="index">
<form class="nodes">
<p>{{ nodes.node_id }}</p>
<template v-if="nodes.node_readmode == false">
<textarea
v-model="nodes.node_text"