From 5ea9750c36b46702dbadcfb600e39a6e03719ead Mon Sep 17 00:00:00 2001 From: Adam Procter <adamprocter@researchnot.es> Date: Mon, 7 Dec 2020 14:45:03 +0000 Subject: [PATCH] edited so move doesn't drag nodes doubles the code though ( as you cant just wrap around part of the draggable component --- CHANGELOG.md | 9 + app/package.json | 2 +- app/src/components/NodesLayer.vue | 222 ++++++++++++------ app/src/components/OtherNodeslayer.vue | 301 ++++++++++++++++++------- app/src/views/Organise.vue | 2 +- 5 files changed, 380 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc8df68..67e2aa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# 0.1.38 + +_5th December 2020_ + +### Changed + +- read mode is now attached to each node instead of positions. +- node text and positioning is now using a computed filter - so the iterating should be less CPU intensive. + # 0.1.37 _30th November 2020_ diff --git a/app/package.json b/app/package.json index e3f7a8f..3e86fb6 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "nodenogg.in", - "version": "0.1.37", + "version": "0.1.38", "private": true, "scripts": { "serve": "vue-cli-service serve", diff --git a/app/src/components/NodesLayer.vue b/app/src/components/NodesLayer.vue index b5f1d00..308d863 100644 --- a/app/src/components/NodesLayer.vue +++ b/app/src/components/NodesLayer.vue @@ -1,69 +1,154 @@ <template> <div ref="nodes" class="node"> - <div v-for="(value, index) in positions_filtered" v-bind:key="index"> - <div v-for="(nodes, index) in $options.myArray" v-bind:key="index"> - <draggable - class="innernode" - :w="value.width" - :h="value.height" - :x="value.x_pos" - :y="value.y_pos" - :z="value.z_index" - :scale="scale" - @activated="onActivated(nodes.node_id)" - @dragging="onDrag" - @resizing="onResize" - @dragstop="onDragstop" - @resizestop="onResizestop" - :drag-cancel="'.drag-cancel'" - style="border: 2px dashed black; background-color: rgb(155, 194, 216)" - :min-width="200" - :min-height="220" - > - <form class="nodes"> - <template v-if="nodes.read_mode == false"> - <textarea - @focus="editTrue(true)" - @blur="editTrue(false)" - autofocus - v-model="nodes.node_text" - @input="editNode" - :id="nodes.node_id" - placeholder="Type your thoughts and ideas here! (auto saved every keystroke)" - ></textarea> - <p class="info">*markdown supported & autosaves</p> - </template> - <template v-else> - <p - :id="nodes.node_id" - :inner-html.prop="nodes.node_text | marked" - ></p> - </template> - <!-- // v-if == 'select' --> - <div class="btn-row"> - <SvgButton - buttonClass="nodes" - @click.prevent="deleteFlag(nodes.node_id)" - /> - <SvgButton2 - buttonClass="nodes" - @click.prevent="readFlag(nodes.node_id, nodes.read_mode)" - /> - </div> - <!-- // v-else // empty 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 v-if="toolmode == 'move'"> + <div v-for="(value, index) in $options.positionsArray" v-bind:key="index"> + <div v-for="(nodes, index) in $options.myArray" v-bind:key="index"> + <draggable + class="innernode" + v-if="nodes.node_id == value.node_id" + :w="value.width" + :h="value.height" + :x="value.x_pos" + :y="value.y_pos" + :z="value.z_index" + :scale="scale" + @activated="onActivated(nodes.node_id)" + :draggable="false" + :resizable="false" + @dragging="onDrag" + @resizing="onResize" + @dragstop="onDragstop" + @resizestop="onResizestop" + :drag-cancel="'.drag-cancel'" + style=" + border: 2px dashed black; + background-color: rgb(155, 194, 216); + " + :min-width="200" + :min-height="220" + > + <form class="nodes"> + <template v-if="nodes.read_mode == false"> + <textarea + @focus="editTrue(true)" + @blur="editTrue(false)" + autofocus + v-model="nodes.node_text" + @input="editNode" + :id="nodes.node_id" + placeholder="Type your thoughts and ideas here! (auto saved every keystroke)" + ></textarea> + <p class="info">*markdown supported & autosaves</p> + </template> + <template v-else> + <p + :id="nodes.node_id" + :inner-html.prop="nodes.node_text | marked" + ></p> + </template> + <template v-if="toolmode == 'select'"> + <div class="btn-row"> + <SvgButton + buttonClass="nodes" + @click.prevent="deleteFlag(nodes.node_id)" + /> + <SvgButton2 + buttonClass="nodes" + @click.prevent="readFlag(nodes.node_id, nodes.read_mode)" + /> + </div> + </template> + + <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> - </div> - </form> - </draggable> + </form> + </draggable> + </div> + </div> + </div> + + <!-- IF NOT MOVE --> + + <div v-if="toolmode != 'move'"> + <div v-for="(value, index) in $options.positionsArray" v-bind:key="index"> + <div v-for="(nodes, index) in $options.myArray" v-bind:key="index"> + <draggable + class="innernode" + v-if="nodes.node_id == value.node_id" + :w="value.width" + :h="value.height" + :x="value.x_pos" + :y="value.y_pos" + :z="value.z_index" + :scale="scale" + @activated="onActivated(nodes.node_id)" + @dragging="onDrag" + @resizing="onResize" + @dragstop="onDragstop" + @resizestop="onResizestop" + :drag-cancel="'.drag-cancel'" + style=" + border: 2px dashed black; + background-color: rgb(155, 194, 216); + " + :min-width="200" + :min-height="220" + > + <form class="nodes"> + <template v-if="nodes.read_mode == false"> + <textarea + @focus="editTrue(true)" + @blur="editTrue(false)" + autofocus + v-model="nodes.node_text" + @input="editNode" + :id="nodes.node_id" + placeholder="Type your thoughts and ideas here! (auto saved every keystroke)" + ></textarea> + <p class="info">*markdown supported & autosaves</p> + </template> + <template v-else> + <p + :id="nodes.node_id" + :inner-html.prop="nodes.node_text | marked" + ></p> + </template> + <template v-if="toolmode == 'select'"> + <div class="btn-row"> + <SvgButton + buttonClass="nodes" + @click.prevent="deleteFlag(nodes.node_id)" + /> + <SvgButton2 + buttonClass="nodes" + @click.prevent="readFlag(nodes.node_id, nodes.read_mode)" + /> + </div> + </template> + + <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> + </draggable> + </div> </div> </div> </div> @@ -124,24 +209,28 @@ export default { return nodes.deleted == false }) }, - + // this is not working correctly as dragging around moves wrong things positions_filtered: function () { return this.configPositions.filter((positions) => { - return this.myNodes.find((node) => { - return !node.deleted && positions.node_id == node.node_id + return this.myNodes.some((node) => { + return positions.node_id == node.node_id }) }) }, }, // this is to stop sync chasing bug myArray: null, + positionsArray: null, // NOTE: ok as created here but NOT if this is the first view to load created() { //access the custom option using $options this.$options.myArray = this.nodes_filtered + this.$options.positionsArray = this.positions_filtered }, updated() { + this.$options.positionsArray = this.positions_filtered + if (this.toolmode == 'addNode') { this.$options.myArray = this.nodes_filtered this.$store.commit('ui/setMode', 'select') @@ -244,7 +333,6 @@ export default { }, deleteFlag(e) { - console.log(e) if (confirm('Confirm discard?')) { this.$store.dispatch('deleteFlag', { e }) this.$options.myArray = this.nodes_filtered diff --git a/app/src/components/OtherNodeslayer.vue b/app/src/components/OtherNodeslayer.vue index 387c007..4bea445 100644 --- a/app/src/components/OtherNodeslayer.vue +++ b/app/src/components/OtherNodeslayer.vue @@ -1,103 +1,220 @@ <template> <div ref="othernodes" class="node"> - <div v-for="(value, index) in positions_filtered" v-bind:key="index"> - <div v-for="(nodes, index) in othernodes_filtered" v-bind:key="index"> - <draggable - :w="value.width" - :h="value.height" - :x="value.x_pos" - :y="value.y_pos" - :z="value.z_index" - :scale="scale" - @activated="onActivated(nodes.node_id)" - @dragging="onDrag" - @resizing="onResize" - @dragstop="onDragstop" - @resizestop="onResizestop" - style="border: 2px solid black; background-color: rgb(205, 234, 255)" - :min-width="200" - :min-height="220" - > - <p - class="read" - :id="nodes.node_id" - :inner-html.prop="nodes.node_text | marked" - ></p> + <div v-if="toolmode == 'move'"> + <div v-for="(value, index) in $options.positionsArray" v-bind:key="index"> + <div v-for="(nodes, index) in othernodes_filtered" v-bind:key="index"> + <draggable + v-if="nodes.node_id == value.node_id" + :w="value.width" + :h="value.height" + :x="value.x_pos" + :y="value.y_pos" + :z="value.z_index" + :scale="scale" + @activated="onActivated(nodes.node_id)" + :draggable="false" + :resizable="false" + @dragging="onDrag" + @resizing="onResize" + @dragstop="onDragstop" + @resizestop="onResizestop" + style=" + border: 2px solid black; + background-color: rgb(205, 234, 255); + " + :min-width="200" + :min-height="220" + > + <p + class="read" + :id="nodes.node_id" + :inner-html.prop="nodes.node_text | marked" + ></p> - <div class="react"> - <div class="eeee"> - <input :value="nodes.node_id" name="id" readonly hidden /> - <input - id="emojifield" - class="regular-input" - v-model="input" - readonly - /> + <div class="react"> + <div class="eeee"> + <input :value="nodes.node_id" name="id" readonly hidden /> + <input + id="emojifield" + class="regular-input" + v-model="input" + readonly + /> - <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" + <emoji-picker @emoji="append" :search="search"> + <div + class="emoji-invoker" + slot="emoji-invoker" + slot-scope="{ events: { click: clickEvent } }" + @click.stop="clickEvent" > - <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 }" - > + <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 - class="emoji-picker" - :style="{ top: display.y + 'px', left: display.x + 'px' }" + slot="emoji-picker" + slot-scope="{ emojis, insert, display }" > - <div class="emoji-picker__search"> - <input type="text" v-model="search" /> - </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(nodes.node_id)" - :title="emojiName" - >{{ emoji }}</span - > + <div + class="emoji-picker" + :style="{ top: display.y + 'px', left: display.x + 'px' }" + > + <div class="emoji-picker__search"> + <input type="text" v-model="search" /> + </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(nodes.node_id)" + :title="emojiName" + >{{ emoji }}</span + > + </div> </div> </div> </div> </div> + </emoji-picker> + <div class="allemoji"> + <div + class="eachemoji" + v-for="(emojis, index) in configEmoji" + :key="index" + > + <p v-if="nodes.node_id == emojis.node_id"> + {{ emojis.emoji_text }} + </p> + </div> </div> - </emoji-picker> - <div class="allemoji"> - <div - class="eachemoji" - v-for="(emojis, index) in configEmoji" - :key="index" - > - <p v-if="nodes.node_id == emojis.node_id"> - {{ emojis.emoji_text }} - </p> + </div> + </div> + </draggable> + </div> + </div> + </div> + + <!-- IF NOT MOVE tool --> + + <div v-if="toolmode != 'move'"> + <div v-for="(value, index) in $options.positionsArray" v-bind:key="index"> + <div v-for="(nodes, index) in othernodes_filtered" v-bind:key="index"> + <draggable + v-if="nodes.node_id == value.node_id" + :w="value.width" + :h="value.height" + :x="value.x_pos" + :y="value.y_pos" + :z="value.z_index" + :scale="scale" + @activated="onActivated(nodes.node_id)" + @dragging="onDrag" + @resizing="onResize" + @dragstop="onDragstop" + @resizestop="onResizestop" + style=" + border: 2px solid black; + background-color: rgb(205, 234, 255); + " + :min-width="200" + :min-height="220" + > + <p + class="read" + :id="nodes.node_id" + :inner-html.prop="nodes.node_text | marked" + ></p> + + <div class="react"> + <div class="eeee"> + <input :value="nodes.node_id" name="id" readonly hidden /> + <input + id="emojifield" + class="regular-input" + v-model="input" + readonly + /> + + <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" /> + </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(nodes.node_id)" + :title="emojiName" + >{{ emoji }}</span + > + </div> + </div> + </div> + </div> + </div> + </emoji-picker> + <div class="allemoji"> + <div + class="eachemoji" + v-for="(emojis, index) in configEmoji" + :key="index" + > + <p v-if="nodes.node_id == emojis.node_id"> + {{ emojis.emoji_text }} + </p> + </div> </div> </div> </div> - </div> - </draggable> + </draggable> + </div> </div> </div> </div> @@ -130,7 +247,6 @@ export default { marked: marked, }, - mounted() {}, computed: { ...mapState({ scale: (state) => state.ui.scale, @@ -150,12 +266,23 @@ export default { positions_filtered: function () { return this.configPositions.filter((positions) => { return this.otherNodes.find((node) => { - return !node.deleted && positions.node_id == node.node_id + return positions.node_id == node.node_id }) }) }, }, + positionsArray: null, + // NOTE: ok as created here but NOT if this is the first view to load + created() { + //access the custom option using $options + this.$options.positionsArray = this.positions_filtered + }, + + updated() { + this.$options.positionsArray = this.positions_filtered + }, + methods: { onActivated(e) { this.nodeid = e diff --git a/app/src/views/Organise.vue b/app/src/views/Organise.vue index 0339fd3..77df061 100644 --- a/app/src/views/Organise.vue +++ b/app/src/views/Organise.vue @@ -76,7 +76,7 @@ <script> import PanZoomContainer from '@/experimental/PanZoomContainer' -//import ConnectionsLayer from '@/components/ConnectionsLayer' +// import ConnectionsLayer from '@/components/ConnectionsLayer' import NodesLayer from '@/components/NodesLayer' import OffLine from '@/components/OffLine' -- GitLab