* Fixed cursor clicking ToDo lists clicking to early
* Added login form to home page with focus on load * Tags update after editing tags from title card * Fixed uploading of images/files * Fixed images not appearing when opening images tab * Search hits all categories on search, like archived * Got rid of brand icons to reduce size * Got rid of DiffPatchMatch and Crypto from note input panel to reduce size * Disabled animation on io events so they don't annoy the shit out of people on other computers
This commit is contained in:
parent
fc1f3f81fe
commit
97e7b011d9
@ -178,10 +178,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-section" v-if="loggedIn && $store.getters.totals && $store.getters.totals['totalNotes']">
|
<div class="menu-section" v-if="loggedIn">
|
||||||
<router-link exact-active-class="active" class="menu-item menu-button" to="/notes" v-on:click.native="emitReloadEvent()">
|
<router-link exact-active-class="active" class="menu-item menu-button" to="/notes" v-on:click.native="emitReloadEvent()">
|
||||||
<i class="file outline icon"></i>Notes
|
<i class="file outline icon"></i>Notes
|
||||||
<counter class="float-right" number-id="totalNotes" />
|
<counter v-if="$store.getters.totals && $store.getters.totals['totalNotes']" class="float-right" number-id="totalNotes" />
|
||||||
</router-link>
|
</router-link>
|
||||||
<div>
|
<div>
|
||||||
<!-- <div class="menu-item sub">Show Only <i class="caret down icon"></i></div> -->
|
<!-- <div class="menu-item sub">Show Only <i class="caret down icon"></i></div> -->
|
||||||
|
112
client/src/components/LoginFormComponent.vue
Normal file
112
client/src/components/LoginFormComponent.vue
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<div v-on:keyup.enter="submit()">
|
||||||
|
|
||||||
|
<div v-if="!thin" class="ui large form">
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui input">
|
||||||
|
<input ref="nameForm" v-model="username" type="text" name="email" placeholder="Username or E-mail address" autofocus>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui input">
|
||||||
|
<input v-model="password" type="password" name="password" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div :class="{ 'disabled':(username.length == 0 || password.length == 0)}" v-on:click="submit" class="ui massive compact fluid green submit button">Sign Up / Login</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div v-if="thin" class="ui small form">
|
||||||
|
<div class="fields">
|
||||||
|
<div class="six wide field">
|
||||||
|
<div class="ui input">
|
||||||
|
<input ref="nameForm" v-model="username" type="text" name="email" placeholder="Username or E-mail address" autofocus>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="six wide field">
|
||||||
|
<div class="ui input">
|
||||||
|
<input v-model="password" type="password" name="password" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="four wide field">
|
||||||
|
<div :class="{ 'disabled':(username.length == 0 || password.length == 0)}" v-on:click="submit" class="ui fluid green submit button">Sign Up / Login</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Login',
|
||||||
|
props:[ 'thin' ],
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
//Focus on login form on desktop
|
||||||
|
if(!this.$store.getters.getIsUserOnMobile){
|
||||||
|
this.$refs.nameForm.focus()
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
enabled: false,
|
||||||
|
username: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
submit(){
|
||||||
|
|
||||||
|
//Both fields are required
|
||||||
|
if(this.username <= 0){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(this.password <= 0){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let vm = this
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
username: this.username,
|
||||||
|
password: this.password
|
||||||
|
}
|
||||||
|
|
||||||
|
axios.post('/api/user/login', data)
|
||||||
|
.then(response => {
|
||||||
|
if(response.data.success){
|
||||||
|
|
||||||
|
const token = response.data.token
|
||||||
|
const username = response.data.username
|
||||||
|
const masterKey = response.data.masterKey
|
||||||
|
|
||||||
|
this.$store.commit('setLoginToken', {token, username, masterKey})
|
||||||
|
|
||||||
|
//Setup socket io after user logs in
|
||||||
|
this.$io.emit('user_connect', token)
|
||||||
|
|
||||||
|
//Redirect user to notes section after login
|
||||||
|
this.$router.push('/notes')
|
||||||
|
} else {
|
||||||
|
// this.password = ''
|
||||||
|
this.$bus.$emit('notification', 'Incorrect Username or Password')
|
||||||
|
vm.$store.commit('destroyLoginToken')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.$bus.$emit('notification', 'Incorrect Username or Password')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -153,7 +153,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Side slide menus for colors, tags, images and other options -->
|
<!-- Side slide menus for colors, tags, images and other options -->
|
||||||
<side-slide-menu v-show="colors" v-on:close="colors = false" name="colors">
|
<side-slide-menu v-if="colors" v-on:close="colors = false" name="colors">
|
||||||
<color-picker
|
<color-picker
|
||||||
@changeColor="onChangeColor"
|
@changeColor="onChangeColor"
|
||||||
@close="colors = false"
|
@close="colors = false"
|
||||||
@ -161,13 +161,13 @@
|
|||||||
/>
|
/>
|
||||||
</side-slide-menu>
|
</side-slide-menu>
|
||||||
|
|
||||||
<side-slide-menu v-show="tags" v-on:close="tags = false" name="tags" :style-object="styleObject">
|
<side-slide-menu v-if="tags" v-on:close="tags = false" name="tags" :style-object="styleObject">
|
||||||
<div class="ui basic segment">
|
<div class="ui basic segment">
|
||||||
<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
|
<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
|
||||||
</div>
|
</div>
|
||||||
</side-slide-menu>
|
</side-slide-menu>
|
||||||
|
|
||||||
<side-slide-menu v-show="images" v-on:close="images = false" name="images" :style-object="styleObject">
|
<side-slide-menu v-if="images" v-on:close="images = false" name="images" :style-object="styleObject">
|
||||||
<div class="ui basic segment">
|
<div class="ui basic segment">
|
||||||
<simple-attachment-note
|
<simple-attachment-note
|
||||||
v-on:close="images = false"
|
v-on:close="images = false"
|
||||||
@ -233,8 +233,8 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
const crypto = require('crypto')
|
// const crypto = require('crypto')
|
||||||
const DiffMatchPatch = require('../../../server/helpers/DiffMatchPatch')
|
// const DiffMatchPatch = require('../../../server/helpers/DiffMatchPatch')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InputNotes',
|
name: 'InputNotes',
|
||||||
@ -443,19 +443,14 @@
|
|||||||
|
|
||||||
let el = e.target
|
let el = e.target
|
||||||
|
|
||||||
//Adjust ofset by 40 px
|
//If the offset is triggered with a negative offset, it means the before element was clicked
|
||||||
let correction = 40
|
if(e.offsetX < -5){
|
||||||
|
//Will hide keyboard if clicked on mobile
|
||||||
//Determine if element was clicked or area before it, before means checkbox was clicked
|
if(this.$store.getters.getIsUserOnMobile){
|
||||||
if (e.offsetX > e.target.offsetLeft - correction) {
|
|
||||||
//Element was clicked
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//Will hide keyboard if clicked, much better for mobile
|
|
||||||
this.editor.blur()
|
this.editor.blur()
|
||||||
|
}
|
||||||
|
|
||||||
//Area before element was clicked, they clicked the checkbox
|
//Area before element was clicked, they clicked the checkbox
|
||||||
this.onKeyup()
|
|
||||||
if (el.className === 'active'){
|
if (el.className === 'active'){
|
||||||
el.className = 'inactive';
|
el.className = 'inactive';
|
||||||
} else {
|
} else {
|
||||||
@ -869,171 +864,6 @@
|
|||||||
console.log('Could not fetch note')
|
console.log('Could not fetch note')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
diffText(){
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
// dont emit to one user
|
|
||||||
if(this.usersOnNote <= 1){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//Post latest diff to server, server will emit change event to all connected clients
|
|
||||||
// clearTimeout(this.emitChangeDebounce)
|
|
||||||
this.emitChangeDebounce = setTimeout(i => {
|
|
||||||
|
|
||||||
//caldulate text diff
|
|
||||||
let oldText = this.diffNoteText
|
|
||||||
let newText = this.getText()
|
|
||||||
|
|
||||||
if(oldText == newText){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const dmp = new DiffMatchPatch.diff_match_patch()
|
|
||||||
const diff = dmp.diff_main(oldText, newText)
|
|
||||||
// dmp.diff_cleanupSemantic(diff)
|
|
||||||
const patch_list = dmp.patch_make(oldText, newText, diff);
|
|
||||||
const patch_text = dmp.patch_toText(patch_list);
|
|
||||||
|
|
||||||
|
|
||||||
var patches = dmp.patch_fromText(patch_text);
|
|
||||||
var results = dmp.patch_apply(patches, oldText);
|
|
||||||
|
|
||||||
const computedText = results[0]
|
|
||||||
|
|
||||||
//Save computed diff text
|
|
||||||
this.noteText = computedText
|
|
||||||
this.diffNoteText = computedText
|
|
||||||
|
|
||||||
if(patch_text == ''){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(patch_text)
|
|
||||||
this.$io.emit('note_diff', {
|
|
||||||
id: this.rawTextId,
|
|
||||||
diff: patch_text
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
}, 5)
|
|
||||||
},
|
|
||||||
patchText(patch_text){
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
//
|
|
||||||
// Capture x,y of caret and position into string
|
|
||||||
//
|
|
||||||
|
|
||||||
let currentSelection = this.editor.getSelection()
|
|
||||||
let lineText = currentSelection.startContainer.textContent
|
|
||||||
// console.log(lineText)
|
|
||||||
let cursorOffset = parseInt(currentSelection.startOffset) //number of characters in
|
|
||||||
let path = this.xpath(currentSelection.commonAncestorContainer.parentElement)
|
|
||||||
// console.log(path)
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
//Set up text to process diff
|
|
||||||
//
|
|
||||||
|
|
||||||
let currentText = this.editor._getHTML()
|
|
||||||
const startingLines = (currentText.match(/<br>/g) || '').length + 1
|
|
||||||
// console.log('1')
|
|
||||||
|
|
||||||
const dmp = new DiffMatchPatch.diff_match_patch()
|
|
||||||
var patches = dmp.patch_fromText(patch_text);
|
|
||||||
var results = dmp.patch_apply(patches, currentText);
|
|
||||||
let newText = results[0]
|
|
||||||
// console.log('2')
|
|
||||||
|
|
||||||
this.noteText = newText
|
|
||||||
this.diffNoteText = newText
|
|
||||||
// console.log('3')
|
|
||||||
// this.editor._setHTML(newText)
|
|
||||||
this.editor.setHTML(newText)
|
|
||||||
|
|
||||||
// console.log('4')
|
|
||||||
|
|
||||||
//
|
|
||||||
// I user hasn't selected the document, we are done here
|
|
||||||
// @TODO add code to halt execution
|
|
||||||
//
|
|
||||||
|
|
||||||
const endingLines = (newText.match(/<br>/g) || '').length + 1
|
|
||||||
|
|
||||||
// if(this.pastFocusedNode != null || true){
|
|
||||||
setTimeout( ()=>{
|
|
||||||
|
|
||||||
var root = this.editor.getRoot()
|
|
||||||
//Get node under current x,y on dom (may break on scroll)
|
|
||||||
// let node = document.elementFromPoint(mouse.x, mouse.y)
|
|
||||||
let node = this.getElementByXPath(path)
|
|
||||||
|
|
||||||
if(node.firstChild){
|
|
||||||
node = node.firstChild
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the number of lines changed
|
|
||||||
if(startingLines != endingLines){
|
|
||||||
|
|
||||||
//Line diff may be +1 or -1
|
|
||||||
let lineDiff = endingLines - startingLines
|
|
||||||
console.log('Line Diff => ', lineDiff)
|
|
||||||
|
|
||||||
//Pull out node number from path
|
|
||||||
var nodeNumber = path.match(/\d+/)
|
|
||||||
let modifyNode = null
|
|
||||||
if(nodeNumber.length == 1){
|
|
||||||
modifyNode = parseInt(nodeNumber[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
path = path.replace(modifyNode, modifyNode + lineDiff )
|
|
||||||
console.log(path)
|
|
||||||
let maybeNext = this.getElementByXPath(path)
|
|
||||||
if(maybeNext && maybeNext.firstChild){
|
|
||||||
maybeNext = maybeNext.firstChild
|
|
||||||
}
|
|
||||||
|
|
||||||
if(maybeNext && maybeNext.textContent == lineText){
|
|
||||||
node = maybeNext
|
|
||||||
console.log('The Node Moved!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('Targeting Node')
|
|
||||||
// console.log(node)
|
|
||||||
|
|
||||||
//Create and set range
|
|
||||||
let squireRange = this.editor.createRange(node, cursorOffset)
|
|
||||||
squireRange.collapse(true)
|
|
||||||
this.editor.setSelection(squireRange)
|
|
||||||
// console.log('cursor set')
|
|
||||||
|
|
||||||
}, 20)
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
xpath(el) {
|
|
||||||
//Skip things we can't use
|
|
||||||
if (typeof el == "string") return document.evaluate(el, document, null, 0, null)
|
|
||||||
if (!el || el.nodeType != 1) return ''
|
|
||||||
|
|
||||||
//Anchor xpath using Ids or test-ids
|
|
||||||
const testId = el.getAttribute('test-id')
|
|
||||||
if (el.id) return "//*[@id='" + el.id + "']"
|
|
||||||
|
|
||||||
//Continue to build path
|
|
||||||
const sames = [].filter.call(el.parentNode.children, function (x) { return x.tagName == el.tagName })
|
|
||||||
return this.xpath(el.parentNode) + '/' + el.tagName.toLowerCase() + (sames.length > 1 ? '['+([].indexOf.call(sames, el)+1)+']' : '')
|
|
||||||
},
|
|
||||||
getElementByXPath(xpath){
|
|
||||||
|
|
||||||
return new XPathEvaluator()
|
|
||||||
.createExpression(xpath)
|
|
||||||
.evaluate(document, XPathResult.FIRST_ORDERED_NODE_TYPE) .singleNodeValue
|
|
||||||
},
|
|
||||||
onKeyup(){
|
onKeyup(){
|
||||||
|
|
||||||
this.statusText = 'modified'
|
this.statusText = 'modified'
|
||||||
@ -1198,7 +1028,7 @@
|
|||||||
|
|
||||||
//Server will hand deliver diffs from other notes to this one
|
//Server will hand deliver diffs from other notes to this one
|
||||||
this.$io.on('incoming_diff', incomingDiffData => {
|
this.$io.on('incoming_diff', incomingDiffData => {
|
||||||
this.patchText(incomingDiffData)
|
// this.patchText(incomingDiffData)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
titleResize(){
|
titleResize(){
|
||||||
|
@ -235,7 +235,7 @@
|
|||||||
this.showTagSlideMenu = state
|
this.showTagSlideMenu = state
|
||||||
|
|
||||||
if(state == false){
|
if(state == false){
|
||||||
// this.$bus.$emit('update_single_note', this.note.id)
|
this.$bus.$emit('update_single_note', this.note.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -87,7 +87,10 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted(){
|
||||||
|
this.loadImages()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
loadImages(){
|
||||||
axios.post('/api/attachment/search', {'attachmentType':'files', 'setSize':1000})
|
axios.post('/api/attachment/search', {'attachmentType':'files', 'setSize':1000})
|
||||||
.then( ({data}) => {
|
.then( ({data}) => {
|
||||||
|
|
||||||
@ -102,7 +105,6 @@
|
|||||||
})
|
})
|
||||||
.catch(error => { this.$bus.$emit('notification', 'Failed to Load Attachments') })
|
.catch(error => { this.$bus.$emit('notification', 'Failed to Load Attachments') })
|
||||||
},
|
},
|
||||||
methods: {
|
|
||||||
onFileClick(file){
|
onFileClick(file){
|
||||||
|
|
||||||
const imageCode = `<img alt="image" src="/api/static/thumb_${file.file_location}">`
|
const imageCode = `<img alt="image" src="/api/static/thumb_${file.file_location}">`
|
||||||
|
@ -22,8 +22,8 @@
|
|||||||
<div class="fourteen wide column">
|
<div class="fourteen wide column">
|
||||||
<h2 class="ui header"><i class="small green tags icon"></i>Tags</h2>
|
<h2 class="ui header"><i class="small green tags icon"></i>Tags</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="two wide middle aligned center aligned column" v-on:click="menuOpen = false">
|
<div class="two wide middle aligned center aligned column" v-on:click="closeMenu()">
|
||||||
<i class="grey close icon"></i>
|
<i class="link grey close icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="sixteen wide middle aligned column" v-if="loadedTags.length == 0">
|
<div class="sixteen wide middle aligned column" v-if="loadedTags.length == 0">
|
||||||
Tags added to Notes will appear here.
|
Tags added to Notes will appear here.
|
||||||
@ -44,7 +44,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="shade" v-if="menuOpen" v-on:click="menuOpen = false"></div>
|
<div class="shade" v-if="menuOpen" v-on:click="closeMenu()"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -63,6 +63,9 @@
|
|||||||
components: {
|
components: {
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
|
closeMenu(){
|
||||||
|
this.menuOpen = false
|
||||||
|
},
|
||||||
openMenu(){
|
openMenu(){
|
||||||
this.menuOpen = true
|
this.menuOpen = true
|
||||||
axios.post('/api/tag/usertags')
|
axios.post('/api/tag/usertags')
|
||||||
|
@ -23,7 +23,7 @@ import 'fomantic-ui-css/components/container.css'
|
|||||||
import 'fomantic-ui-css/components/form.css'
|
import 'fomantic-ui-css/components/form.css'
|
||||||
import 'fomantic-ui-css/components/grid.css'
|
import 'fomantic-ui-css/components/grid.css'
|
||||||
import 'fomantic-ui-css/components/header.css'
|
import 'fomantic-ui-css/components/header.css'
|
||||||
import 'fomantic-ui-css/components/icon.css'
|
import 'fomantic-ui-css/components/icon.css' //Modified to remove brand icons
|
||||||
import 'fomantic-ui-css/components/input.css'
|
import 'fomantic-ui-css/components/input.css'
|
||||||
import 'fomantic-ui-css/components/segment.css'
|
import 'fomantic-ui-css/components/segment.css'
|
||||||
import 'fomantic-ui-css/components/label.css'
|
import 'fomantic-ui-css/components/label.css'
|
||||||
|
@ -120,7 +120,7 @@
|
|||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<h3 class="subtext">
|
<h3 class="subtext">
|
||||||
An easy, encrypted Note App<i class="i cursor icon blinking"></i>
|
An easy, free, secure Note App<i class="i cursor icon blinking"></i>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -131,14 +131,24 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<!-- Go to notes button -->
|
||||||
<div class="four wide center aligned column">
|
<div class="row" v-if="$parent.loggedIn">
|
||||||
<router-link class="ui huge green labeled icon button" to="/login">
|
<div class="sixteen wide middle algined center aligned column">
|
||||||
<i class="plug icon"></i>Sign Up
|
<router-link class="ui huge green labeled icon button" to="/notes">
|
||||||
|
<i class="external alternate icon"></i>Go to Notes
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="eight wide middle aligned column">
|
</div>
|
||||||
<h2>Only a Username and Password are required.</h2>
|
|
||||||
|
<!-- Small login form -->
|
||||||
|
<div class="row" v-if="!$parent.loggedIn">
|
||||||
|
<div class="sixteen wide middle algined column">
|
||||||
|
<div class="ui text container">
|
||||||
|
<h2>
|
||||||
|
<i class="plug icon"></i>
|
||||||
|
Sign Up Now - Only a Username and Password are required.</h2>
|
||||||
|
<login-form :thin="true" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -310,6 +320,9 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'WelcomePage',
|
name: 'WelcomePage',
|
||||||
|
components: {
|
||||||
|
'login-form':require('@/components/LoginFormComponent.vue').default,
|
||||||
|
},
|
||||||
data(){
|
data(){
|
||||||
return {
|
return {
|
||||||
height: null,
|
height: null,
|
||||||
@ -328,7 +341,7 @@ export default {
|
|||||||
//Don't change hero banner on mobile
|
//Don't change hero banner on mobile
|
||||||
if(!this.$store.getters.getIsUserOnMobile){
|
if(!this.$store.getters.getIsUserOnMobile){
|
||||||
let windowHeight = window.innerHeight
|
let windowHeight = window.innerHeight
|
||||||
this.height = windowHeight - (windowHeight * 0.15)
|
this.height = windowHeight - (windowHeight * 0.18)
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -21,19 +21,8 @@
|
|||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
|
|
||||||
<div class="ui large form">
|
<login-form />
|
||||||
<div class="field">
|
|
||||||
<div class="ui input">
|
|
||||||
<input v-model="username" type="text" name="email" placeholder="Username or E-mail address" autofocus>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<div class="ui input">
|
|
||||||
<input v-model="password" type="password" name="password" placeholder="Password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div :class="{ 'disabled':(username.length == 0 || password.length == 0)}" v-on:click="submit" class="ui massive compact fluid green submit button">Login</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>You will remain logged in on this browser, for 30 days or until you log out.</p>
|
<p>You will remain logged in on this browser, for 30 days or until you log out.</p>
|
||||||
@ -49,6 +38,9 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Login',
|
name: 'Login',
|
||||||
|
components: {
|
||||||
|
'login-form':require('@/components/LoginFormComponent.vue').default,
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
v-on:tagClick="tagId => toggleTagFilter(tagId)"
|
v-on:tagClick="tagId => toggleTagFilter(tagId)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="ui basic shrinking icon button" v-on:click="toggleTitleView()">
|
<div class="ui basic shrinking icon button" v-on:click="toggleTitleView()" v-if="$store.getters.totals && $store.getters.totals['totalNotes'] > 0">
|
||||||
<i v-if="titleView" class="th icon"></i>
|
<i v-if="titleView" class="th icon"></i>
|
||||||
<i v-if="!titleView" class="bars icon"></i>
|
<i v-if="!titleView" class="bars icon"></i>
|
||||||
</div>
|
</div>
|
||||||
@ -91,7 +91,7 @@
|
|||||||
<!-- Note title card display -->
|
<!-- Note title card display -->
|
||||||
<div class="sixteen wide column">
|
<div class="sixteen wide column">
|
||||||
|
|
||||||
<h3 v-if="$store.getters.totals && $store.getters.totals['totalNotes'] == 0">
|
<h3 v-if="$store.getters.totals && $store.getters.totals['totalNotes'] == 0 && fastFilters['notesHome'] == 1">
|
||||||
No Notes Yet. <br>Thats ok.<br><br> <br>
|
No Notes Yet. <br>Thats ok.<br><br> <br>
|
||||||
<img loading="lazy" width="25%" src="/api/static/assets/marketing/hamburger.svg" alt="Create a new note"><br>
|
<img loading="lazy" width="25%" src="/api/static/assets/marketing/hamburger.svg" alt="Create a new note"><br>
|
||||||
Create one when you feel ready.
|
Create one when you feel ready.
|
||||||
@ -264,6 +264,13 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.$bus.$on('update_single_note', (noteId) => {
|
||||||
|
//Do not update note if its open
|
||||||
|
if(this.activeNoteId1 != noteId){
|
||||||
|
this.updateSingleNote(noteId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
//Update totals for app
|
//Update totals for app
|
||||||
this.$store.dispatch('fetchAndUpdateUserTotals')
|
this.$store.dispatch('fetchAndUpdateUserTotals')
|
||||||
|
|
||||||
@ -277,10 +284,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// this.$bus.$on('update_single_note', (noteId) => {
|
|
||||||
// this.updateSingleNote(noteId)
|
|
||||||
// })
|
|
||||||
|
|
||||||
this.$bus.$on('note_deleted', (noteId) => {
|
this.$bus.$on('note_deleted', (noteId) => {
|
||||||
//Remove deleted note from set, its deleted
|
//Remove deleted note from set, its deleted
|
||||||
|
|
||||||
@ -664,6 +667,18 @@
|
|||||||
//Sort notes into defined sections
|
//Sort notes into defined sections
|
||||||
notes.forEach(note => {
|
notes.forEach(note => {
|
||||||
|
|
||||||
|
if(this.searchTerm.length > 0){
|
||||||
|
if(note.pinned == 1){
|
||||||
|
this.noteSections.pinned.push(note)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Push to default note section
|
||||||
|
this.noteSections.notes.push(note)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Display all tags in tag section
|
||||||
if(this.searchTags.length >= 1){
|
if(this.searchTags.length >= 1){
|
||||||
this.noteSections.tagged.push(note)
|
this.noteSections.tagged.push(note)
|
||||||
return
|
return
|
||||||
@ -693,9 +708,7 @@
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if(note.archived == 1){
|
if(note.archived == 1){ return }
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//Only show sent notes section if shared is selected
|
//Only show sent notes section if shared is selected
|
||||||
if(this.fastFilters.onlyShowSharedNotes == 1){
|
if(this.fastFilters.onlyShowSharedNotes == 1){
|
||||||
@ -746,6 +759,8 @@
|
|||||||
//clear out tags
|
//clear out tags
|
||||||
this.searchTags = []
|
this.searchTags = []
|
||||||
this.loadingInProgress = false
|
this.loadingInProgress = false
|
||||||
|
this.searchTerm = ''
|
||||||
|
this.$bus.$emit('reset_fast_filters')
|
||||||
|
|
||||||
//A little hacky, brings user to notes page then filters on click
|
//A little hacky, brings user to notes page then filters on click
|
||||||
if(this.$route.name != 'Note Page'){
|
if(this.$route.name != 'Note Page'){
|
||||||
|
@ -57,6 +57,8 @@ Tag.addToNote = (userId, noteId, tagText) => {
|
|||||||
.then( newTagId => {
|
.then( newTagId => {
|
||||||
Tag.associateWithNote(userId, noteId, newTagId)
|
Tag.associateWithNote(userId, noteId, newTagId)
|
||||||
.then( result => {
|
.then( result => {
|
||||||
|
|
||||||
|
SocketIo.to(userId).emit('new_note_text_saved', {noteId})
|
||||||
resolve(result)
|
resolve(result)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -12,6 +12,7 @@ let userId = null
|
|||||||
router.use(function setUserId (req, res, next) {
|
router.use(function setUserId (req, res, next) {
|
||||||
if(userId = req.headers.userId){
|
if(userId = req.headers.userId){
|
||||||
userId = req.headers.userId
|
userId = req.headers.userId
|
||||||
|
masterKey = req.headers.masterKey
|
||||||
}
|
}
|
||||||
|
|
||||||
next()
|
next()
|
||||||
@ -52,9 +53,7 @@ router.post('/upload', upload.single('file'), function (req, res, next) {
|
|||||||
|
|
||||||
Attachment.processUploadedFile(userId, noteId, req.file)
|
Attachment.processUploadedFile(userId, noteId, req.file)
|
||||||
.then( uploadResults => {
|
.then( uploadResults => {
|
||||||
//Reindex note, attachment may have had text
|
res.send(uploadResults)
|
||||||
Note.reindex(userId, noteId)
|
|
||||||
.then( data => {res.send(uploadResults)})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user