Added rate limiting and server security
Ton of little visual style tweaks and little up improvements for mobile
This commit is contained in:
parent
749d2cea94
commit
ecbf6a9cde
@ -6,7 +6,7 @@ mkdir -p $BACKUPDIR
|
|||||||
cd $BACKUPDIR
|
cd $BACKUPDIR
|
||||||
|
|
||||||
NOW=$(date +"%Y-%m-%d_%H-%M")
|
NOW=$(date +"%Y-%m-%d_%H-%M")
|
||||||
ssh mab@avidhabit.com -p 13328 "mysqldump --all-databases --user root -p***REMOVED***" > "backup-$NOW.sql"
|
ssh mab@solidscribe.com -p 13328 "mysqldump --all-databases --user root -p***REMOVED***" > "backup-$NOW.sql"
|
||||||
|
|
||||||
cp "backup-$NOW.sql" "/mnt/Windows Data/DatabaseBackups/backup-$NOW.sql"
|
cp "backup-$NOW.sql" "/mnt/Windows Data/DatabaseBackups/backup-$NOW.sql"
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@ tar -czf release.tar.gz server node_modules client/dist staticFiles/assets
|
|||||||
|
|
||||||
#send compressed release to remote machine
|
#send compressed release to remote machine
|
||||||
echo -e "\e[32m\nMoving compressed release to production... \n\e[0m"
|
echo -e "\e[32m\nMoving compressed release to production... \n\e[0m"
|
||||||
rsync -e 'ssh -p 13328' -havzC --update release.tar.gz mab@avidhabit.com:/home/mab/pi/
|
rsync -e 'ssh -p 13328' -havzC --update release.tar.gz mab@solidscribe.com:/home/mab/pi/
|
||||||
|
|
||||||
# Remove Release from local after its been uploaded
|
# Remove Release from local after its been uploaded
|
||||||
rm release.tar.gz
|
rm release.tar.gz
|
||||||
|
|
||||||
#uncompress release on server
|
#uncompress release on server
|
||||||
echo -e "\e[32m\nExtracting release on production... \n\e[0m"
|
echo -e "\e[32m\nExtracting release on production... \n\e[0m"
|
||||||
ssh mab@avidhabit.com -p 13328 "cd /home/mab/pi/; rm -r server node_modules client; tar -xzf *.tar.gz --overwrite; rm *.tar.gz; pm2 reload all"
|
ssh mab@solidscribe.com -p 13328 "cd /home/mab/pi/; rm -r server node_modules client; tar -xzf *.tar.gz --overwrite; rm *.tar.gz; pm2 reload all"
|
||||||
|
|
||||||
#Congratulate how awesome you are
|
#Congratulate how awesome you are
|
||||||
echo -e "\e[32m\nRelease Complete! Nice Work! \n\e[0m"
|
echo -e "\e[32m\nRelease Complete! Nice Work! \n\e[0m"
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app" :class="{ 'night-mode':($store.getters.getIsNightMode) }">
|
||||||
|
|
||||||
<global-site-menu />
|
<global-site-menu />
|
||||||
|
|
||||||
|
@ -35,6 +35,14 @@ div.ui.basic.segment.no-fluf-segment {
|
|||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Night mode modifiers */
|
||||||
|
|
||||||
|
/*Make images sepia in night mode */
|
||||||
|
.night-mode img {
|
||||||
|
filter: grayscale(50%) brightness(80%) sepia(80%);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* OVERWRITE DEFAULT SEMANTIC STYLES FOR CUSTOM/NIGHT MODES*/
|
/* OVERWRITE DEFAULT SEMANTIC STYLES FOR CUSTOM/NIGHT MODES*/
|
||||||
body {
|
body {
|
||||||
color: var(--text_color);
|
color: var(--text_color);
|
||||||
@ -231,22 +239,27 @@ a:hover {
|
|||||||
.squire-box a {
|
.squire-box a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
/* .note-card-text i,
|
.note-card-text i:not(.icon),
|
||||||
.squire-box i {
|
.squire-box i {
|
||||||
padding: 0.5em 0.99em;
|
padding: 0.5em 0.99em;
|
||||||
border: 1px solid #CCC;
|
border-radius: 1px;
|
||||||
margin: 1px;
|
|
||||||
border-radius: 9px;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}*/
|
font-style: normal;
|
||||||
|
background-color: rgba(113, 113, 113, 0.1);
|
||||||
|
}
|
||||||
|
.night-mode .note-card-text i:not(.icon),
|
||||||
|
.night-mode .squire-box i {
|
||||||
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-card-text p,
|
||||||
.squire-box p {
|
.squire-box p {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
.note-card-text blockquote,
|
.note-card-text blockquote,
|
||||||
.squire-box blockquote {
|
.squire-box blockquote {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.8em;
|
padding: 0 0 0 2.5em;
|
||||||
border-left: 2px solid blue;
|
|
||||||
}
|
}
|
||||||
.note-card-text img {
|
.note-card-text img {
|
||||||
max-width:100%;
|
max-width:100%;
|
||||||
@ -305,6 +318,10 @@ a:hover {
|
|||||||
/* adjust checkboxes for mobile. Make them a little bigger, easier to click */
|
/* adjust checkboxes for mobile. Make them a little bigger, easier to click */
|
||||||
@media only screen and (max-width: 740px) {
|
@media only screen and (max-width: 740px) {
|
||||||
|
|
||||||
|
.ui.button.shrinking {
|
||||||
|
font-size: 0.85714286rem;
|
||||||
|
}
|
||||||
|
|
||||||
.note-card-text ul > li,
|
.note-card-text ul > li,
|
||||||
.squire-box ul > li {
|
.squire-box ul > li {
|
||||||
min-height: 30px;
|
min-height: 30px;
|
||||||
@ -346,6 +363,12 @@ a:hover {
|
|||||||
.float-right {
|
.float-right {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
.ui.grid.reduced-padding > .column {
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 2px;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.textarea-height {
|
.textarea-height {
|
||||||
height: calc(100% - 90px);
|
height: calc(100% - 90px);
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
.menu-logo-display {
|
||||||
|
width: 25px;
|
||||||
|
margin: 5px 0 0 34px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -101,31 +106,39 @@
|
|||||||
<i class="green bars icon"></i>
|
<i class="green bars icon"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<router-link class="ui large basic compact icon button" to="/notes" v-on:click.native="emitReloadEvent()">
|
<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>
|
<i class="green home icon"></i>
|
||||||
</router-link>
|
</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">
|
<div v-on:click="toggleNightMode" class="ui large basic compact icon button">
|
||||||
<i class="green moon outline icon"></i>
|
<i class="green moon outline icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="six wide center aligned column">
|
|
||||||
<img v-if="!loggedIn" src="/api/static/assets/favicon.ico" alt="logo" />
|
|
||||||
<search-input v-if="loggedIn && mobile"></search-input>
|
<search-input v-if="loggedIn && mobile"></search-input>
|
||||||
</div>
|
|
||||||
<div class="three wide right aligned column">
|
|
||||||
|
|
||||||
<!-- mobile create note button -->
|
<!-- mobile create note button -->
|
||||||
<div v-if="loggedIn">
|
<span v-if="loggedIn">
|
||||||
<div v-if="!disableNewNote" @click="createNote" class="ui large basic compact icon button">
|
<span v-if="!disableNewNote" @click="createNote" class="ui large basic compact icon button">
|
||||||
<i class="green plus icon"></i>
|
<i class="green plus icon"></i>
|
||||||
</div>
|
</span>
|
||||||
<div v-if="disableNewNote" class="ui large basic compact icon button">
|
<span v-if="disableNewNote" class="ui large basic compact icon button">
|
||||||
<i class="grey plus icon"></i>
|
<i class="grey plus icon"></i>
|
||||||
</div>
|
</span>
|
||||||
</div>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -136,10 +149,11 @@
|
|||||||
|
|
||||||
<div class="global-menu" v-if="!collapsed" v-on:click="menuClicked">
|
<div class="global-menu" v-if="!collapsed" v-on:click="menuClicked">
|
||||||
|
|
||||||
<div class="menu-section">
|
<div class="menu-section" v-on:click="collapseMenu">
|
||||||
<div class="menu-item menu-button" v-on:click="collapseMenu">
|
<!-- <div class="menu-item menu-button" > -->
|
||||||
<i class="angle left icon"></i>
|
<i class="white angle left icon"></i>
|
||||||
</div>
|
<img class="menu-logo-display" loading="lazy" src="/api/static/assets/logo.svg" alt="Solid Scribe Logo">
|
||||||
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="menu-section" v-if="loggedIn">
|
<div class="menu-section" v-if="loggedIn">
|
||||||
|
@ -19,23 +19,24 @@
|
|||||||
|
|
||||||
<div class="note-menu">
|
<div class="note-menu">
|
||||||
|
|
||||||
<nm-button v-on:click.native="close" icon="close" />
|
<nm-button tip="Close" bottom-tip="true" v-on:click.native="close" icon="close" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="toggleList('ol')" icon="list ol" />
|
<nm-button tip="Numbered List" bottom-tip="true" v-on:click.native="toggleList('ol')" icon="list ol" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="toggleList('ul')" icon="tasks" />
|
<nm-button tip="Task List" bottom-tip="true" v-on:click.native="toggleList('ul')" icon="tasks" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="toggleBold()" icon="bold" />
|
<nm-button tip="Bold" bottom-tip="true" v-on:click.native="toggleBold()" icon="bold" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="toggleItalic()" icon="quote left" />
|
<nm-button tip="Quote" bottom-tip="true" v-on:click.native="toggleItalic()" icon="quote left" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="modifyFont('1.4em')" icon="text height" />
|
<nm-button tip="Title" bottom-tip="true" v-on:click.native="modifyFont('1.4em')" icon="text height" />
|
||||||
|
|
||||||
<nm-button v-on:click.native="undoCustom()" icon="undo" />
|
<nm-button tip="Indent" bottom-tip="true" v-on:click.native="editor.increaseQuoteLevel()" icon="indent" />
|
||||||
|
|
||||||
<nm-button v-if="usersOnNote > 1" icon="green user circle" />
|
<nm-button tip="Outdent" bottom-tip="true" v-on:click.native="editor.decreaseQuoteLevel()" icon="outdent" />
|
||||||
|
|
||||||
|
<nm-button tip="Users on Note" bottom-tip="true" v-if="usersOnNote > 1" icon="green user circle" />
|
||||||
|
|
||||||
<nm-button icon="ellipsis horizontal" v-on:click.native="showNoteOptions = !showNoteOptions" />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Squire box grows -->
|
<!-- Squire box grows -->
|
||||||
@ -92,25 +93,52 @@
|
|||||||
|
|
||||||
<!-- bottom stats -->
|
<!-- bottom stats -->
|
||||||
<div class="ui basic segment">
|
<div class="ui basic segment">
|
||||||
<div class="ui grid">
|
<div class="ui grid reduced-padding">
|
||||||
<div class="sixteen wide column">
|
|
||||||
|
|
||||||
<div class="ui basic button"v-if="!isEncrypted" v-on:click="passwordEnterVisible = true">
|
<div class="four wide column">
|
||||||
|
<!-- Tags -->
|
||||||
|
<button class="ui compact basic fluid button shrinking" v-on:click="showTagSlideMenu = !showTagSlideMenu; modified = true">
|
||||||
|
<i class="tags icon"></i> Tags
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<!-- Archive Button -->
|
||||||
|
<button class="ui compact basic fluid button shrinking" v-on:click="onToggleArchived">
|
||||||
|
<span v-if="archived == 1"><i class="green archive icon"></i> Archived</span>
|
||||||
|
<span v-if="archived != 1"><i class="archive icon"></i> Archive</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="four wide column"><!-- Pin button -->
|
||||||
|
<button class="ui compact basic fluid button shrinking" v-on:click="onTogglePinned">
|
||||||
|
<span v-if="pinned == 1"><i class="green pin icon"></i> Pinned</span>
|
||||||
|
<span v-if="pinned != 1"><i class="pin icon"></i> Pin</span>
|
||||||
|
</button></div>
|
||||||
|
<div class="four wide column">
|
||||||
|
<!-- files button -->
|
||||||
|
<button class="ui compact basic fluid button shrinking" v-on:click="openEditAttachment">
|
||||||
|
<i class="folder icon"></i> Files
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="sixteen wide column"></div> -->
|
||||||
|
|
||||||
|
<div class="eight wide column">
|
||||||
|
|
||||||
|
<button class="ui basic compact button shrinking" v-if="!isEncrypted" v-on:click="passwordEnterVisible = true">
|
||||||
<i class="shield alternate icon"></i>
|
<i class="shield alternate icon"></i>
|
||||||
Password Protect
|
Password Protect
|
||||||
</div>
|
</button>
|
||||||
<div class="ui icon basic button" v-if="isEncrypted && isDecrypted" v-on:click="disableEncryption">
|
<button class="ui icon basic compact button shrinking" v-if="isEncrypted && isDecrypted" v-on:click="disableEncryption">
|
||||||
<i class="unlock icon"></i>
|
<i class="unlock icon"></i>
|
||||||
Remove Password
|
Remove Password
|
||||||
</div>
|
</button>
|
||||||
|
|
||||||
<div class="ui basic compact button">
|
|
||||||
Status: {{ statusText }}
|
|
||||||
</div>
|
|
||||||
<div class="ui basic compact button" :data-tooltip="`Created: ${$helpers.timeAgo(created)}`">
|
|
||||||
Last Change: {{ $helpers.timeAgo(updated) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="seven wide right aligned middle aligned column">
|
||||||
|
<span :data-tooltip="`Created: ${$helpers.timeAgo(created)}`">
|
||||||
|
Edited: {{ $helpers.timeAgo(updated) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="one wide column"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -127,30 +155,12 @@
|
|||||||
|
|
||||||
<div class="note-menu shrink-icons-on-mobile">
|
<div class="note-menu shrink-icons-on-mobile">
|
||||||
|
|
||||||
<!-- Pin Button -->
|
|
||||||
<nm-button
|
|
||||||
v-on:click.native="onToggleArchived"
|
|
||||||
:icon="(archived == 1)?'green archive':'archive'"
|
|
||||||
:text="(archived == 1)?'Archived':'Archive'"
|
|
||||||
tip="Show in archive"
|
|
||||||
:showText="true"
|
|
||||||
></nm-button>
|
|
||||||
|
|
||||||
<!-- archive button -->
|
|
||||||
<nm-button
|
|
||||||
v-on:click.native="onTogglePinned"
|
|
||||||
:icon="(pinned == 1)?'green pin':'pin'"
|
|
||||||
:text="(pinned == 1)?'Pinned':'Pin'"
|
|
||||||
tip="Pin to top of list"
|
|
||||||
:showText="true"
|
|
||||||
></nm-button>
|
|
||||||
|
|
||||||
<!-- colors button -->
|
<!-- colors button -->
|
||||||
<nm-button
|
<nm-button
|
||||||
v-on:click.native="showColorPicker"
|
v-on:click.native="showColorPicker"
|
||||||
icon="paint brush"
|
icon="paint brush"
|
||||||
text="Colors"
|
text="Color"
|
||||||
tip="Colors"
|
tip="Note Color"
|
||||||
></nm-button>
|
></nm-button>
|
||||||
|
|
||||||
<!-- add images panel -->
|
<!-- add images panel -->
|
||||||
@ -161,27 +171,18 @@
|
|||||||
tip="Images"
|
tip="Images"
|
||||||
></nm-button>
|
></nm-button>
|
||||||
|
|
||||||
<!-- Tags -->
|
|
||||||
<nm-button
|
|
||||||
v-on:click.native="showTagSlideMenu = !showTagSlideMenu; modified = true"
|
|
||||||
icon="tags"
|
|
||||||
text="Tags"
|
|
||||||
tip="Tags"
|
|
||||||
></nm-button>
|
|
||||||
|
|
||||||
<!-- file upload button -->
|
<!-- file upload button -->
|
||||||
<file-upload-button
|
<file-upload-button
|
||||||
class="nm-button"
|
class="nm-button"
|
||||||
:noteId="noteid" />
|
:noteId="noteid" />
|
||||||
|
|
||||||
<!-- files button -->
|
<nm-button v-on:click.native="undoCustom()" icon="undo" tip="Undo" text="Undo" />
|
||||||
|
|
||||||
<nm-button
|
<nm-button
|
||||||
v-on:click.native="openEditAttachment"
|
icon="ellipsis horizontal"
|
||||||
icon="folder"
|
text="Options"
|
||||||
text="Files"
|
tip="More Options"
|
||||||
tip="Files on Note"
|
v-on:click.native="showNoteOptions = !showNoteOptions" />
|
||||||
:showText="true"
|
|
||||||
></nm-button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -238,12 +239,6 @@
|
|||||||
Uncheck all Checked items
|
Uncheck all Checked items
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="eight wide column">
|
|
||||||
<div class="ui labeled icon fluid basic button" v-on:click="undoCustom">
|
|
||||||
<i class="undo icon"></i>
|
|
||||||
Undo last change
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="eight wide column">
|
<div class="eight wide column">
|
||||||
<div class="ui labeled icon fluid basic button" v-on:click="calculateMath" data-tooltip="Calculates algebra before '='">
|
<div class="ui labeled icon fluid basic button" v-on:click="calculateMath" data-tooltip="Calculates algebra before '='">
|
||||||
<i class="calculator icon"></i>
|
<i class="calculator icon"></i>
|
||||||
@ -251,6 +246,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sixteen wide column" v-if="rawTextId > 0">
|
<div class="sixteen wide column" v-if="rawTextId > 0">
|
||||||
|
<h2>Share Note</h2>
|
||||||
<share-note-component
|
<share-note-component
|
||||||
:note-id="noteid"
|
:note-id="noteid"
|
||||||
:raw-text-id="rawTextId"
|
:raw-text-id="rawTextId"
|
||||||
@ -274,7 +270,7 @@
|
|||||||
<h2><i class="green lock alternate icon"></i>Password protect this Note</h2>
|
<h2><i class="green lock alternate icon"></i>Password protect this Note</h2>
|
||||||
<p>Password protection will prevent anyone from reading the text of this note, unless they enter the correct password.</p>
|
<p>Password protection will prevent anyone from reading the text of this note, unless they enter the correct password.</p>
|
||||||
<p><b>Only the note text is protected. Title, tags, and files are not encrypted and remain visible without a password.</b></p>
|
<p><b>Only the note text is protected. Title, tags, and files are not encrypted and remain visible without a password.</b></p>
|
||||||
<p>The password you select will only be used for this note. You can use the same password on multiple notes. The note will be encrypted using the password entered. A longer password is will be more secure.</p>
|
<p>The password you select will only be used for this note. You can use the same password on multiple notes. The note will be encrypted using the password entered. A longer password will be more secure.</p>
|
||||||
<h4><i class="red icon exclamation triangle"></i> Warning. There is no way to recover a lost password.</h4>
|
<h4><i class="red icon exclamation triangle"></i> Warning. There is no way to recover a lost password.</h4>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="nm-button" :class="moreClass" :data-tooltip="tip" data-inverted>
|
<div class="nm-button" :class="moreClass" :data-tooltip="tip" data-inverted :data-position=" bottomTip?'bottom center':'top center'">
|
||||||
<!-- Display Icon and text -->
|
<!-- Display Icon and text -->
|
||||||
<i v-if="icon" :class="`${icon} icon`"></i>
|
<i v-if="icon" :class="`${icon} icon`"></i>
|
||||||
<span v-if="(text && mobile) || (text && showText)">{{text}}</span>
|
<span v-if="(text && mobile) || (text && showText)">{{text}}</span>
|
||||||
@ -21,12 +21,11 @@
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NoteMenuButtonComponent',
|
name: 'NoteMenuButtonComponent',
|
||||||
props: [ 'icon', 'text', 'tooltip', 'moreClass', 'showText', 'tip'],
|
props: [ 'icon', 'text', 'tooltip', 'moreClass', 'showText', 'tip', 'bottomTip'],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
files: [],
|
files: [],
|
||||||
mobile: false,
|
mobile: false,
|
||||||
showTooltip: false,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount(){
|
beforeMount(){
|
||||||
|
@ -1,10 +1,46 @@
|
|||||||
|
<style type="text/css" scoped>
|
||||||
|
.fixed-search {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<template>
|
<template>
|
||||||
<div class="ui form">
|
<span>
|
||||||
<div class="ui left icon fluid input">
|
|
||||||
<input v-model="searchTerm" @keyup="searchKeyUp" @:keyup.enter="search" placeholder="Search Notes and Files" />
|
<div class="ui form" v-if="!$store.getters.getIsUserOnMobile">
|
||||||
<i class="search icon"></i>
|
<!-- normal search menu -->
|
||||||
|
<div class="ui left icon fluid input">
|
||||||
|
<input v-model="searchTerm" @keyup="searchKeyUp" @keyup.enter="search" placeholder="Search Notes and Files" ref="searchInput"/>
|
||||||
|
<i class="search icon"></i>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<span class="ui basic icon button" v-on:click="openFloatingSearch">
|
||||||
|
<i class="green search icon"></i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="fixed-search" v-if="showFixedSearch">
|
||||||
|
<div class="ui raised segment">
|
||||||
|
<h2 class="ui center aligned header">Search!</h2>
|
||||||
|
<div class="ui form">
|
||||||
|
<div class="ui left icon fluid input">
|
||||||
|
<input
|
||||||
|
ref="fixedSearch"
|
||||||
|
v-model="searchTerm"
|
||||||
|
@keyup.enter="search"
|
||||||
|
v-on:blur="showFixedSearch = false"
|
||||||
|
placeholder="Press Enter to Search" />
|
||||||
|
<i class="search icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -16,6 +52,7 @@
|
|||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
searchTimeout: null,
|
searchTimeout: null,
|
||||||
searchDebounceDuration: 300,
|
searchDebounceDuration: 300,
|
||||||
|
showFixedSearch: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeCreate: function(){
|
beforeCreate: function(){
|
||||||
@ -29,13 +66,27 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
openFloatingSearch(){
|
||||||
|
this.showFixedSearch = !this.showFixedSearch
|
||||||
|
|
||||||
|
if(this.showFixedSearch){
|
||||||
|
this.$nextTick( () => {
|
||||||
|
this.searchTerm = ''
|
||||||
|
this.$refs.fixedSearch.focus()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
searchKeyUp(){
|
searchKeyUp(){
|
||||||
|
//This event is not triggered on mobile
|
||||||
clearTimeout(this.searchTimeout)
|
clearTimeout(this.searchTimeout)
|
||||||
this.searchTimeout = setTimeout(() => {
|
this.searchTimeout = setTimeout(() => {
|
||||||
this.search()
|
this.search()
|
||||||
}, this.searchDebounceDuration)
|
}, this.searchDebounceDuration)
|
||||||
},
|
},
|
||||||
search(){
|
search(){
|
||||||
|
if(this.$store.getters.getIsUserOnMobile){
|
||||||
|
this.$refs.fixedSearch.blur()
|
||||||
|
}
|
||||||
this.$bus.$emit('update_search_term', this.searchTerm)
|
this.$bus.$emit('update_search_term', this.searchTerm)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ui basic segment no-fluf-segment" ref="content">
|
<div class="ui basic segment no-fluf-segment" ref="content">
|
||||||
<div class="ui grid">
|
<div class="ui stacking grid">
|
||||||
|
|
||||||
<div class="ui twelve wide column">
|
<div class="sixteen wide column">
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
<i class="folder open outline icon"></i>
|
<i class="folder open outline icon"></i>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<!-- subnav -->
|
<!-- subnav -->
|
||||||
<router-link
|
<router-link
|
||||||
exact-active-class="green"
|
exact-active-class="green"
|
||||||
class="ui basic button"
|
class="ui basic button shrinking"
|
||||||
to="/attachments">
|
to="/attachments">
|
||||||
<i class="open folder outline icon"></i>
|
<i class="open folder outline icon"></i>
|
||||||
All
|
All
|
||||||
@ -22,7 +22,7 @@
|
|||||||
<router-link
|
<router-link
|
||||||
v-if="$store.getters.totals && $store.getters.totals['linkFiles']"
|
v-if="$store.getters.totals && $store.getters.totals['linkFiles']"
|
||||||
exact-active-class="green"
|
exact-active-class="green"
|
||||||
class="ui basic button"
|
class="ui basic button shrinking"
|
||||||
to="/attachments/type/links">
|
to="/attachments/type/links">
|
||||||
<i class="linkify icon"></i>
|
<i class="linkify icon"></i>
|
||||||
Links
|
Links
|
||||||
@ -30,16 +30,13 @@
|
|||||||
<router-link
|
<router-link
|
||||||
v-if="$store.getters.totals && $store.getters.totals['otherFiles']"
|
v-if="$store.getters.totals && $store.getters.totals['otherFiles']"
|
||||||
exact-active-class="green"
|
exact-active-class="green"
|
||||||
class="ui basic button"
|
class="ui basic button shrinking"
|
||||||
to="/attachments/type/files">
|
to="/attachments/type/files">
|
||||||
<i class="copy icon"></i>
|
<i class="copy icon"></i>
|
||||||
Other Files
|
Other Files
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide bottom aligned column">
|
|
||||||
<i v-if="loading" class="green sync alternate loading icon"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sixteen wide column" v-if="searchParams.noteId">
|
<div class="sixteen wide column" v-if="searchParams.noteId">
|
||||||
<router-link class="ui green button" to="/attachments">
|
<router-link class="ui green button" to="/attachments">
|
||||||
@ -50,6 +47,8 @@
|
|||||||
<i class="file outline icon"></i>
|
<i class="file outline icon"></i>
|
||||||
Open Note
|
Open Note
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<i v-if="loading" class="green sync alternate loading icon"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sixteen wide column" v-if="searchParams['noteId'] && attachments.length == 0">
|
<div class="sixteen wide column" v-if="searchParams['noteId'] && attachments.length == 0">
|
||||||
|
@ -11,12 +11,16 @@
|
|||||||
-moz-animation: fadeorama 16s ease infinite;
|
-moz-animation: fadeorama 16s ease infinite;
|
||||||
animation: fadeorama 16s ease infinite;
|
animation: fadeorama 16s ease infinite;
|
||||||
}
|
}
|
||||||
|
.logo-display {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
.lightly-padded {
|
.lightly-padded {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
.massive-text {
|
.massive-text {
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 4rem;
|
font-size: 4rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.blinking {
|
.blinking {
|
||||||
animation:blinkingText 1.5s linear infinite;
|
animation:blinkingText 1.5s linear infinite;
|
||||||
@ -63,6 +67,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*safari fix - prevents page from being below the menu */
|
/*safari fix - prevents page from being below the menu */
|
||||||
|
.green-text {
|
||||||
|
color: #3710a4;
|
||||||
|
}
|
||||||
.dont-pad-me {
|
.dont-pad-me {
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
@ -101,13 +108,18 @@
|
|||||||
|
|
||||||
<!-- desktop column - large screen only -->
|
<!-- desktop column - large screen only -->
|
||||||
<div class="seven wide middle aligned left aligned column">
|
<div class="seven wide middle aligned left aligned column">
|
||||||
<h2 class="massive-text">Take Notes, <br>Like Never Before</h2>
|
|
||||||
|
<h2 class="massive-text">
|
||||||
|
<img class="logo-display" loading="lazy" src="/api/static/assets/logo.svg" alt="Solid Scribe Logo">
|
||||||
|
<br>
|
||||||
|
Solid Scribe
|
||||||
|
</h2>
|
||||||
|
|
||||||
<h3 class="subtext">
|
<h3 class="subtext">
|
||||||
Using an online note application <i class="i cursor icon blinking"></i>
|
Take Notes Like Never Before<i class="i cursor icon blinking"></i>
|
||||||
</h3>
|
</h3>
|
||||||
<p>Assuming you have never used a note application previously in your life.</p>
|
<p class="green-text">Assuming you have never used a note application previously in your life.</p>
|
||||||
<br>
|
|
||||||
<i class="huge inverted chevron circle down icon"></i>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="eight wide middle aligned left aligned column">
|
<div class="eight wide middle aligned left aligned column">
|
||||||
@ -269,7 +281,6 @@
|
|||||||
<p>
|
<p>
|
||||||
If you see anything broken or want to see a feature implemented, I'm open to suggestions. <i class="thumbs up icon"></i>
|
If you see anything broken or want to see a feature implemented, I'm open to suggestions. <i class="thumbs up icon"></i>
|
||||||
</p>
|
</p>
|
||||||
<p>Hero Slide Photo Credit - <a target="_blank" href="https://unsplash.com/@tkaslik14">https://unsplash.com/@tkaslik14</a></p>
|
|
||||||
<p>Generic Marketing Images - <a target="_blank" href="https://undraw.co/">https://unDraw.co/</a></p>
|
<p>Generic Marketing Images - <a target="_blank" href="https://undraw.co/">https://unDraw.co/</a></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="four wide column">
|
<div class="four wide column">
|
||||||
@ -291,15 +302,14 @@ export default {
|
|||||||
realInformation: false,
|
realInformation: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount(){
|
beforeCreate(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Force HTTPS on prod, always. Dev doesn't have certs
|
//Force HTTPS on prod, always. Dev doesn't have certs
|
||||||
const isDev = process.env['NODE_ENV'] == 'development'
|
const isDev = process.env['NODE_ENV'] == 'development'
|
||||||
if (!isDev && location.protocol != 'https:'){
|
if (!isDev && location.protocol != 'https:'){
|
||||||
window.location.replace('https://www.avidhabit.com')
|
window.location.replace('https://www.solidscribe.com')
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeMount(){
|
||||||
|
|
||||||
//Don't change hero banner on mobile
|
//Don't change hero banner on mobile
|
||||||
if(!this.$store.getters.getIsUserOnMobile){
|
if(!this.$store.getters.getIsUserOnMobile){
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<div class="ten wide column" :class="{ 'sixteen wide column':$store.getters.getIsUserOnMobile }">
|
<div class="ten wide column" :class="{ 'sixteen wide column':$store.getters.getIsUserOnMobile }">
|
||||||
|
|
||||||
<div class="ui basic button"
|
<div class="ui basic button shrinking"
|
||||||
v-on:click="updateFastFilters(3)"
|
v-on:click="updateFastFilters(3)"
|
||||||
v-if="$store.getters.totals && ($store.getters.totals['sharedToNotes'] > 0 || $store.getters.totals['sharedFromNotes'] > 0)"
|
v-if="$store.getters.totals && ($store.getters.totals['sharedToNotes'] > 0 || $store.getters.totals['sharedFromNotes'] > 0)"
|
||||||
style="position: relative;">
|
style="position: relative;">
|
||||||
@ -24,12 +24,12 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui basic button" v-on:click="updateFastFilters(2)" v-if="$store.getters.totals && $store.getters.totals['archivedNotes'] > 0">
|
<div class="ui basic button shrinking" v-on:click="updateFastFilters(2)" v-if="$store.getters.totals && $store.getters.totals['archivedNotes'] > 0">
|
||||||
<i class="green archive icon"></i>Archived
|
<i class="green archive icon"></i>Archived
|
||||||
<!-- <span>{{ $store.getters.totals['archivedNotes'] }}</span> -->
|
<!-- <span>{{ $store.getters.totals['archivedNotes'] }}</span> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui basic button" v-on:click="updateFastFilters(4)" v-if="$store.getters.totals && $store.getters.totals['encryptedNotes'] > 0">
|
<div class="ui basic button shrinking" v-on:click="updateFastFilters(4)" v-if="$store.getters.totals && $store.getters.totals['encryptedNotes'] > 0">
|
||||||
<i class="green lock alternate icon"></i>Locked
|
<i class="green lock alternate icon"></i>Locked
|
||||||
<!-- <span>{{ $store.getters.totals['encryptedNotes'] }}</span> -->
|
<!-- <span>{{ $store.getters.totals['encryptedNotes'] }}</span> -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -12,8 +12,11 @@
|
|||||||
"body-parser": "^1.18.3",
|
"body-parser": "^1.18.3",
|
||||||
"cheerio": "^1.0.0-rc.3",
|
"cheerio": "^1.0.0-rc.3",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
|
"express-rate-limit": "^5.1.1",
|
||||||
"gm": "^1.23.1",
|
"gm": "^1.23.1",
|
||||||
|
"helmet": "^3.21.3",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
|
"module-alias": "^2.2.2",
|
||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"mysql2": "^1.6.5",
|
"mysql2": "^1.6.5",
|
||||||
"node-tesseract-ocr": "^1.0.0",
|
"node-tesseract-ocr": "^1.0.0",
|
||||||
|
@ -26,6 +26,17 @@ ProcessText.stripBlankHtmlLines = (string) => {
|
|||||||
return string.replace(/\<p\>\<br\>\<\/p\>/g,'')
|
return string.replace(/\<p\>\<br\>\<\/p\>/g,'')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Remove Double Empty HTML lines from a string
|
||||||
|
ProcessText.stripDoubleBlankLines = (string) => {
|
||||||
|
|
||||||
|
if(string == undefined || string == null || string.length == 0){
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
//Blank lines look like this -> <p><br></p>
|
||||||
|
return string.replace(/\<p\>\<br\>\<\/p\>\<p\>\<br\>\<\/p\>/g,'')
|
||||||
|
}
|
||||||
|
|
||||||
ProcessText.getUrlsFromString = (string) => {
|
ProcessText.getUrlsFromString = (string) => {
|
||||||
const urlPattern = /(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[A-Z0-9+&@#/%=~_|$])/igm
|
const urlPattern = /(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[A-Z0-9+&@#/%=~_|$])/igm
|
||||||
return string.match(urlPattern)
|
return string.match(urlPattern)
|
||||||
@ -41,11 +52,16 @@ ProcessText.getUrlsFromString = (string) => {
|
|||||||
+ If note starts as a list, skip the title
|
+ If note starts as a list, skip the title
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ProcessText.deduceNoteTitle = (inString) => {
|
ProcessText.deduceNoteTitle = (inTitle, inString) => {
|
||||||
|
|
||||||
let title = '' //Title of note
|
let title = inTitle //Title of note
|
||||||
let sub = '' //sub text below note
|
let sub = '' //sub text below note
|
||||||
|
|
||||||
|
//Always return a title as a String
|
||||||
|
if(title == null){
|
||||||
|
title = ''
|
||||||
|
}
|
||||||
|
|
||||||
if(!inString || inString == null || inString.length == 0){
|
if(!inString || inString == null || inString.length == 0){
|
||||||
return {title, sub}
|
return {title, sub}
|
||||||
}
|
}
|
||||||
@ -55,16 +71,17 @@ ProcessText.deduceNoteTitle = (inString) => {
|
|||||||
|
|
||||||
const tagFreeLength = ProcessText.removeHtml(inString).length
|
const tagFreeLength = ProcessText.removeHtml(inString).length
|
||||||
|
|
||||||
if(tagFreeLength < 100){
|
//
|
||||||
sub = ProcessText.stripBlankHtmlLines(inString)
|
// Simplified attempt!
|
||||||
return {title, sub}
|
// Remove tags, push caret if greater than 200 chars...thats it
|
||||||
|
// Still needs, links to open in a new window.
|
||||||
|
|
||||||
|
sub = ProcessText.stripDoubleBlankLines(inString)
|
||||||
|
if(tagFreeLength > 200){
|
||||||
|
sub += '... <i class="green caret down icon"></i>'
|
||||||
}
|
}
|
||||||
|
|
||||||
//Primare Case - Short notes
|
return {title, sub}
|
||||||
if(tagFreeLength < 300){
|
|
||||||
sub = ProcessText.stripBlankHtmlLines(inString)
|
|
||||||
return {title, sub}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Emergency ending tag if truncated. This will help regex find all the lines
|
//Emergency ending tag if truncated. This will help regex find all the lines
|
||||||
inString += '</end>'
|
inString += '</end>'
|
||||||
@ -87,6 +104,7 @@ ProcessText.deduceNoteTitle = (inString) => {
|
|||||||
let charLimit = 400
|
let charLimit = 400
|
||||||
let listStart = false
|
let listStart = false
|
||||||
let noTitleJustList = false
|
let noTitleJustList = false
|
||||||
|
let appendCaret = false
|
||||||
|
|
||||||
for(let i=0; i < totalLines; i++){
|
for(let i=0; i < totalLines; i++){
|
||||||
|
|
||||||
@ -167,8 +185,8 @@ ProcessText.deduceNoteTitle = (inString) => {
|
|||||||
if(cleanCutString.length == 0){
|
if(cleanCutString.length == 0){
|
||||||
cleanCutString = cutString
|
cleanCutString = cutString
|
||||||
}
|
}
|
||||||
|
appendCaret = true
|
||||||
|
|
||||||
finalLines.push(cleanCutString + '... <i class="green caret down icon"></i>')
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,9 +194,13 @@ ProcessText.deduceNoteTitle = (inString) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tagFreeLength.length >= 300 || appendCaret){
|
||||||
|
finalLines.push('... <i class="green caret down icon"></i>')
|
||||||
|
}
|
||||||
|
|
||||||
//Pull out title if its not an empty string
|
//Pull out title if its not an empty string
|
||||||
if(ProcessText.removeHtml(finalLines[0]).trim().replace(' ','').length > 0 && !noTitleJustList){
|
if(!noTitleJustList && title == ''){
|
||||||
// title = finalLines.shift()
|
title = ProcessText.removeHtml( finalLines.shift() ).replace(' ','')
|
||||||
}
|
}
|
||||||
|
|
||||||
sub = finalLines.join('')
|
sub = finalLines.join('')
|
||||||
|
@ -3,10 +3,29 @@ require('module-alias/register')
|
|||||||
|
|
||||||
let Auth = require('@helpers/Auth')
|
let Auth = require('@helpers/Auth')
|
||||||
|
|
||||||
|
const helmet = require('helmet')
|
||||||
|
|
||||||
|
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const app = express()
|
const app = express()
|
||||||
|
app.use( helmet() )
|
||||||
const port = 3000
|
const port = 3000
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Request Rate Limiter
|
||||||
|
//
|
||||||
|
const rateLimit = require('express-rate-limit');
|
||||||
|
const limiter = rateLimit({
|
||||||
|
windowMs: 10 * 60 * 1000, // minutes
|
||||||
|
max: 1000 // limit each IP to 100 requests per windowMs
|
||||||
|
});
|
||||||
|
|
||||||
|
// apply to all requests
|
||||||
|
app.use(limiter);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var http = require('http').createServer(app);
|
var http = require('http').createServer(app);
|
||||||
var io = require('socket.io')(http, {
|
var io = require('socket.io')(http, {
|
||||||
path:'/socket'
|
path:'/socket'
|
||||||
|
@ -512,7 +512,7 @@ Note.solrQuery = (userId, searchQuery, searchTags) => {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
//Number of characters before and after search word
|
//Number of characters before and after search word
|
||||||
const front = 5
|
const front = 20
|
||||||
const tail = 150
|
const tail = 150
|
||||||
|
|
||||||
db.promise()
|
db.promise()
|
||||||
@ -584,7 +584,7 @@ Note.search = (userId, searchQuery, searchTags, fastFilters) => {
|
|||||||
let searchParams = [userId]
|
let searchParams = [userId]
|
||||||
let noteSearchQuery = `
|
let noteSearchQuery = `
|
||||||
SELECT note.id,
|
SELECT note.id,
|
||||||
SUBSTRING(note_raw_text.text, 1, 1500) as text,
|
SUBSTRING(note_raw_text.text, 1, 500) as text,
|
||||||
note_raw_text.title as title,
|
note_raw_text.title as title,
|
||||||
note_raw_text.updated as updated,
|
note_raw_text.updated as updated,
|
||||||
opened,
|
opened,
|
||||||
@ -722,15 +722,10 @@ Note.search = (userId, searchQuery, searchTags, fastFilters) => {
|
|||||||
if(note.encrypted == 1){ note.text = '' }
|
if(note.encrypted == 1){ note.text = '' }
|
||||||
|
|
||||||
//Deduce note title
|
//Deduce note title
|
||||||
const textData = ProcessText.deduceNoteTitle(note.text)
|
const textData = ProcessText.deduceNoteTitle(note.title, note.text)
|
||||||
// console.log(textData)
|
// console.log(textData)
|
||||||
|
|
||||||
// console.log(textData)
|
note.title = textData.title
|
||||||
|
|
||||||
if(note.title == null){
|
|
||||||
note.title = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
note.subtext = textData.sub
|
note.subtext = textData.sub
|
||||||
note.titleLength = textData.titleLength
|
note.titleLength = textData.titleLength
|
||||||
note.subtextLength = textData.subtextLength
|
note.subtextLength = textData.subtextLength
|
||||||
|
@ -5,6 +5,10 @@ let Tag = module.exports = {}
|
|||||||
Tag.userTags = (userId, searchQuery, searchTags, fastFilters) => {
|
Tag.userTags = (userId, searchQuery, searchTags, fastFilters) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
if(searchQuery && searchQuery.length > 0){
|
||||||
|
return resolve([])
|
||||||
|
}
|
||||||
|
|
||||||
let query = `
|
let query = `
|
||||||
SELECT
|
SELECT
|
||||||
tag.id,
|
tag.id,
|
||||||
@ -12,7 +16,7 @@ Tag.userTags = (userId, searchQuery, searchTags, fastFilters) => {
|
|||||||
COUNT(note_tag.note_id) as usages
|
COUNT(note_tag.note_id) as usages
|
||||||
FROM tag
|
FROM tag
|
||||||
JOIN note_tag ON tag.id = note_tag.tag_id
|
JOIN note_tag ON tag.id = note_tag.tag_id
|
||||||
JOIN note On note.id = note_tag.note_id
|
JOIN note ON note.id = note_tag.note_id
|
||||||
WHERE note_tag.user_id = ?
|
WHERE note_tag.user_id = ?
|
||||||
`
|
`
|
||||||
|
|
||||||
|
BIN
staticFiles/assets/favicon.ico
Normal file → Executable file
BIN
staticFiles/assets/favicon.ico
Normal file → Executable file
Binary file not shown.
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 41 KiB |
Loading…
Reference in New Issue
Block a user