Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Procter
nodenoggin vue3 duplicate
Commits
4f6d1a29
Commit
4f6d1a29
authored
Apr 01, 2021
by
Adam Procter
Browse files
slowly building up
parent
939cdc7f
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
.env
View file @
4f6d1a29
VUE_APP_COUCH_HTTP=http
VUE_APP_COUCH_USER=auto-admin
VUE_APP_COUCH_PASS=testing@
VUE_APP_COUCH_URL=127.0.0.1:5984/
\ No newline at end of file
VUE_APP_COUCH_URL=localhost:5984/
\ No newline at end of file
package.json
View file @
4f6d1a29
...
...
@@ -9,6 +9,7 @@
},
"dependencies"
:
{
"
core-js
"
:
"
^3.10.0
"
,
"
marked
"
:
"
^2.0.1
"
,
"
pouchdb
"
:
"
^7.2.2
"
,
"
vue
"
:
"
^3.0.9
"
,
"
vue-router
"
:
"
^4.0.5
"
,
...
...
src/components/AddNodes.vue
0 → 100644
View file @
4f6d1a29
/// 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
&
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
>
src/components/JoinMicrocosm.vue
View file @
4f6d1a29
...
...
@@ -14,7 +14,7 @@
v-model.trim=
"name"
type=
"text"
id=
"name"
auto
complete=
"name"
auto
focus
placeholder=
"type name here!"
autocorrect=
"off"
autocapitalize=
"none"
...
...
@@ -36,14 +36,75 @@
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>
<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>
...
...
@@ -61,6 +122,11 @@ export default {
microcosm
:
''
,
microcosmSet
:
false
,
microcosmFormatted
:
''
,
settings
:
false
,
protocol
:
''
,
username
:
''
,
password
:
''
,
url
:
''
,
}
},
...
...
@@ -75,7 +141,7 @@ export default {
// 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)
,
this
.
$store
.
dispatch
(
'
setName
'
,
this
.
nameFormatted
)
},
setMicrocosm
()
{
...
...
@@ -88,6 +154,15 @@ export default {
// now we sent this same data set to the store
this
.
$store
.
dispatch
(
'
setMicrocosm
'
,
this
.
microcosmFormatted
)
},
configureRemote
(
protocol
,
username
,
password
,
url
)
{
// console.log(protocol, username, password, url)
this
.
$store
.
dispatch
(
'
configureRemote
'
,
{
protocol
,
username
,
password
,
url
,
})
},
focusInput
()
{
this
.
$refs
.
microcosm
.
focus
()
...
...
@@ -132,10 +207,18 @@ h2 {
padding
:
1em
;
margin-left
:
-1em
;
margin-right
:
-0.4em
;
margin-bottom
:
1
em
;
margin-bottom
:
2.5
em
;
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 +231,7 @@ input {
font-size
:
1em
;
}
button
{
display
:
block
;
cursor
:
pointer
;
background-color
:
#1cc469
;
border
:
none
;
...
...
@@ -155,4 +239,7 @@ button {
padding
:
1em
;
font-size
:
1em
;
}
.configButton
{
background-color
:
rgba
(
196
,
47
,
152
,
0.4
);
}
</
style
>
src/store/index.js
View file @
4f6d1a29
import
{
createStore
}
from
'
vuex
'
import
PouchDB
from
'
pouchdb
'
import
Router
from
'
@/router
'
//import Router from '@/router'
// Checking for previous microcosm last entered from LocalStorage
if
(
localStorage
.
getItem
(
'
nogg_microcosm
'
)
==
null
)
{
...
...
@@ -34,34 +35,37 @@ export const store = createStore({
version
:
process
.
env
.
VUE_APP_VERSION
,
microcosm
:
''
,
name
:
name
,
myNodes
:
[],
allNodes
:
[],
configRemote
:
[],
}
},
mutations
:
{
SET_NAME
(
state
,
doc
)
{
state
.
name
=
doc
store
.
commit
(
'
GET_MY_NODES
'
)
SET_NAME
(
state
,
e
)
{
state
.
name
=
e
},
SET_MICROCOSM
(
state
,
doc
)
{
const
urlmicrocosm
=
Router
.
currentRoute
.
params
.
microcosm
SET_MICROCOSM
(
state
,
e
)
{
//
const urlmicrocosm = Router.currentRoute.params.microcosm
pouchdb
.
close
().
then
(
function
()
{
// if the URL Parameter has /microcosm/usethisname
if
(
urlmicrocosm
!=
undefined
)
{
microcosm
=
urlmicrocosm
localStorage
.
setItem
(
'
nogg_microcosm
'
,
microcosm
)
}
else
{
microcosm
=
doc
}
microcosm
=
e
// if (urlmicrocosm != undefined) {
// microcosm = urlmicrocosm
// localStorage.setItem('nogg_microcosm', microcosm)
// } else {
// microcosm = doc
// }
pouchdb
=
new
PouchDB
(
microcosm
)
if
(
state
.
configRemote
&&
state
.
configRemote
.
length
>
0
)
{
remote
=
state
.
configRemote
[
0
].
protocol
+
state
.
configRemote
[
0
].
couchusername
+
'
://
'
+
state
.
configRemote
[
0
].
username
+
'
:
'
+
state
.
configRemote
[
0
].
couch
password
+
state
.
configRemote
[
0
].
password
+
'
@
'
+
state
.
configRemote
[
0
].
couch
url
+
state
.
configRemote
[
0
].
url
+
'
/
'
+
microcosm
+
'
/
'
...
...
@@ -76,14 +80,101 @@ export const store = createStore({
microcosm
+
'
/
'
}
store
.
dispatch
(
'
syncDB
'
)
})
},
SET_REMOTE
(
state
,
e
)
{
state
.
configRemote
=
[
{
protocol
:
e
.
protocol
,
username
:
e
.
username
,
password
:
e
.
password
,
url
:
e
.
url
,
},
]
},
// ADD_NODE(state) {
// var uniqueid =
// Math.random().toString(36).substring(2, 15) +
// Math.random().toString(36).substring(2, 15)
// if (state.microcosm == 'first_visit') {
// console.log('not allowed on this microcosm')
// } else {
// pouchdb.get(state.name).then(function (doc) {
// doc.nodes.push({
// node_id: uniqueid,
// node_text: '',
// node_owner: state.name,
// node_type: 'sheet',
// node_shape: 'square',
// node_deleted: false,
// node_readmode: false,
// node_color: '#9bc2d8',
// })
// return pouchdb
// .put({
// _id: state.name,
// _rev: doc._rev,
// _attachments: doc._attachments,
// nodes: doc.nodes,
// })
// .then(function () {
// return pouchdb.get(state.name).then(function (doc) {
// state.myNodes = doc.nodes
// var end = Object.keys(state.myNodes).length - 1
// const newNode = {
// nodeid: state.myNodes[end].id,
// nodetext: state.myNodes[end].text,
// }
// console.log(newNode)
// })
// })
// .catch(function (err) {
// if (err.status == 404) {
// // pouchdb.put({ })
// }
// })
// })
// }
// },
GET_ALL_NODES
(
state
)
{
pouchdb
.
allDocs
({
include_docs
:
true
,
})
.
then
(
function
(
doc
)
{
state
.
allNodes
=
doc
.
rows
store
.
commit
(
'
GET_MY_NODES
'
)
})
.
catch
(
function
()
{
//console.log(err)
})
},
GET_MY_NODES
(
state
)
{
pouchdb
.
get
(
state
.
name
)
.
then
(
function
(
doc
)
{
var
i
for
(
i
=
0
;
i
<
Object
.
keys
(
doc
.
nodes
).
length
;
i
++
)
{
state
.
myNodes
=
doc
.
nodes
}
})
.
catch
(
function
()
{
// console.log(err)
})
},
},
actions
:
{
syncDB
:
()
=>
{
pouchdb
.
replicate
.
from
(
remote
).
on
(
'
complete
'
,
function
()
{
// turn on two-way, continuous, retriable sync
store
.
commit
(
'
GET_ALL_NODES
'
)
pouchdb
.
sync
(
remote
,
{
live
:
true
,
...
...
@@ -93,6 +184,7 @@ export const store = createStore({
})
.
on
(
'
change
'
,
function
()
{
// pop info into function to find out more
store
.
commit
(
'
GET_ALL_NODES
'
)
})
.
on
(
'
paused
'
,
function
()
{})
.
on
(
'
active
'
,
function
()
{})
...
...
@@ -110,8 +202,11 @@ export const store = createStore({
setMicrocosm
:
({
commit
},
e
)
=>
{
commit
(
'
SET_MICROCOSM
'
,
e
)
},
configureRemote
:
({
commit
},
e
)
=>
{
commit
(
'
SET_REMOTE
'
,
e
)
},
},
modules
:
{},
})
export
default
store
store
.
dispatch
(
'
syncDB
'
)
src/views/Start.vue
View file @
4f6d1a29
...
...
@@ -46,10 +46,9 @@ aside {
}
a
{
display
:
block
;
font-size
:
0.8
em
;
font-size
:
1
em
;
color
:
black
;
text-decoration-line
:
none
;
border-radius
:
1em
;