Skip to content
Snippets Groups Projects
Commit 8c662ffe authored by Adam Procter's avatar Adam Procter
Browse files

added basic cards view / enhanced list view

also added leave button in navigation for  better small screen support
parent cd328555
No related branches found
No related tags found
No related merge requests found
No preview for this file type
# 0.1.27
_9th October 2020_
### Added
- Basic card view of all nodes
- Leave link in Navigation
### Changed
- List view now you can enter basic read mode
- List view you can now discard your nodes
# 0.1.26 # 0.1.26
_6th October 2020_ _6th October 2020_
...@@ -10,7 +24,7 @@ _6th October 2020_ ...@@ -10,7 +24,7 @@ _6th October 2020_
### Added ### Added
- the toolbar now shows (in basic form) to you only your device name and the microcosm you are currently viewing - The toolbar now shows (in basic form) to you only your device name and the microcosm you are currently viewing
# 0.1.25 # 0.1.25
......
{ {
"name": "nodenogg.in", "name": "nodenogg.in",
"version": "0.1.24", "version": "0.1.27",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
......
<template>
<div>
<div v-for="(value, index) in configPositions" v-bind:key="index">
<div class="nodes" v-if="nodeid == value.node_id && deleted == false">
<form>
<!-- <div v-if="posvalue.read_mode == false"> -->
<div v-if="value.read_mode == false">
<div v-for="value in $options.myArray" v-bind:key="value.node_id">
<div v-if="value.deleted == false">
<textarea
v-if="nodeid == value.node_id"
@focus="editTrue(true)"
@blur="editTrue(false)"
autofocus
v-model="value.node_text"
@input="editNode"
:id="value.node_id"
placeholder="Idea goes here!"
ref="newnode"
></textarea>
</div>
</div>
</div>
<div v-if="value.read_mode == true">
<p
class="read"
:id="nodeid"
:inner-html.prop="nodetext | marked"
></p>
</div>
<div class="allemoji">
<div
class="eachemoji"
v-for="(emojis, index) in configEmoji"
:key="index"
>
<p v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
</div>
<p class="info">*markdown supported &amp; autosaves</p>
<div class="btn-row">
<BaseButton buttonClass="danger" @click="deleteFlag()"
>Discard</BaseButton
>
<div v-if="value.read_mode == true">
<BaseButton class="read" buttonClass="action" @click="readFlag()"
>Edit Mode
</BaseButton>
</div>
<div v-else>
<BaseButton class="read" buttonClass="action" @click="readFlag()"
>Read Mode</BaseButton
>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import marked from 'marked'
var readmode
export default {
name: 'CardsLayer',
data: function () {
return {}
},
props: {
nodeid: String,
nodetext: String,
deleted: Boolean,
},
computed: mapState({
myNodes: (state) => state.myNodes,
configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
}),
filters: {
marked: marked,
},
myArray: null,
created() {
this.$options.myArray = this.myNodes
},
methods: {
editNode(e) {
var nodeid = e.target.id
var nodetext = e.target.value
this.$store.dispatch('editNode', { nodeid, nodetext })
},
deleteFlag(e) {
e = this.nodeid
this.$store.dispatch('deleteFlag', { e })
},
readFlag(e) {
e = this.nodeid
var i
for (i = 0; i < Object.keys(this.configPositions).length; i++) {
if (this.configPositions[i].node_id == this.nodeid) {
this.localreadmode = this.configPositions[i].read_mode
}
}
if (this.localreadmode == true) {
readmode = false
this.$store.dispatch('readFlag', { e, readmode })
this.mode = 'Read'
} else {
readmode = true
this.$store.dispatch('readFlag', { e, readmode })
this.mode = 'Edit'
}
},
editTrue(e) {
this.$emit('editTrue', e)
},
},
}
</script>
<style lang="css" scoped>
h2 {
color: red;
}
.nodes {
/* width: 95%; */
width: 285px;
height: 355px;
border: 2px dashed black;
background-color: rgb(155, 194, 216);
margin-top: 1em;
margin-right: 1em;
}
.read {
/* min-width: 100px; */
min-height: 175px;
padding: 0 1em 0 1em;
}
textarea {
width: 90%;
height: 175px;
resize: none;
box-sizing: border-box;
font-family: 'Inter var', Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin: 1em;
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;
}
img {
width: 100%;
}
</style>
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<div v-for="(value, index) in configPositions" v-bind:key="index"> <div v-for="(value, index) in configPositions" v-bind:key="index">
<div class="nodes" v-if="nodeid == value.node_id && deleted == false"> <div class="nodes" v-if="nodeid == value.node_id && deleted == false">
<form> <form>
<div v-if="value.read_mode == false">
<!-- <div v-if="posvalue.read_mode == false"> --> <!-- <div v-if="posvalue.read_mode == false"> -->
<div v-for="value in $options.myArray" v-bind:key="value.node_id"> <div v-for="value in $options.myArray" v-bind:key="value.node_id">
<div v-if="value.deleted == false"> <div v-if="value.deleted == false">
...@@ -11,14 +12,49 @@ ...@@ -11,14 +12,49 @@
@focus="editTrue(true)" @focus="editTrue(true)"
@blur="editTrue(false)" @blur="editTrue(false)"
autofocus autofocus
ref="newnode"
v-model="value.node_text" v-model="value.node_text"
@input="editNode" @input="editNode"
:id="value.node_id" :id="value.node_id"
placeholder="Idea goes here!" placeholder="Idea goes here!"
ref="newnode"
></textarea> ></textarea>
</div> </div>
</div> </div>
</div>
<div v-if="value.read_mode == true">
<p
class="read"
:id="nodeid"
:inner-html.prop="nodetext | marked"
></p>
</div>
<div class="allemoji">
<div
class="eachemoji"
v-for="(emojis, index) in configEmoji"
:key="index"
>
<p v-if="nodeid == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
</div>
<p class="info">*markdown supported &amp; autosaves</p>
<div class="btn-row">
<BaseButton buttonClass="danger" @click="deleteFlag()"
>Discard</BaseButton
>
<div v-if="value.read_mode == true">
<BaseButton class="read" buttonClass="action" @click="readFlag()"
>Edit Mode
</BaseButton>
</div>
<div v-else>
<BaseButton class="read" buttonClass="action" @click="readFlag()"
>Read Mode</BaseButton
>
</div>
</div>
</form> </form>
</div> </div>
</div> </div>
...@@ -27,7 +63,8 @@ ...@@ -27,7 +63,8 @@
<script> <script>
import { mapState } from 'vuex' import { mapState } from 'vuex'
import marked from 'marked'
var readmode
export default { export default {
name: 'ListLayer', name: 'ListLayer',
...@@ -41,9 +78,14 @@ export default { ...@@ -41,9 +78,14 @@ export default {
deleted: Boolean, deleted: Boolean,
}, },
filters: {
marked: marked,
},
computed: mapState({ computed: mapState({
myNodes: (state) => state.myNodes, myNodes: (state) => state.myNodes,
configPositions: (state) => state.configPositions, configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
}), }),
myArray: null, myArray: null,
...@@ -61,6 +103,34 @@ export default { ...@@ -61,6 +103,34 @@ export default {
editTrue(e) { editTrue(e) {
this.$emit('editTrue', e) this.$emit('editTrue', e)
}, },
deleteFlag(e) {
e = this.nodeid
this.$store.dispatch('deleteFlag', { e })
},
readFlag(e) {
e = this.nodeid
var i
for (i = 0; i < Object.keys(this.configPositions).length; i++) {
if (this.configPositions[i].node_id == this.nodeid) {
this.localreadmode = this.configPositions[i].read_mode
}
}
if (this.localreadmode == true) {
readmode = false
this.$store.dispatch('readFlag', { e, readmode })
this.mode = 'Read'
} else {
readmode = true
this.$store.dispatch('readFlag', { e, readmode })
this.mode = 'Edit'
}
},
focusInput() {
this.$refs.newnode.focus()
},
}, },
} }
</script> </script>
...@@ -91,4 +161,29 @@ textarea { ...@@ -91,4 +161,29 @@ textarea {
background-color: rgb(187, 227, 255); background-color: rgb(187, 227, 255);
scrollbar-color: yellow 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;
}
img {
width: 100%;
}
</style> </style>
<template>
<div>
<div v-for="(value, index) in configPositions" v-bind:key="index">
<div class="nodes" v-if="nodeid == value.node_id && deleted == false">
<form>
<div v-for="value in $options.myArray" v-bind:key="value.node_id">
<div v-if="nodeid == value.node_id && deleted == false">
<p
class="read"
:id="nodeid"
:inner-html.prop="nodetext | marked"
></p>
<!-- <h3>Reactions</h3> -->
<div class="react" v-if="value.node_id != undefined">
<!-- <h2>React</h2> -->
<div class="eeee">
<input :value="value.node_id" name="id" readonly hidden />
<input
id="emojifield"
class="regular-input"
v-model="input"
readonly
/>
<div class="allemoji">
<div
class="eachemoji"
v-for="(emojis, index) in configEmoji"
:key="index"
>
<p v-if="value.node_id == emojis.node_id">
{{ emojis.emoji_text }}
</p>
</div>
</div>
<emoji-picker @emoji="append" :search="search">
<div
class="emoji-invoker"
slot="emoji-invoker"
slot-scope="{ events: { click: clickEvent } }"
@click.stop="clickEvent"
>
<svg
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
/>
</svg>
</div>
<div
slot="emoji-picker"
slot-scope="{ emojis, insert, display }"
>
<div
class="emoji-picker"
:style="{
top: display.y + 'px',
left: display.x + 'px',
}"
>
<div class="emoji-picker__search">
<input type="text" v-model="search" v-focus />
</div>
<div>
<div
v-for="(emojiGroup, category) in emojis"
:key="category"
>
<h5>{{ category }}</h5>
<div class="emojis">
<span
v-for="(emoji, emojiName) in emojiGroup"
:key="emojiName"
@click="insert(emoji), sentReact()"
:title="emojiName"
>{{ emoji }}</span
>
</div>
</div>
</div>
</div>
</div>
</emoji-picker>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import EmojiPicker from 'vue-emoji-picker'
import marked from 'marked'
export default {
name: 'OtherCardslayer',
components: {
EmojiPicker,
},
data() {
return {
input: '',
search: '',
}
},
props: {
nodeid: String,
nodetext: String,
deleted: Boolean,
},
filters: {
marked: marked,
},
computed: mapState({
otherNodes: (state) => state.otherNodes,
configPositions: (state) => state.configPositions,
configEmoji: (state) => state.configEmoji,
}),
myArray: null,
created() {
this.$options.myArray = this.otherNodes
},
methods: {
append(emoji) {
this.input += emoji
},
sentReact(nodeid, emojitext) {
emojitext = this.input
nodeid = this.nodeid
this.$store.dispatch('addEmoji', {
nodeid,
emojitext,
})
this.input = ''
},
},
directives: {
focus: {
inserted(el) {
el.focus()
},
},
},
}
</script>
<style lang="css" scoped>
h2 {
color: red;
}
.allemoji {
font-size: 2em;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(0, auto));
}
.eachemoji p {
margin: 0em;
}
.nodes {
width: 285px;
border: 2px solid black;
background-color: rgb(205, 234, 255);
margin-top: 1em;
margin-right: 1em;
padding-left: 1em;
padding-bottom: 1em;
}
input {
display: none;
}
.emoji-invoker {
cursor: pointer;
transition: all 0.8s;
}
.emoji-invoker:hover > svg {
fill: #000000;
}
.emoji-invoker > svg {
fill: #767b7e;
margin-top: 10px;
margin-left: 0.2em;
transform: scale(1.5);
}
.emoji-picker {
transform: scale(1.2);
z-index: 1;
font-family: Montserrat;
border: 1px solid #ccc;
width: 18rem;
height: 20rem;
overflow: scroll;
padding: 1rem;
box-sizing: border-box;
border-radius: 0.5rem;
background: #fff;
box-shadow: 1px 1px 8px #c7dbe6;
margin-top: 3em;
margin-left: 3em;
}
.emoji-picker__search {
display: flex;
}
.emoji-picker__search > input {
flex: 1;
border-radius: 10rem;
border: 1px solid #ccc;
padding: 0.5rem 1rem;
outline: none;
}
.emoji-picker h5 {
margin-top: 0;
margin-bottom: 0;
color: #b1b1b1;
text-transform: uppercase;
font-size: 0.8rem;
cursor: default;
}
.emoji-picker .emojis {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.emoji-picker .emojis:after {
content: '';
flex: auto;
}
.emoji-picker .emojis span {
padding: 0.2rem;
cursor: pointer;
border-radius: 5px;
}
.emoji-picker .emojis span:hover {
background: #ececec;
cursor: pointer;
}
</style>
...@@ -20,17 +20,17 @@ export default { ...@@ -20,17 +20,17 @@ export default {
name: 'OtherListlayer', name: 'OtherListlayer',
props: { props: {
nodeid: String, nodeid: String,
nodetext: String nodetext: String,
}, },
computed: mapState({ computed: mapState({
otherNodes: state => state.otherNodes otherNodes: (state) => state.otherNodes,
}), }),
filters: { filters: {
// need to write a reverse data filter I suspect here so new data is at the top of list // need to write a reverse data filter I suspect here so new data is at the top of list
marked: marked marked: marked,
} },
} }
</script> </script>
......
import Vue from 'vue' import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import Home from '../views/Home.vue' import Home from '../views/Home.vue'
import Cards from '../views/Cards.vue'
import List from '../views/List.vue' import List from '../views/List.vue'
import Discarded from '../views/Discarded.vue' import Discarded from '../views/Discarded.vue'
import Leave from '../views/Leave.vue'
// import Oldhome from '../views/Oldhome' // import Oldhome from '../views/Oldhome'
//import Test from '../views/Test' //import Test from '../views/Test'
...@@ -14,9 +16,14 @@ export const routes = [ ...@@ -14,9 +16,14 @@ export const routes = [
name: 'Home', name: 'Home',
component: Home, component: Home,
}, },
{
path: '/cards',
name: 'Cards',
component: Cards,
},
{ {
path: '/list', path: '/list',
name: 'List', name: 'My List',
component: List, component: List,
}, },
{ {
...@@ -34,6 +41,12 @@ export const routes = [ ...@@ -34,6 +41,12 @@ export const routes = [
import(/* webpackChunkName: "about" */ '../views/About.vue'), import(/* webpackChunkName: "about" */ '../views/About.vue'),
}, },
{
path: '/leave',
name: 'Leave',
component: Leave,
},
// { // {
// path: '/test', // path: '/test',
// name: 'IPFS Test', // name: 'IPFS Test',
......
<template>
<div>
<div v-if="clientset">
<div id="listwrapper">
<h1 class="mobile">nodes - card view</h1>
<div class="btn-row">
<BaseButton class="new" buttonClass="action" @click="addNode()"
>Create Node</BaseButton
>
</div>
<div class="grid">
<CardsLayer
@editTrue="(e) => editTrue(e)"
v-for="value in myNodes"
v-bind:key="value.node_id"
v-bind:nodeid="value.node_id"
v-bind:nodetext="value.node_text"
v-bind:deleted="value.deleted"
/>
<OtherCardslayer
v-for="value in otherNodes"
v-bind:key="value.node_id"
v-bind:nodeid="value.node_id"
v-bind:nodetext="value.node_text"
v-bind:deleted="value.deleted"
/>
</div>
</div>
</div>
<div v-else>
<OnBoard @clientAdded="clientAdded()" @editTrue="(e) => editTrue(e)" />
</div>
</div>
</template>
<script>
import Router from '@/router'
import CardsLayer from '@/components/CardsLayer'
import OtherCardslayer from '@/components/OtherCardslayer'
import OnBoard from '@/components/OnBoard'
import { mapState } from 'vuex'
import marked from 'marked'
import { shortcutsMixin } from '@/components/mixins/shortcutsMixin.js'
export default {
name: 'List',
mixins: [shortcutsMixin],
data: function () {
return {
localmicrocosm: Router.currentRoute.params.microcosm,
clientid: '',
clientset: false,
offline: false,
name: false,
microcosm: false,
}
},
props: {
nodeid: String,
nodetext: String,
deleted: Boolean,
},
computed: {
...mapState({
myNodes: (state) => state.myNodes,
otherNodes: (state) => state.otherNodes,
}),
},
created() {
if (typeof window !== 'undefined') {
document.addEventListener('keydown', this.handleKeyPress)
}
},
beforeDestroy() {
if (typeof window !== 'undefined') {
document.removeEventListener('keydown', this.handleKeyPress)
}
},
mounted() {},
methods: {
clientAdded() {
this.clientset = !this.clientset
},
addNode() {
this.$store.dispatch('addNode')
},
editTrue(e) {
this.$store.dispatch('shortcutState', e)
},
},
components: {
CardsLayer,
OtherCardslayer,
OnBoard,
},
filters: {
marked: marked,
},
}
</script>
<style lang="css" scoped>
.grid {
display: flex;
flex-wrap: wrap;
}
#listwrapper {
margin-left: 1em;
margin-bottom: 1em;
}
.mobile {
font-size: 1em;
}
.new {
margin-bottom: 1em;
}
</style>
...@@ -58,6 +58,9 @@ export default { ...@@ -58,6 +58,9 @@ export default {
clientAdded() { clientAdded() {
this.clientset = !this.clientset this.clientset = !this.clientset
}, },
editTrue(e) {
this.$store.dispatch('shortcutState', e)
},
}, },
} }
</script> </script>
......
<template>
<div class="leave"></div>
</template>
<script>
export default {
name: 'Leave',
created() {
this.removeLocal()
},
methods: {
removeLocal: function () {
localStorage.removeItem('myNNClient')
localStorage.removeItem('mylastMicrocosm')
location.assign(
process.env.VUE_APP_HTTP + '://' + process.env.VUE_APP_URL + '/'
)
},
},
}
</script>
<style lang="css" scoped></style>
...@@ -57,6 +57,8 @@ export default { ...@@ -57,6 +57,8 @@ export default {
computed: { computed: {
...mapState({ ...mapState({
myNodes: (state) => state.myNodes, myNodes: (state) => state.myNodes,
shortcutstate: (state) => state.shortcutstate,
toolmode: (state) => state.ui.mode,
}), }),
}, },
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment