Major Update: Changed Text Input View

* Created new toolbar that moves on mobile
This commit is contained in:
Max G
2020-05-02 19:10:20 +00:00
parent bcb31e9af5
commit c8033588dd
11 changed files with 795 additions and 260 deletions

View File

@@ -4,196 +4,194 @@
id="InputNotes"
class="master-note-edit"
@keyup.esc="close()"
:class="[{ 'size-down':(sizeDown == true), 'full-focus':(fullFocusEditor) }, 'position-'+position ]"
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}"
:class="[{ 'full-focus':(fullFocusEditor) }, 'position-'+position ]"
>
<div class="input-container-wrapper">
<!-- Main Menu -->
<div class="edit-menu" :class="{ 'slide-out-top':(sizeDown == true) }">
<!-- Loading indicator -->
<div v-if="loading" class="loading-note">
<div class="ui active dimmer">
<div class="ui text loader">{{loadingMessage}}</div>
</div>
</div>
<div class="note-menu">
<nm-button tip="Close" bottom-tip="true" v-on:click.native="close()" icon="close" />
<nm-button tip="Text Color" bottom-tip="true" icon="palette icon" v-on:click.native="colorpicker = true" />
<nm-button tip="Bold" bottom-tip="true" v-on:click.native="toggleBold()" icon="bold" />
<nm-button tip="Quote" bottom-tip="true" v-on:click.native="toggleItalic()" icon="quote left" />
<nm-button tip="Big Text" bottom-tip="true" v-on:click.native="modifyFont('1.4em')" icon="text height" />
<div class="edit-spacer"></div>
<nm-button tip="Indent" bottom-tip="true" v-on:click.native="editor.increaseQuoteLevel()" icon="indent" />
<div class="menu-top-half">
<div class="edit-button" v-on:click="close()" data-tooltip="Close" data-position="bottom center" data-inverted>
<i class="close icon"></i>
</div>
<nm-button tip="Outdent" bottom-tip="true" v-on:click.native="editor.decreaseQuoteLevel()" icon="outdent" />
<div class="edit-divide"></div>
<nm-button tip="Remove Formatting" bottom-tip="true" v-on:click.native="removeFormatting()" icon="remove format icon" />
<div class="edit-button" v-on:click="toggleList('ul')" data-tooltip="Task List" data-position="bottom center" data-inverted>
<i class="tasks icon"></i>
</div>
<div class="edit-button" v-on:click="toggleList('ol')" data-tooltip="Numbered List" data-position="bottom center" data-inverted>
<i class="list ol icon"></i>
</div>
<nm-button v-on:click.native="undoCustom()" icon="undo" bottom-tip="true" tip="Undo" />
<div class="edit-button" v-on:click="colorpicker = true" data-tooltip="Text Color" data-position="bottom center" data-inverted>
<i class="palette icon"></i>
</div>
<nm-button tip="Users on Note" bottom-tip="true" v-if="usersOnNote > 1" icon="green user circle" />
<div class="edit-button" v-on:click="toggleBold()" data-tooltip="Bold" data-position="bottom center" data-inverted>
<i class="bold icon"></i>
</div>
</div>
<!-- Squire box grows -->
<div class="note-wrapper">
<textarea
ref="titleTextarea"
v-on:keyup="titleResize"
v-on:keydown="titleResize"
@keydown.enter.exact.prevent="editor.focus(); editor.moveCursorToEnd()"
rows="1"
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}"
v-on:blur="save" type="text" v-model="noteTitle" placeholder="Title" class="stealth-input">
</textarea>
<div v-show="isDecrypted" id="squire-id" class="squire-box" ref="squirebox" placeholder="Note Text"></div>
<!-- Decrypt note prompt -->
<div v-if="isEncrypted && !isDecrypted" class="ui basic padded segment">
<div class="ui raised segment">
<h3 class="ui center aligned icon header">
<i class="green lock alternate icon"></i>
<span v-if="!lockedOut">
This note is encrypted and requires a password to be opened.
</span>
<!-- note is locked for 5 minutes -->
<span v-if="lockedOut">
To many unlock attempts. Note is locked for 5 minutes.
</span>
</h3>
<!-- Decrypt note -->
<div class="ui form" v-if="!lockedOut">
<h5 class="ui horizontal divider header" v-if="passwordHint && passwordHint.length > 0">
Hint: {{ passwordHint }}
</h5>
<div class="field">
<input :name="`randomThing-${noteid}`" :id="`yupper-${noteid}`"type="password" v-model="password" placeholder="Note Password" v-on:keyup.enter="decryptNote" autofocus ref="decryptNotePrompt">
</div>
<div class="field">
<div v-on:click="decryptNote" class="ui green fluid button" v-if="password.length >= 3">
Unlock Note
</div>
<div class="ui disabled fluid button" v-if="password.length < 3">
Unlock Note
</div>
</div>
</div>
<div class="edit-button" v-on:click="toggleItalic()" data-tooltip="Quote" data-position="bottom center" data-inverted>
<i class="quote left icon"></i>
</div>
<div class="edit-button" v-on:click="modifyFont('1.4em')" data-tooltip="Title" data-position="bottom center" data-inverted>
<i class="text height icon"></i>
</div>
<div class="edit-button" v-on:click="editor.increaseQuoteLevel()" data-tooltip="Indent" data-position="bottom center" data-inverted>
<i class="indent icon"></i>
</div>
<div class="edit-button" v-on:click="editor.decreaseQuoteLevel()" data-tooltip="Outdent" data-position="bottom center" data-inverted>
<i class="outdent 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>
</div>
<div class="menu-bottom-half">
<div class="edit-divide"></div>
<!-- bottom stats -->
<div class="ui basic segment">
<div class="ui grid compact">
<div class="four wide column">
<button class="ui compact basic fluid icon button shrinking" v-if="!isEncrypted"
v-on:click="$router.push(`/notes/open/${noteid}/menu/passwordprotect`)" data-tooltip="Add Password">
<i class="shield alternate icon"></i>
Protect
</button>
<button class="ui compact basic fluid icon button shrinking" v-if="isEncrypted && isDecrypted" v-on:click="disableEncryption" data-tooltip="Remove Password Protection">
<i class="unlock icon"></i>
Un-protect
</button>
</div>
<div class="four wide column">
<!-- Archive Button -->
<button class="ui compact basic fluid icon button shrinking" v-on:click="onToggleArchived" :data-tooltip="archived == 1?'Move to main list':'Move to Archive'">
<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 icon button shrinking" v-on:click="onTogglePinned" :data-tooltip="pinned == 1?'Un-pin from top':'Pin to top'">
<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 icon button shrinking" v-on:click="openEditAttachment" data-tooltip="Files on note">
<i class="folder icon"></i> Files
</button>
</div>
<div class="one wide column"></div>
<div class="eight wide middle aligned column">
<span :data-tooltip="`Created: ${$helpers.timeAgo(created)}`">
Edited: {{ $helpers.timeAgo(updated) }}
</span>
</div>
<div class="one wide column"></div>
<div class="edit-button" v-on:click="undoCustom()" data-tooltip="Undo" data-position="bottom center" data-inverted>
<i class="undo icon"></i>
</div>
</div>
</div>
<div class="edit-divide"></div>
<!-- && this.$store.getters.getIsUserOnMobile -->
<span class="note-status-indicator" v-on:click="save()" v-if="statusText != 'Saved' && $store.getters.getIsUserOnMobile">
<div class="ui green button">{{statusText}}</div>
</span>
<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/colors`)" data-tooltip="Note Color" data-position="bottom center" data-inverted>
<i class="paint brush icon"></i>
</div>
<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/tags`)" data-tooltip="Tags" data-position="bottom center" data-inverted>
<i class="tags icon"></i>
</div>
<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/images`)" data-tooltip="Images" data-position="bottom center" data-inverted>
<i class="image icon"></i>
</div>
<!-- Note options on the bottom of note -->
<div class="all-settings">
<div class="note-menu shrink-icons-on-mobile">
<nm-button tip="Task List" v-on:click.native="toggleList('ul')" icon="tasks" text="Check" />
<nm-button tip="Numbered List" v-on:click.native="toggleList('ol')" icon="list ol" text="List"/>
<!-- colors button -->
<nm-button
v-on:click.native="$router.push(`/notes/open/${noteid}/menu/colors`)"
icon="paint brush"
text="Color"
tip="Note Color"
></nm-button>
<!-- Tags -->
<nm-button
v-on:click.native="$router.push(`/notes/open/${noteid}/menu/tags`)"
icon="tags"
text="Tags"
tip="Tags"
></nm-button>
<!-- add images panel -->
<nm-button
v-on:click.native="$router.push(`/notes/open/${noteid}/menu/images`)"
icon="image"
text="Images"
tip="Images"
></nm-button>
<!-- file upload button -->
<file-upload-button
class="nm-button"
data-tooltip="Upload File" data-position="bottom center" data-inverted
class="edit-button"
:noteId="noteid" />
<nm-button
icon="ellipsis horizontal"
text="Options"
tip="More Options"
v-on:click.native="$router.push(`/notes/open/${noteid}/menu/options`)" />
<div class="edit-divide"></div>
<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/options`)" data-tooltip="More Options" data-position="bottom center" data-inverted>
<i class="tools icon"></i>
</div>
<div class="edit-divide"></div>
<!-- protect -->
<div class="edit-button" v-if="!isEncrypted"
v-on:click="$router.push(`/notes/open/${noteid}/menu/passwordprotect`)" data-tooltip="Password Protect" data-position="bottom center" data-inverted>
<i class="shield alternate icon"></i>
</div>
<!-- data-tooltip="Remove Password Protection" -->
<div class="edit-button" v-if="isEncrypted && isDecrypted" v-on:click="disableEncryption()" data-tooltip="Close" data-position="bottom center" data-inverted>
<i class="unlock icon"></i>
</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>
<span v-if="archived == 1"><i class="green archive icon"></i></span>
<span v-if="archived != 1"><i class="archive icon"></i></span>
</div>
<div class="edit-button" v-on:click="onTogglePinned" :data-tooltip="pinned == 1?'Un-pin from top':'Pin to top'" data-position="bottom center" data-inverted>
<span v-if="pinned == 1"><i class="green pin icon"></i></span>
<span v-if="pinned != 1"><i class="pin icon"></i></span>
</div>
<!-- data-tooltip="Files on note" -->
<div class="edit-button" v-on:click="openEditAttachment" data-tooltip="Files" data-position="bottom center" data-inverted>
<i class="folder icon"></i>
</div>
</div>
<!-- <span :data-tooltip="`Created: ${$helpers.timeAgo(created)}`">
Edited: {{ $helpers.timeAgo(updated) }}
</span> -->
</div>
</div>
<div class="bottom-edit-menu"></div>
<div class="input-container-wrapper" :class="{ 'size-down':(sizeDown == true)}" >
<!-- Loading indicator -->
<div v-if="loading" class="loading-note">
<div class="ui active dimmer">
<div class="ui text loader">{{loadingMessage}}</div>
</div>
</div>
<!-- Squire box grows -->
<div class="note-wrapper" :style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}">
<!-- Title input area -->
<textarea
ref="titleTextarea"
v-on:keyup="titleResize"
v-on:keydown="titleResize"
@keydown.enter.exact.prevent="editor.focus(); editor.moveCursorToEnd()"
rows="1"
:style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}"
v-on:blur="save" type="text" v-model="noteTitle" placeholder="Title" class="stealth-input">
</textarea>
<!-- Squire Box - only appears if decrypted -->
<div v-show="isDecrypted" id="squire-id" class="squire-box" ref="squirebox" placeholder="Note Text"></div>
<!-- Decrypt note prompt -->
<div v-if="isEncrypted && !isDecrypted" class="ui basic padded segment">
<div class="ui raised segment">
<h3 class="ui center aligned icon header">
<i class="green lock alternate icon"></i>
<span v-if="!lockedOut">
This note is encrypted and requires a password to be opened.
</span>
<!-- note is locked for 5 minutes -->
<span v-if="lockedOut">
To many unlock attempts. Note is locked for 5 minutes.
</span>
</h3>
<!-- Decrypt note -->
<div class="ui form" v-if="!lockedOut">
<h5 class="ui horizontal divider header" v-if="passwordHint && passwordHint.length > 0">
Hint: {{ passwordHint }}
</h5>
<div class="field">
<input :name="`randomThing-${noteid}`" :id="`yupper-${noteid}`"type="password" v-model="password" placeholder="Note Password" v-on:keyup.enter="decryptNote" autofocus ref="decryptNotePrompt">
</div>
<div class="field">
<div v-on:click="decryptNote" class="ui green fluid button" v-if="password.length >= 3">
Unlock Note
</div>
<div class="ui disabled fluid button" v-if="password.length < 3">
Unlock Note
</div>
</div>
</div>
</div>
</div>
</div>
<!-- && this.$store.getters.getIsUserOnMobile -->
<span class="note-status-indicator" v-on:click="save()" v-if="statusText != 'Saved' && $store.getters.getIsUserOnMobile">
<div class="ui green button">{{statusText}}</div>
</span>
</div>
<!-- color picker -->
<color-tooltip
@@ -203,7 +201,6 @@
/>
<!-- Side slide menus for colors, tags, images and other options -->
<side-slide-menu v-show="colors" v-on:close="colors = false" name="colors">
<color-picker
@changeColor="onChangeColor"
@@ -319,7 +316,13 @@
</div>
</side-slide-menu>
<!-- <div class="full-focus-shade"></div> -->
<!-- Show side shades if user is on desktop only -->
<div class="full-focus-shade shade1"
:class="{ 'slide-out-left':(sizeDown == true) }"
v-on:click="close()"></div>
<div class="full-focus-shade shade2"
:class="{ 'slide-out-right':(sizeDown == true) }"
v-on:click="close()"></div>
</div>
</template>
@@ -460,7 +463,7 @@
this.hashedPass = ''
clearTimeout(this.autoLockTimeout)
this.$io.emit('leave_room', this.rawTextId)
// this.$io.emit('leave_room', this.rawTextId)
this.$bus.$off('new_file_upload')
@@ -1263,6 +1266,9 @@
})
},
setupWebSockets(){
return
//Tell server to push this note into a room
this.$io.emit('join_room', this.rawTextId)
@@ -1354,33 +1360,98 @@
<style type="text/css" scoped>
.full-focus-shade {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--menu-accent);
z-index: 999;
cursor: pointer;
opacity: 0.8;
}
.shade1 {
left: 50%;
}
.shade2 {
right: 50%;
}
/* squire styles */
.input-container-wrapper {
display: block;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
display: flex;
flex-direction: column;
position: fixed;
top: 0;
bottom: 0;
left: 15%;
right: 15%;
z-index: 1005;
overflow-x: scroll;
scrollbar-width: none;
}
/*Three main elements nested in panel */
.note-menu {
/*position: absolute;*/
top: 0;/*
.note-wrapper {
background-color: var(--background_color);
border: 1px solid var(--menu-accent);;
margin: 45px 0 45px 0;
}
/*
Edit Menu Styles START
*/
.edit-menu {
position: fixed;
top: 0;
left: 0;
right: 0;*/
flex-grow: 0;
right: 0;
width: 100%;
display: block;
background-color: var(--background_color);
z-index: 1019;
padding: 3px 5px;
border: none;
border-bottom: 1px solid var(--menu-accent);
}
.note-wrapper {
flex-grow: 1;
overflow: scroll;
.menu-top-half, .menu-bottom-half {
display: inline-block;
}
.edit-spacer {
width: calc(15% - 10px);
display: inline-block;
height: 10px;
opacity: 0;
}
.edit-button {
background-color: var(--background_color);
color: var(--menu-text);
display: inline-block;
font-size: 1.4em;
padding: 4px 1px 5px 4px;
border-radius: 3px;
cursor: pointer;
}
.edit-button:hover {
background-color: var(--menu-accent);
}
.edit-divide {
display: inline-block;
background-color: var(--menu-accent);
height: 15px;
width: 1px;
margin: 0 3px;
padding: 0;
}
@media only screen and (max-width: 740px) {
.edit-spacer {
display: none;
}
}
/*
Edit Menu Styles END
*/
.stealth-input {
width: 100%;
@@ -1388,29 +1459,17 @@
background-color: rgba(255,255,255,0.1);
border: none;
font-size: 1.7em;
/*line-height: 1.7em;*/
color: var(--text_color);
resize: none;
overflow: hidden;
margin: 0;
}
/*Settings manager styles */
.all-settings {
/*border-top: 1px solid #534c68;*/
background: #221f2b;
/*position: absolute;*/
/*bottom: 40px;*/
/*right: 0;*/
/*left: 0;*/
z-index: 99;
/*border: 1px solid;*/
/*background-color: var(--background_color);*/
/*border-color: var(--border_color);*/
/*box-sizing: border-box;*/
/*border-radius: 7px;*/
/*box-shadow: 0px 3px 7px 0px rgba(140,140,140,1);*/
/*padding: 1.2em 0 0;*/
flex-grow: 0;
}
/*End Settings manager styles */
@@ -1421,12 +1480,8 @@
.master-note-edit {
position: fixed;
bottom: 0;
background: var(--background_color);
/*color: var(--text_color);*/
height: 100vh;
box-shadow: 0px 0px 5px 2px rgba(140,140,140,1);
z-index: 1001;
/*overflow-x: scroll;*/
overflow-y: scroll;
overflow-x: hidden;
@@ -1443,12 +1498,49 @@
left: 50%;
right: 0;
}
.master-note-edit.full-focus {
left: 15%;
right: 15%;
}
@media only screen and (max-width: 740px) {
.master-note-edit.position-0 {
.input-container-wrapper {
left: 0;
right: 0;
top: 0;
top: 35px;
bottom: 40px;
background-color: var(--background_color);
}
.note-wrapper {
margin: 0;
border: none;
}
.shade1, .shade2 {
right: 150%;
}
/*menu overwrites */
.bottom-edit-menu {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
display: block;
background-color: var(--background_color);
z-index: 1012;
border: none;
border-top: 1px solid var(--menu-accent);
min-height: 40px;
}
.edit-menu {
text-align: center;
}
.menu-bottom-half {
z-index: 1005;
position: fixed;
bottom: 4px;
left: 0;
right: 0;
text-align: center;
}
}
@@ -1457,10 +1549,9 @@
left: 50%;
right: 0%;
}
/* .master-note-edit.position-1.full-focus {
left: 20%;
right: 20%;
}*/
.master-note-edit.position-2 {
left: 0%;
right: 50%;
@@ -1474,17 +1565,59 @@
box-shadow: none;
}
.size-down {
animation: size-down 0.5s ease;
}
/* animations START */
@keyframes size-down {
0% {
top: 0;
.slide-out-top {
animation: slide-out-top 0.5s ease;
}
100% {
top: 150vh;
@keyframes slide-out-top {
0% {
top: 0;
}
100% {
top: -100px;
}
}
}
.size-down {
animation: size-down 0.5s ease;
}
@keyframes size-down {
0% {
top: 0;
}
100% {
top: 150vh;
}
}
.slide-out-left {
animation: slide-out-left 0.5s ease;
}
@keyframes slide-out-left {
0% {
left: 85%;
}
100% {
left: 150%;
}
}
.slide-out-right {
animation: slide-out-right 0.5s ease;
}
@keyframes slide-out-right {
0% {
right: 85%;
}
100% {
right: 150%;
}
}
/* animations END */
</style>