Added privacy policy
Updated marketing Added some keyboard shortcuts Added settings page Added accent theming Added beta 2FA
This commit is contained in:
@@ -182,7 +182,6 @@
|
||||
openNote(){
|
||||
const noteId = this.item.note_id
|
||||
this.$router.push('/notes/open/'+noteId)
|
||||
this.$bus.$emit('open_note', noteId)
|
||||
},
|
||||
openEditAttachments(){
|
||||
const noteId = this.item.note_id
|
||||
|
@@ -24,9 +24,9 @@
|
||||
}
|
||||
},
|
||||
beforeMount(){
|
||||
this.$bus.$on('reset_fast_filters', () => {
|
||||
this.orderString = 'Order by Last Edited'
|
||||
})
|
||||
// this.$bus.$on('reset_fast_filters', () => {
|
||||
// this.orderString = 'Order by Last Edited'
|
||||
// })
|
||||
},
|
||||
methods:{
|
||||
displayString(){
|
||||
|
@@ -19,9 +19,10 @@
|
||||
bottom: 0;
|
||||
}
|
||||
.menu-logo-display {
|
||||
width: 25px;
|
||||
margin: 5px 0 0 42px;
|
||||
width: 27px;
|
||||
margin: 5px 0 0 41px;
|
||||
display: inline-block;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
@@ -79,15 +80,17 @@
|
||||
background-color: var(--small_element_bg_color);
|
||||
border-bottom: 1px solid;
|
||||
border-color: var(--border_color);
|
||||
padding: 5px 1rem 5px;
|
||||
/*padding: 5px 1rem 5px;*/
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
.place-holder {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
.top-menu-bar img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
.logo-display {
|
||||
width: 27px;
|
||||
height: auto;
|
||||
}
|
||||
.version-display {
|
||||
position: absolute;
|
||||
@@ -101,6 +104,19 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mobile-button {
|
||||
display: inline-block;
|
||||
font-size: 2em;
|
||||
padding: 6px 3px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mobile-button.active {
|
||||
background-color: transparent;
|
||||
}
|
||||
.mobile-button i {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<template>
|
||||
@@ -110,45 +126,37 @@
|
||||
|
||||
<!-- collapsed menu, appears as a bar -->
|
||||
<div class="top-menu-bar" v-if="(collapsed || mobile) && !menuOpen">
|
||||
<div class="ui grid">
|
||||
|
||||
<div class="seven wide column">
|
||||
<div class="ui large basic compact icon button" v-on:click="collapseMenu">
|
||||
<i class="green bars icon"></i>
|
||||
</div>
|
||||
|
||||
<!-- <router-link v-if="loggedIn" class="ui large basic compact icon button" to="/notes" v-on:click.native="emitReloadEvent()">
|
||||
<i class="green home icon"></i>
|
||||
</router-link> -->
|
||||
|
||||
<router-link v-if="loggedIn" class="ui basic icon button" exact-active-class="active" to="/attachments">
|
||||
<i class="open folder outline icon"></i>
|
||||
</router-link>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="two wide center aligned bottom aligned column">
|
||||
<img loading="lazy" src="/api/static/assets/logo.svg" alt="Solid Scribe Logo">
|
||||
</div>
|
||||
|
||||
<div class="seven wide right aligned column">
|
||||
|
||||
<div v-on:click="toggleNightMode" class="ui large basic compact icon button">
|
||||
<i class="green moon outline icon"></i>
|
||||
</div>
|
||||
|
||||
<!-- mobile create note button -->
|
||||
<span v-if="loggedIn">
|
||||
<span v-if="!disableNewNote" @click="createNote" class="ui large green compact icon button">
|
||||
<i class="plus icon"></i>
|
||||
</span>
|
||||
<span v-if="disableNewNote" class="ui large basic compact icon button">
|
||||
<i class="grey plus icon"></i>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="mobile-button">
|
||||
<i class="green link bars icon" v-on:click="collapseMenu"></i>
|
||||
</div>
|
||||
|
||||
<div class="mobile-button"></div>
|
||||
|
||||
<router-link v-if="loggedIn" to="/quick" class="mobile-button" exact-active-class="active">
|
||||
<i class="green sticky note outline icon"></i>
|
||||
</router-link>
|
||||
|
||||
<router-link v-if="loggedIn" class="mobile-button" exact-active-class="active" to="/notes" v-on:click.native="emitReloadEvent()">
|
||||
<logo class="logo-display" color="var(--main-accent)" />
|
||||
</router-link>
|
||||
|
||||
<router-link v-if="loggedIn" class="mobile-button" exact-active-class="active" to="/attachments">
|
||||
<i class="green open folder outline icon"></i>
|
||||
</router-link>
|
||||
|
||||
<div class="mobile-button"></div>
|
||||
|
||||
<!-- mobile create note button -->
|
||||
<span v-if="loggedIn">
|
||||
<span v-if="!disableNewNote" @click="createNote" class="mobile-button">
|
||||
<i class="green plus icon"></i>
|
||||
</span>
|
||||
<span v-if="disableNewNote" class="mobile-button">
|
||||
<i class="grey plus icon"></i>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="shade" v-if="mobile && !collapsed" v-on:click="collapseMenu"></div>
|
||||
@@ -161,7 +169,7 @@
|
||||
<div class="menu-section" v-on:click="collapseMenu">
|
||||
<!-- <div class="menu-item menu-button" > -->
|
||||
<i class="white angle left icon"></i>
|
||||
<img class="menu-logo-display" loading="lazy" src="/api/static/assets/logo.svg" alt="Solid Scribe Logo">
|
||||
<logo class="menu-logo-display" color="var(--main-accent)" />
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
|
||||
@@ -236,14 +244,14 @@
|
||||
|
||||
<div class="menu-section">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/help">
|
||||
<i class="question circle outline icon"></i>Help
|
||||
<i class="question circle outline icon"></i>Help / Terms
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="menu-section" v-if="loggedIn" :data-tooltip="`Logout ${this.$store.getters.getUsername}`" data-inverted="" data-position="right center">
|
||||
<div v-on:click="destroyLoginToken" class="menu-item menu-button">
|
||||
<i v-if="userIcon" class="user outline icon"></i>{{ usernameDisplay }}
|
||||
</div>
|
||||
<div class="menu-section" v-if="loggedIn" :data-tooltip="`Settings for ${this.$store.getters.getUsername}`" data-inverted="" data-position="right center">
|
||||
<router-link class="menu-item menu-button" exact-active-class="active" to="/settings">
|
||||
<i v-if="userIcon" class="cog icon"></i>{{ usernameDisplay }}
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -264,6 +272,7 @@
|
||||
components: {
|
||||
'search-input': require('@/components/SearchInput.vue').default,
|
||||
'counter':require('@/components/AnimatedCounterComponent.vue').default,
|
||||
'logo':require('@/components/LogoComponent.vue').default,
|
||||
},
|
||||
data: function(){
|
||||
return {
|
||||
@@ -274,10 +283,14 @@
|
||||
disableNewNote: false,
|
||||
menuOpen: true,
|
||||
userIcon: true,
|
||||
resizeDebounce: null,
|
||||
}
|
||||
},
|
||||
beforeCreate: function(){
|
||||
|
||||
beforeMount(){
|
||||
window.addEventListener('resize', this.resizeEventHandler)
|
||||
},
|
||||
beforeDestroy(){
|
||||
window.removeEventListener('resize', this.resizeEventHandler)
|
||||
},
|
||||
mounted: function(){
|
||||
this.mobile = this.$store.getters.getIsUserOnMobile
|
||||
@@ -316,6 +329,19 @@
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resizeEventHandler(e) {
|
||||
clearTimeout(this.resizeDebounce)
|
||||
this.resizeDebounce = setTimeout(() => {
|
||||
|
||||
this.menuOpen = false
|
||||
this.collapsed = false
|
||||
|
||||
if(window.innerWidth < 700){
|
||||
|
||||
this.collapsed = true
|
||||
}
|
||||
}, 100)
|
||||
},
|
||||
menuClicked(){
|
||||
//Collapse menu when item is clicked in mobile
|
||||
if(this.mobile && !this.collapsed){
|
||||
@@ -334,28 +360,22 @@
|
||||
|
||||
},
|
||||
createNote(event){
|
||||
const title = ''
|
||||
|
||||
this.disableNewNote = true
|
||||
|
||||
axios.post('/api/note/create', {title})
|
||||
axios.post('/api/note/create', {title:''})
|
||||
.then(response => {
|
||||
|
||||
if(response.data && response.data.id){
|
||||
//Redirect to note page if user is not on it
|
||||
this.$bus.$emit('open_note', response.data.id)
|
||||
|
||||
//Push new note to url and it will open
|
||||
this.$router.push('/notes/open/'+response.data.id)
|
||||
|
||||
this.disableNewNote = false
|
||||
}
|
||||
})
|
||||
.catch(error => { this.$bus.$emit('notification', 'Failed to create note') })
|
||||
},
|
||||
destroyLoginToken() {
|
||||
axios.post('/api/user/logout')
|
||||
setTimeout(() => {
|
||||
this.$bus.$emit('notification', 'Logged Out')
|
||||
this.$store.commit('destroyLoginToken')
|
||||
this.$router.push('/')
|
||||
}, 200)
|
||||
},
|
||||
toggleNightMode(){
|
||||
this.$store.commit('toggleNightMode')
|
||||
},
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="loading-container">
|
||||
<svg version="1.1" id="L6" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
|
||||
<rect fill="none" :stroke="$store.getters.getIsNightMode > 0 ? '#FFF':'#16ab39'" stroke-width="4" x="25" y="25" width="50" height="50" rx="5">
|
||||
<rect fill="none" :stroke="$store.getters.getIsNightMode > 0 ? '#FFF':'var(--main-accent)'" stroke-width="4" x="25" y="25" width="50" height="50" rx="5">
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
dur="0.5s"
|
||||
@@ -12,7 +12,7 @@
|
||||
attributeType="XML"
|
||||
begin="rectBox.end"/>
|
||||
</rect>
|
||||
<rect x="25" y="25" :fill="$store.getters.getIsNightMode > 0 ? '#FFF':'#16ab39'" width="50" height="50">
|
||||
<rect x="25" y="25" :fill="$store.getters.getIsNightMode > 0 ? '#FFF':'var(--main-accent)'" width="50" height="50">
|
||||
<animate
|
||||
attributeName="height"
|
||||
dur="1.3s"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
|
||||
<template>
|
||||
|
||||
<div v-on:keyup.enter="login()">
|
||||
@@ -14,6 +15,11 @@
|
||||
<input v-model="password" type="password" name="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="field" v-if="require2FA">
|
||||
<div class="ui input">
|
||||
<input v-model="authToken" ref="authForm" type="text" name="authToken" placeholder="Authorization Token">
|
||||
</div>
|
||||
</div>
|
||||
<div class="sixteen wide field">
|
||||
<div class="ui fluid buttons">
|
||||
<div :class="{ 'disabled':(username.length == 0 || password.length == 0)}" v-on:click="login()" class="ui green button">
|
||||
@@ -27,34 +33,54 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sixteen wide column">
|
||||
<span class="small-terms">
|
||||
By signing up you agree to Solid Scribe's
|
||||
<router-link to="/help">
|
||||
Terms of Use
|
||||
</router-link>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Thin form display -->
|
||||
<div v-if="thin" class="ui small form">
|
||||
<div class="fields">
|
||||
<div class="four wide field">
|
||||
<div class="equal width fields">
|
||||
<div class="field">
|
||||
<div class="ui input">
|
||||
<input ref="nameForm" v-model="username" type="text" name="email" placeholder="Username or E-mail">
|
||||
</div>
|
||||
</div>
|
||||
<div class="four wide field">
|
||||
<div class="field">
|
||||
<div class="ui input">
|
||||
<input v-model="password" type="password" name="password" placeholder="Password">
|
||||
</div>
|
||||
</div>
|
||||
<div class="four wide field">
|
||||
<div class="field" v-if="require2FA">
|
||||
<div class="ui input">
|
||||
<input v-model="authToken" ref="authForm" type="text" name="authToken" placeholder="Authorization Token">
|
||||
</div>
|
||||
</div>
|
||||
<!-- hide this field if someone is logging in with 2FA -->
|
||||
<div class="field" v-if="!require2FA">
|
||||
<div v-on:click="register()" class="ui fluid green button">
|
||||
<i class="plug icon"></i>
|
||||
Sign Up
|
||||
</div>
|
||||
</div>
|
||||
<div class="four wide field">
|
||||
<div class="field">
|
||||
<div v-on:click="login()" class="ui fluid button">
|
||||
<i class="power icon"></i>
|
||||
Login
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="small-terms">
|
||||
By signing up you agree to Solid Scribe's
|
||||
<router-link to="/help">
|
||||
Terms of Use
|
||||
</router-link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -83,7 +109,9 @@
|
||||
return {
|
||||
enabled: false,
|
||||
username: '',
|
||||
password: ''
|
||||
password: '',
|
||||
authToken: '',
|
||||
require2FA: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -139,14 +167,30 @@
|
||||
return
|
||||
}
|
||||
|
||||
axios.post('/api/user/login', {'username': this.username, 'password': this.password})
|
||||
axios.post('/api/user/login', {'username': this.username, 'password': this.password, 'authToken':this.authToken })
|
||||
.then(({data}) => {
|
||||
|
||||
if(data == false){
|
||||
this.$bus.$emit('notification', 'Unable to Login - Incorrect Username or Password')
|
||||
//Enable 2FA on form
|
||||
if(data.success == false && data.verificationRequired == true && this.require2FA == false){
|
||||
this.$bus.$emit('notification', data.message)
|
||||
this.require2FA = true
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.authForm.focus()
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.finalizeLogin(data)
|
||||
if(data.success == false){
|
||||
this.$bus.$emit('notification', data.message)
|
||||
return
|
||||
}
|
||||
|
||||
if(data.success){
|
||||
this.finalizeLogin(data)
|
||||
return
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
this.$bus.$emit('notification', 'Unable to Login - Incorrect Username or Password')
|
||||
@@ -154,4 +198,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style type="text/css" scoped="true">
|
||||
.small-terms {
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
80
client/src/components/LogoComponent.vue
Normal file
80
client/src/components/LogoComponent.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 132.29166 132.29167"
|
||||
height="500"
|
||||
width="500">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
style="display:inline"
|
||||
transform="translate(0,-164.70832)"
|
||||
id="layer1">
|
||||
<path
|
||||
class="darken-accent"
|
||||
id="path3813-4"
|
||||
d="m 56.22733,165.36641 -55.56249926,15.875 8e-7,63.5 47.62499846,11.90625 v 27.78125 l -47.76066333,-13.9757 0.13566407,10.00695 55.56249926,15.875 v -47.625 l -47.6249985,-11.90625 -8e-7,-47.625 47.7606633,-13.94121 c 0.135664,-2.30629 -0.135664,-9.87129 -0.135664,-9.87129 z"
|
||||
:style="`fill:${displayColor};fill-opacity:1;stroke:none;stroke-width:0.5291667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1`" />
|
||||
<path
|
||||
class="brighten-accent"
|
||||
id="path4563"
|
||||
d="m 20.508581,220.92891 c 15.265814,-14.23899 27.809717,-7.68002 39.687499,3.96875 v -7.9375 C 51.75093,200.8366 37.512584,206.01499 20.508581,205.05391 Z"
|
||||
:style="`fill:${displayColor};fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1`" />
|
||||
<path
|
||||
class="brighten-accent"
|
||||
id="path4563-6"
|
||||
d="m 111.78985,220.92891 c -15.265834,-14.23899 -27.809737,-7.68002 -39.68752,3.96875 v -7.9375 c 8.445151,-16.12356 22.683497,-10.94517 39.68752,-11.90625 z"
|
||||
:style="`display:inline;fill:${displayColor};fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1`" />
|
||||
<path
|
||||
class="brighten-accent"
|
||||
id="path3813-4-2"
|
||||
d="m 76.07108,165.36641 55.5625,15.875 v 63.5 l -47.625,11.90625 v 27.78125 l 47.76067,-13.9757 -0.13567,10.00695 -55.5625,15.875 v -47.625 l 47.625,-11.90626 V 189.17891 L 75.93542,175.2377 c -0.13567,-2.30629 0.13566,-9.87129 0.13566,-9.87129 z"
|
||||
:style="`display:inline;fill:${displayColor};fill-opacity:1;stroke:none;stroke-width:0.52916676;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1`" />
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'LoadingIcon',
|
||||
props:[ 'color' ],
|
||||
data(){
|
||||
return {
|
||||
displayColor: '#21BA45', //Default green color
|
||||
}
|
||||
},
|
||||
created(){
|
||||
//Set color if passed
|
||||
if(this.color){
|
||||
this.displayColor = this.color
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style type="text/css" scoped>
|
||||
.darken-accent {
|
||||
filter: brightness(62%);
|
||||
}
|
||||
.brighten-accent {
|
||||
filter: saturate(145%);
|
||||
}
|
||||
</style>
|
@@ -2,9 +2,8 @@
|
||||
<!-- change class to .master-note-edit to have it popup on the screen -->
|
||||
<div
|
||||
id="InputNotes"
|
||||
class="master-note-edit full-focus"
|
||||
@keyup.esc="close()"
|
||||
:class="[ 'position-'+position ]"
|
||||
class="master-note-edit full-focus position-0"
|
||||
@keyup.esc="closeButtonAction()"
|
||||
>
|
||||
|
||||
<!-- Giant Edit Note Menu -->
|
||||
@@ -14,7 +13,7 @@
|
||||
<div class="edit-spacer"></div>
|
||||
|
||||
<div class="menu-top-half">
|
||||
<div class="edit-button" v-on:click="close()" data-tooltip="Close" data-position="bottom center" data-inverted>
|
||||
<div class="edit-button" v-on:click="closeButtonAction()" data-tooltip="Close" data-position="bottom center" data-inverted>
|
||||
<i class="close icon"></i>
|
||||
</div>
|
||||
|
||||
@@ -61,7 +60,19 @@
|
||||
</div>
|
||||
|
||||
<div class="menu-bottom-half">
|
||||
|
||||
<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/table`)" data-tooltip="Insert Table" data-position="bottom center" data-inverted>
|
||||
<i class="border all icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="edit-button" v-on:click="insertDivide()" data-tooltip="Insert Divide" data-position="bottom center" data-inverted>
|
||||
<i class="grip lines icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="edit-button" v-on:click="insertTable(4,4)" data-tooltip="Insert Table" data-position="bottom center" data-inverted>
|
||||
<i class="book dead icon"></i>
|
||||
</div>
|
||||
|
||||
<div class="edit-button" v-on:click="removeFormatting()" data-tooltip="Remove Formatting" data-position="bottom center" data-inverted>
|
||||
<i class="remove format icon"></i>
|
||||
</div>
|
||||
@@ -95,7 +106,8 @@
|
||||
|
||||
<div class="edit-divide"></div>
|
||||
|
||||
<!-- <div class="edit-button" v-on:click="onToggleArchived()" :data-tooltip="archived == 1?'Move to main list':'Move to Archive'" data-position="bottom center" data-inverted>
|
||||
<!--
|
||||
<div class="edit-button" v-on:click="onToggleArchived()" :data-tooltip="archived == 1?'Move to main list':'Move to Archive'" data-position="bottom center" data-inverted>
|
||||
<span v-if="archived == 1"><i class="green archive icon"></i></span>
|
||||
<span v-if="archived != 1"><i class="archive icon"></i></span>
|
||||
</div>
|
||||
@@ -105,17 +117,13 @@
|
||||
<span v-if="pinned != 1"><i class="pin icon"></i></span>
|
||||
</div> -->
|
||||
|
||||
<!-- data-tooltip="Files on note" -->
|
||||
<!-- <div v-if="attachmentCount > 0" class="edit-button" v-on:click="openEditAttachment" data-tooltip="Files" data-position="bottom center" data-inverted>
|
||||
<i class="folder icon"></i>
|
||||
{{ attachmentCount }}
|
||||
</div> -->
|
||||
|
||||
<div class="edit-button" v-if="usersOnNote > 1">
|
||||
<i class="green eye icon"></i> {{ usersOnNote }}
|
||||
</div>
|
||||
|
||||
<!-- <div class="edit-button" v-on:click="simulateTyping()">
|
||||
<!--
|
||||
<div class="edit-button" v-on:click="simulateTyping()">
|
||||
<i class="purple bolt icon"></i>
|
||||
</div> -->
|
||||
|
||||
@@ -132,7 +140,6 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="bottom-edit-menu"></div>
|
||||
@@ -163,7 +170,7 @@
|
||||
</textarea>
|
||||
|
||||
<!-- Squire Box -->
|
||||
<div id="squire-id" class="squire-box" ref="squirebox" placeholder="Note Text"></div>
|
||||
<div id="squire-id" class="squire-box" ref="squirebox" placeholder="Type Note Here"></div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -224,19 +231,19 @@
|
||||
<div class="sixteen wide column">
|
||||
<div class="ui labeled icon fluid basic button" v-on:click="sortList">
|
||||
<i class="sort amount up icon"></i>
|
||||
Sort List items (Move checked to bottom)
|
||||
Sort List
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<div class="ui labeled icon fluid basic button" v-on:click="deleteCompletedListItems">
|
||||
<i class="trash icon"></i>
|
||||
Delete Checked Items
|
||||
Delete Checked
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<div class="ui labeled icon fluid basic button" v-on:click="uncheckAllListItems">
|
||||
<i class="list ul icon"></i>
|
||||
Uncheck all Checked items
|
||||
Uncheck All
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
@@ -245,6 +252,15 @@
|
||||
Simple Math
|
||||
</div>
|
||||
</div>
|
||||
<div class="eight wide column">
|
||||
<!-- data-tooltip="Files on note" -->
|
||||
<div v-on:click="openEditAttachment" class="ui labeled icon fluid basic button">
|
||||
<i class="folder icon"></i>
|
||||
Note Files
|
||||
{{ attachmentCount }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sixteen wide column" v-if="rawTextId > 0">
|
||||
<h2>Share Note</h2>
|
||||
<share-note-component
|
||||
@@ -257,13 +273,20 @@
|
||||
</div>
|
||||
</side-slide-menu>
|
||||
|
||||
<!-- create table option -->
|
||||
<side-slide-menu v-if="table" v-on:close="table = false; fetchNoteTags()" name="table" :style-object="styleObject">
|
||||
<div class="ui basic segment">
|
||||
Create a table
|
||||
</div>
|
||||
</side-slide-menu>
|
||||
|
||||
<!-- Show side shades if user is on desktop only -->
|
||||
<div class="full-focus-shade shade1"
|
||||
:class="{ 'slide-out-left':sizeDown }"
|
||||
v-on:click="close()"></div>
|
||||
v-on:click="closeButtonAction()"></div>
|
||||
<div class="full-focus-shade shade2"
|
||||
:class="{ 'slide-out-right':sizeDown }"
|
||||
v-on:click="close()"></div>
|
||||
v-on:click="closeButtonAction()"></div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
@@ -335,6 +358,7 @@
|
||||
images: false,
|
||||
options: false,
|
||||
colorpicker: false,
|
||||
table: false,
|
||||
|
||||
//Diff text/sync text variables
|
||||
diffTextTimeout: null,
|
||||
@@ -355,7 +379,7 @@
|
||||
//Handle changes in URL to
|
||||
|
||||
if(newVal.id == undefined || newVal.id != this.noteid){
|
||||
this.close()
|
||||
// this.closeButtonAction()
|
||||
}
|
||||
|
||||
//Reset all note menus on URL change
|
||||
@@ -364,6 +388,7 @@
|
||||
this.tags = false
|
||||
this.options = false
|
||||
this.images = false
|
||||
this.table = false
|
||||
|
||||
//If a menu value is set, open it
|
||||
if(newVal.openMenu){
|
||||
@@ -394,18 +419,20 @@
|
||||
|
||||
document.removeEventListener('visibilitychange', this.checkForUpdatedNote)
|
||||
|
||||
// if(this.editor){
|
||||
this.editor.destroy()
|
||||
// }
|
||||
//Obliterate squire instance
|
||||
this.editor.destroy()
|
||||
|
||||
this.close()
|
||||
|
||||
},
|
||||
mounted: function() {
|
||||
|
||||
//Show loading for a minimum time
|
||||
setTimeout(()=>{
|
||||
this.forceShowLoading = false
|
||||
}, 500)
|
||||
|
||||
document.addEventListener('visibilitychange', this.checkForUpdatedNote)
|
||||
// document.addEventListener('visibilitychange', this.checkForUpdatedNote)
|
||||
|
||||
//Init squire as early as possible
|
||||
this.editor = new Squire( this.$refs.squirebox, {blockTag: 'p' })
|
||||
@@ -599,6 +626,30 @@
|
||||
|
||||
this.editor.addEventListener('keydown', event => {
|
||||
|
||||
//Tab to increase quote level, tab + shigt to decrease quote level
|
||||
const keyCode = event.key
|
||||
if(keyCode == 'Tab'){
|
||||
|
||||
if(event.shiftKey){
|
||||
this.editor.decreaseQuoteLevel()
|
||||
} else {
|
||||
this.editor.increaseQuoteLevel()
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
return false
|
||||
}
|
||||
|
||||
//Save on pressing CTRL/CMD + S
|
||||
if(keyCode == 's' && (event.ctrlKey || event.metaKey) ){
|
||||
|
||||
this.$bus.$emit('notification', 'Note Saved')
|
||||
this.save()
|
||||
|
||||
event.preventDefault()
|
||||
return false
|
||||
}
|
||||
|
||||
//Prevent new list items from having
|
||||
this.$nextTick( () => {
|
||||
//Wait a moment to get item under cursor
|
||||
@@ -612,10 +663,6 @@
|
||||
})
|
||||
})
|
||||
|
||||
this.editor.addEventListener('keydown', event => {
|
||||
|
||||
})
|
||||
|
||||
//Bind event handlers
|
||||
this.editor.addEventListener('keyup', event => {
|
||||
|
||||
@@ -682,7 +729,7 @@
|
||||
//Block notes you don't have access to from opening
|
||||
if(response.data === false){
|
||||
this.$bus.$emit('notification', 'Error opening Note')
|
||||
this.close(true)
|
||||
this.close()
|
||||
return
|
||||
}
|
||||
|
||||
@@ -915,18 +962,21 @@
|
||||
|
||||
return hash;
|
||||
},
|
||||
close(force = false){
|
||||
closeButtonAction(){
|
||||
this.sizeDown = true
|
||||
//This timeout allows animation to play before closing
|
||||
setTimeout(() => {
|
||||
this.$router.push('/notes')
|
||||
}, 300)
|
||||
},
|
||||
close(){
|
||||
|
||||
// force = true
|
||||
|
||||
// console.log(`Close Note ${this.noteid} -> force: ${force}, modified: ${this.modified}`)
|
||||
|
||||
if(force){
|
||||
this.$bus.$emit('close_active_note', {
|
||||
noteId: this.noteid, modified: this.modified
|
||||
})
|
||||
return
|
||||
}
|
||||
//Skip everything if foce close is true. Note will just die.
|
||||
if(this.currentNoteId == 0){ return }
|
||||
|
||||
this.loadingMessage = 'Saving...'
|
||||
this.loading = true
|
||||
@@ -938,14 +988,10 @@
|
||||
axios.post('/api/note/reindex')
|
||||
}
|
||||
|
||||
this.sizeDown = true
|
||||
//This timeout allows animation to play before closing
|
||||
setTimeout(() => {
|
||||
this.$bus.$emit('close_active_note', {
|
||||
noteId: this.noteid, modified: this.modified
|
||||
})
|
||||
return
|
||||
}, 300)
|
||||
this.$bus.$emit('close_active_note', {
|
||||
noteId: this.noteid, modified: this.modified
|
||||
})
|
||||
return
|
||||
})
|
||||
},
|
||||
destroyWebSockets(){
|
||||
@@ -1005,8 +1051,8 @@
|
||||
let element = this.$refs.titleTextarea
|
||||
let padding = 0
|
||||
|
||||
element.style.height = 'auto';
|
||||
element.style.height = (element.scrollHeight + padding) +'px';
|
||||
element.style.height = 'auto'
|
||||
element.style.height = (element.scrollHeight + padding) +'px'
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1152,7 +1198,7 @@
|
||||
background-color: var(--menu-accent);
|
||||
}
|
||||
.edit-active {
|
||||
background-color: #21BA45;
|
||||
background-color: var(--main-accent);
|
||||
color: white;
|
||||
}
|
||||
.edit-divide {
|
||||
|
@@ -67,7 +67,7 @@
|
||||
</span>
|
||||
|
||||
<span class="time-ago-display" :class="{ 'hover-hide':(!$store.getters.getIsUserOnMobile) }">
|
||||
{{$helpers.timeAgo(note.updated)}}
|
||||
{{$helpers.timeAgo( note.updated )}}
|
||||
</span>
|
||||
|
||||
<span class="teeny-buttons" :class="{ 'hover-hide':(!$store.getters.getIsUserOnMobile) }">
|
||||
@@ -234,12 +234,12 @@
|
||||
},
|
||||
justClosed(){
|
||||
|
||||
//Scroll note into view
|
||||
// this.$el.scrollIntoView({
|
||||
// behavior: 'smooth',
|
||||
// block: 'center',
|
||||
// inline: 'center'
|
||||
// })
|
||||
// Scroll note into view
|
||||
this.$el.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'center'
|
||||
})
|
||||
|
||||
//After scroll, trigger green outline animation
|
||||
setTimeout(() => {
|
||||
@@ -356,13 +356,14 @@
|
||||
|
||||
/*Strict font sizes for card display*/
|
||||
.small-text {
|
||||
max-height: 261px;
|
||||
max-height: 267px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
.small-text, .small-text > p, .small-text > h1, .small-text > h2 {
|
||||
/*font-size: 1.0em !important;*/
|
||||
font-size: 16px !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.small-text > p, , .small-text > h1, .small-text > h2 {
|
||||
margin-bottom: 0.5em;
|
||||
@@ -370,7 +371,7 @@
|
||||
.big-text > p:first-child,
|
||||
.big-text > h1, .big-text > h2 {
|
||||
/*font-size: 1.3em !important;*/
|
||||
font-size: 17px !important;
|
||||
font-size: 20px !important;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
@@ -415,14 +416,14 @@
|
||||
border-color: var(--border_color);
|
||||
/*width: calc(33.333% - 10px);*/
|
||||
width: calc(25% - 10px);
|
||||
min-width: 190px;
|
||||
/*min-width: 190px;*/
|
||||
min-height: 130px;
|
||||
/*transition: box-shadow 0.3s;*/
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
|
||||
line-height: 1.8rem;
|
||||
letter-spacing: 0.02rem;
|
||||
letter-spacing: 0.05rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: left;
|
||||
@@ -555,27 +556,50 @@
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* Tweak mobile display to show only one column */
|
||||
@media only screen and (min-width: 1500px) {
|
||||
.note-title-display-card {
|
||||
width: calc(20% - 10px);
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 740px) {
|
||||
/* Break points determine when display cards shrink */
|
||||
@media only screen and (max-width: 700px) {
|
||||
.note-title-display-card {
|
||||
width: calc(100% + 10px);
|
||||
margin: 0px -5px 10px -5px;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 700px) and (max-width: 900px) {
|
||||
.note-title-display-card {
|
||||
width: calc(50% - 10px);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 900px) and (max-width: 1100px) {
|
||||
.note-title-display-card {
|
||||
width: calc(33.33333% - 10px);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1100px) and (max-width: 1300px) {
|
||||
.note-title-display-card {
|
||||
width: calc(25% - 10px);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1300px) and (max-width: 1800px) {
|
||||
.note-title-display-card {
|
||||
width: calc(20% - 10px);
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 1800px) {
|
||||
.note-title-display-card {
|
||||
width: calc(16.66666% - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*Animations for cool border effects*/
|
||||
@keyframes bgin {
|
||||
0% {
|
||||
background-image:
|
||||
linear-gradient(to right, #21BA45 50%, #21BA45 100%), /* TopLeft to Right */
|
||||
linear-gradient(to bottom, #21BA45 50%, #21BA45 100%), /* TopRight to Bottom */
|
||||
linear-gradient(to right, #21BA45 50%, #21BA45 100%), /* BottomLeft to Right*/
|
||||
linear-gradient(to bottom, #21BA45 50%, #21BA45 100%); /* TopLeft to Bottom */
|
||||
linear-gradient(to right, var(--main-accent) 50%, var(--main-accent) 100%), /* TopLeft to Right */
|
||||
linear-gradient(to bottom, var(--main-accent) 50%, var(--main-accent) 100%), /* TopRight to Bottom */
|
||||
linear-gradient(to right, var(--main-accent) 50%, var(--main-accent) 100%), /* BottomLeft to Right*/
|
||||
linear-gradient(to bottom, var(--main-accent) 50%, var(--main-accent) 100%); /* TopLeft to Bottom */
|
||||
/*Initial state, no BG*/
|
||||
background-size: 0 4px, 4px 0, 0 4px, 4px 0;
|
||||
}
|
||||
@@ -590,10 +614,10 @@
|
||||
30% {
|
||||
background-size: 100% 4px, 4px 100%, 100% 4px, 4px 100%;
|
||||
background-image:
|
||||
linear-gradient(to right, #21BA45 50%, #21BA45 100%), /* TopLeft to Right */
|
||||
linear-gradient(to bottom, #21BA45 50%, #21BA45 100%), /* TopRight to Bottom */
|
||||
linear-gradient(to right, #21BA45 50%, #21BA45 100%), /* BottomLeft to Right*/
|
||||
linear-gradient(to bottom, #21BA45 50%, #21BA45 100%); /* TopLeft to Bottom */
|
||||
linear-gradient(to right, var(--main-accent) 50%, var(--main-accent) 100%), /* TopLeft to Right */
|
||||
linear-gradient(to bottom, var(--main-accent) 50%, var(--main-accent) 100%), /* TopRight to Bottom */
|
||||
linear-gradient(to right, var(--main-accent) 50%, var(--main-accent) 100%), /* BottomLeft to Right*/
|
||||
linear-gradient(to bottom, var(--main-accent) 50%, var(--main-accent) 100%); /* TopLeft to Bottom */
|
||||
}
|
||||
100% {
|
||||
background-image:
|
||||
|
@@ -98,13 +98,17 @@
|
||||
},
|
||||
beforeCreate: function(){
|
||||
},
|
||||
mounted: function(){
|
||||
|
||||
beforeMount(){
|
||||
//search clear
|
||||
this.$bus.$on('reset_fast_filters', () => {
|
||||
this.searchTerm = ''
|
||||
this.tagSuggestions = []
|
||||
})
|
||||
},
|
||||
beforeDestroy(){
|
||||
this.$bus.$off('reset_fast_filters')
|
||||
},
|
||||
mounted: function(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
@@ -148,7 +152,6 @@
|
||||
|
||||
if(response.data && response.data.id){
|
||||
this.$router.push('/notes/open/'+response.data.id)
|
||||
this.$bus.$emit('open_note', response.data.id)
|
||||
}
|
||||
})
|
||||
.catch(error => { this.$bus.$emit('notification', 'Failed to create note') })
|
||||
|
Reference in New Issue
Block a user