Tons of littele interface changes and cleanups
Massive update to image scraper with much better image getter Lots of little ui updates for mobile
This commit is contained in:
		@@ -53,7 +53,7 @@ helpers.timeAgo = (time) => {
 | 
				
			|||||||
			if (typeof format[2] == 'string') {
 | 
								if (typeof format[2] == 'string') {
 | 
				
			||||||
				return format[list_choice]
 | 
									return format[list_choice]
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				return Math.floor(seconds / format[2]) + ' ' + format[1]// + ' ' + token
 | 
									return Math.floor(seconds / format[2]) + ' ' + format[1] + ' ' + token
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ html {
 | 
				
			|||||||
	height:100%;
 | 
						height:100%;
 | 
				
			||||||
	padding: 0;
 | 
						padding: 0;
 | 
				
			||||||
	margin: 0;
 | 
						margin: 0;
 | 
				
			||||||
	background: none;
 | 
						background: var(--body_bg_color);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
a:hover {
 | 
					a:hover {
 | 
				
			||||||
	text-decoration: underline;
 | 
						text-decoration: underline;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2117,7 +2117,7 @@ var cleanTree = function cleanTree ( node, config, preserveWS ) {
 | 
				
			|||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    data = data.replace( /^[ \t\r\n]+/g, sibling ? ' ' : '' );
 | 
					                    data = data.replace( /^[ \r\n]+/g, sibling ? ' ' : '' );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if ( endsWithWS ) {
 | 
					                if ( endsWithWS ) {
 | 
				
			||||||
                    walker.currentNode = child;
 | 
					                    walker.currentNode = child;
 | 
				
			||||||
@@ -2132,7 +2132,7 @@ var cleanTree = function cleanTree ( node, config, preserveWS ) {
 | 
				
			|||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    data = data.replace( /[ \t\r\n]+$/g, sibling ? ' ' : '' );
 | 
					                    data = data.replace( /[ \r\n]+$/g, sibling ? ' ' : '' );
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if ( data ) {
 | 
					                if ( data ) {
 | 
				
			||||||
                    child.data = data;
 | 
					                    child.data = data;
 | 
				
			||||||
@@ -2693,7 +2693,8 @@ var sanitizeToDOMFragment = function ( html, isPaste, self ) {
 | 
				
			|||||||
        ALLOW_UNKNOWN_PROTOCOLS: true,
 | 
					        ALLOW_UNKNOWN_PROTOCOLS: true,
 | 
				
			||||||
        WHOLE_DOCUMENT: false,
 | 
					        WHOLE_DOCUMENT: false,
 | 
				
			||||||
        RETURN_DOM: true,
 | 
					        RETURN_DOM: true,
 | 
				
			||||||
        RETURN_DOM_FRAGMENT: true
 | 
					        RETURN_DOM_FRAGMENT: true,
 | 
				
			||||||
 | 
					        FORCE_BODY: false
 | 
				
			||||||
    }) : null;
 | 
					    }) : null;
 | 
				
			||||||
    return frag ? doc.importNode( frag, true ) : doc.createDocumentFragment();
 | 
					    return frag ? doc.importNode( frag, true ) : doc.createDocumentFragment();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@@ -5011,4 +5012,4 @@ if ( typeof exports === 'object' ) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}( document ) );
 | 
					}( document ) );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,54 +1,59 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	<div :style="{ 'background-color':allStyles['noteBackground'], 'color':allStyles['noteText']}">
 | 
						<div>
 | 
				
			||||||
		<div class="ui basic segment">
 | 
							
 | 
				
			||||||
		<div class="ui grid">
 | 
							<div class="ui grid">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<div class="ui sixteen wide center aligned column">
 | 
								<div class="ui sixteen wide column">
 | 
				
			||||||
				<div class="ui fluid button" v-on:click="clearStyles">
 | 
									<div class="ui dividing header">
 | 
				
			||||||
 | 
										Reset Background Color and Icon
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<div class="ui labeled basic icon button" v-on:click="clearStyles">
 | 
				
			||||||
					<i class="refresh icon"></i>
 | 
										<i class="refresh icon"></i>
 | 
				
			||||||
					Clear All Styles
 | 
										Reset
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<div class="row">
 | 
								<div class="sixteen wide column rounded" :style="{ 'background-color':allStyles['noteBackground'], 'color':allStyles['noteText']}">
 | 
				
			||||||
				<div class="sixteen wide column">
 | 
									<div class="ui dividing header" :style="{ 'color':allStyles['noteText']}">
 | 
				
			||||||
					<br>
 | 
										<i class="fill drip icon"></i>
 | 
				
			||||||
					<p>Note Color</p>
 | 
										Background Color
 | 
				
			||||||
					<div v-for="color in colors" 
 | 
									</div>
 | 
				
			||||||
						class="color-button" 
 | 
									<div v-for="color in colors" 
 | 
				
			||||||
						:style="{ backgroundColor:color }"
 | 
										class="color-button" 
 | 
				
			||||||
						v-on:click="chosenColor(color)"
 | 
										:style="{ backgroundColor:color }"
 | 
				
			||||||
					></div>
 | 
										v-on:click="chosenColor(color)"
 | 
				
			||||||
 | 
									></div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								<div class="sixteen wide column">
 | 
				
			||||||
 | 
									<div class="ui dividing header">
 | 
				
			||||||
 | 
										<span v-if="allStyles.noteIcon" >
 | 
				
			||||||
 | 
											<i :class="`large ${allStyles.noteIcon} icon`" :style="{ 'color':allStyles.iconColor }"></i>
 | 
				
			||||||
 | 
										</span>
 | 
				
			||||||
 | 
										Note Icon
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<div v-for="icon in icons" class="icon-button" v-on:click="chosenIcon(icon)" >
 | 
				
			||||||
 | 
										<i :class="`large ${icon} icon`"></i>		
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<div class="row">
 | 
								<div class="sixteen wide column">
 | 
				
			||||||
				<div class="sixteen wide column">
 | 
									<div class="ui dividing header">
 | 
				
			||||||
					<p>Note Icon
 | 
										<span v-if="allStyles.noteIcon" >
 | 
				
			||||||
						<span v-if="allStyles.noteIcon" >
 | 
											<i :class="`large ${allStyles.noteIcon} icon`" :style="{ 'color':allStyles.iconColor }"></i>
 | 
				
			||||||
							<i :class="`large ${allStyles.noteIcon} icon`" :style="{ 'color':allStyles.iconColor }"></i>
 | 
										</span>
 | 
				
			||||||
						</span>
 | 
										Icon Color
 | 
				
			||||||
					</p>
 | 
									</div>
 | 
				
			||||||
					<div v-for="icon in icons" class="icon-button" v-on:click="chosenIcon(icon)" >
 | 
									<div v-for="color in getReducedColors()" 
 | 
				
			||||||
						<i :class="`large ${icon} icon`" :style="{ 'color':allStyles.iconColor }"></i>		
 | 
										class="color-button" 
 | 
				
			||||||
					</div>
 | 
										:style="{ backgroundColor:color }"
 | 
				
			||||||
 | 
										v-on:click="chooseIconColor(color)"
 | 
				
			||||||
 | 
									>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
							
 | 
				
			||||||
			<div class="row">
 | 
					 | 
				
			||||||
				<div class="sixteen wide column">
 | 
					 | 
				
			||||||
					<p>Icon Color</p>
 | 
					 | 
				
			||||||
					<div v-for="color in getReducedColors()" 
 | 
					 | 
				
			||||||
						class="color-button" 
 | 
					 | 
				
			||||||
						:style="{ backgroundColor:color }"
 | 
					 | 
				
			||||||
						v-on:click="chooseIconColor(color)"
 | 
					 | 
				
			||||||
					>
 | 
					 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
			</div>
 | 
					 | 
				
			||||||
		</div>
 | 
					 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
@@ -147,20 +152,20 @@
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
<style type="text/css" scoped>
 | 
					<style type="text/css" scoped>
 | 
				
			||||||
	.icon-button {
 | 
						.icon-button, .color-button {
 | 
				
			||||||
		height: 40px;
 | 
							height: 40px;
 | 
				
			||||||
		width: calc(10% - 7px);
 | 
							width: calc(10% - 7px);
 | 
				
			||||||
		display: inline-block;
 | 
							display: inline-block;
 | 
				
			||||||
		cursor: pointer;
 | 
							cursor: pointer;
 | 
				
			||||||
		font-size: 1.3em;
 | 
							font-size: 1.3em;
 | 
				
			||||||
	}
 | 
							border: 1px solid grey;
 | 
				
			||||||
	.color-button {
 | 
							text-align: center;
 | 
				
			||||||
		display: inline-block;
 | 
							padding: 5px 0 0;
 | 
				
			||||||
		width: calc(10% - 7px);
 | 
							border-radius: 4px;
 | 
				
			||||||
		height: 30px;
 | 
					 | 
				
			||||||
		border-radius: 30px;
 | 
					 | 
				
			||||||
		box-shadow: 0px 1px 3px 0px #3e3e3e;
 | 
							box-shadow: 0px 1px 3px 0px #3e3e3e;
 | 
				
			||||||
		margin: 7px 7px 0 0;
 | 
							margin: 7px 7px 0 0;
 | 
				
			||||||
		cursor: pointer;
 | 
						}
 | 
				
			||||||
 | 
						.rounded {
 | 
				
			||||||
 | 
							border-radius: 5px;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
	<!-- change class to .master-note-edit to have it popup on the screen  -->
 | 
						<!-- change class to .master-note-edit to have it popup on the screen. 
 | 
				
			||||||
 | 
							@keyup.esc="closeButtonAction()"  -->
 | 
				
			||||||
	<div 
 | 
						<div 
 | 
				
			||||||
		id="InputNotes" 
 | 
							id="InputNotes" 
 | 
				
			||||||
		class="master-note-edit" 
 | 
							class="master-note-edit"
 | 
				
			||||||
		@keyup.esc="closeButtonAction()"
 | 
					 | 
				
			||||||
	>
 | 
						>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<!-- Giant Edit Note Menu  -->
 | 
							<!-- Giant Edit Note Menu  -->
 | 
				
			||||||
@@ -89,9 +89,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				<div class="edit-divide"></div>
 | 
									<div class="edit-divide"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/colors`)" data-tooltip="Note Color" data-position="bottom center" :style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}">
 | 
					<!-- 				<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/colors`)" data-tooltip="Note Color" data-position="bottom center" :style="{ 'background-color':styleObject['noteBackground'], 'color':styleObject['noteText']}">
 | 
				
			||||||
					<i class="paint brush icon"></i>
 | 
										<i class="paint brush icon"></i>
 | 
				
			||||||
				</div>
 | 
									</div> -->
 | 
				
			||||||
				<!-- <div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/tags`)" data-tooltip="Tags" data-position="bottom center">
 | 
									<!-- <div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/tags`)" data-tooltip="Tags" data-position="bottom center">
 | 
				
			||||||
					<i class="tags icon"></i>
 | 
										<i class="tags icon"></i>
 | 
				
			||||||
				</div> -->
 | 
									</div> -->
 | 
				
			||||||
@@ -107,7 +107,9 @@
 | 
				
			|||||||
				<div class="edit-divide"></div>
 | 
									<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">
 | 
									<div class="edit-button" v-on:click="$router.push(`/notes/open/${noteid}/menu/options`)" data-tooltip="More Options" data-position="bottom center">
 | 
				
			||||||
 | 
										  
 | 
				
			||||||
					<i class="ellipsis horizontal icon"></i>
 | 
										<i class="ellipsis horizontal icon"></i>
 | 
				
			||||||
 | 
										  
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div class="edit-divide"></div>
 | 
									<div class="edit-divide"></div>
 | 
				
			||||||
@@ -128,6 +130,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				<div class="edit-button ui" v-on:click="closeButtonAction()" :data-tooltip="`Close\n(ESC)`" data-position="bottom center">
 | 
									<div class="edit-button ui" v-on:click="closeButtonAction()" :data-tooltip="`Close\n(ESC)`" data-position="bottom center">
 | 
				
			||||||
					<i class="green close icon"></i>
 | 
										<i class="green close icon"></i>
 | 
				
			||||||
 | 
										<span class="ui green text">Done</span>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
@@ -139,7 +142,7 @@
 | 
				
			|||||||
			:class="{ 'side-menu-open':sideMenuOpen, 'size-down':(sizeDown == true),}">
 | 
								:class="{ 'side-menu-open':sideMenuOpen, 'size-down':(sizeDown == true),}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<!-- Squire box grows -->
 | 
								<!-- Squire box grows -->
 | 
				
			||||||
			<div id="text-box-container" class="note-wrapper">
 | 
								<div id="text-box-container" class="note-wrapper" :style="{ 'background-color':styleObject['noteBackground']}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<!-- Loading indicator  -->
 | 
									<!-- Loading indicator  -->
 | 
				
			||||||
				<transition name="fade">
 | 
									<transition name="fade">
 | 
				
			||||||
@@ -161,19 +164,22 @@
 | 
				
			|||||||
					v-on:blur="save" type="text" v-model="noteTitle" placeholder="Title" class="stealth-input glint">
 | 
										v-on:blur="save" type="text" v-model="noteTitle" placeholder="Title" class="stealth-input glint">
 | 
				
			||||||
				</textarea>
 | 
									</textarea>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div class="large-close-button glint" v-on:click="closeButtonAction()">
 | 
									<!-- close button giant -->
 | 
				
			||||||
 | 
									<div v-if="!$store.getters.getIsUserOnMobile" class="large-close-button" v-on:click="closeButtonAction()">
 | 
				
			||||||
					<i class="fitted green close icon"></i>
 | 
										<i class="fitted green close icon"></i>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<!-- little tags on the side, only show on desktop -->
 | 
									<!-- tags on the side, only show on desktop -->
 | 
				
			||||||
				<div class="note-mini-tag-area" :class="{ 'size-down':sizeDown }" v-on:click="$router.push(`/notes/open/${noteid}/menu/tags`)">
 | 
									<div class="note-mini-tag-area" :class="{ 'size-down':sizeDown }"
 | 
				
			||||||
					<span class="add-mini-tag" v-if="noteTags.length == 0">
 | 
										v-on:click="$router.push(`/notes/open/${noteid}/menu/tags`)" 
 | 
				
			||||||
 | 
										:style="{ 'background-color':styleObject['noteBackground'] }">
 | 
				
			||||||
 | 
										<span class="add-mini-tag" v-if="allTags.length == 0">
 | 
				
			||||||
						<i class="tags icon"></i>Add Tags
 | 
											<i class="tags icon"></i>Add Tags
 | 
				
			||||||
					</span>
 | 
										</span>
 | 
				
			||||||
					<span v-for="tag in allTags" class="active-mini-tag" v-if="isTagOnNote(tag.id)">
 | 
										<span v-for="tag in allTags" class="active-mini-tag">
 | 
				
			||||||
						#{{ tag.text }}
 | 
											#{{ tag }}
 | 
				
			||||||
					</span>
 | 
										</span>
 | 
				
			||||||
					<span class="active-mini-tag" v-if="noteTags.length > 0">
 | 
										<span class="active-mini-tag" v-if="allTags.length > 0">
 | 
				
			||||||
						+
 | 
											+
 | 
				
			||||||
					</span>
 | 
										</span>
 | 
				
			||||||
					
 | 
										
 | 
				
			||||||
@@ -201,21 +207,23 @@
 | 
				
			|||||||
		/>
 | 
							/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<!-- Side slide menus for colors, tags, images and other options -->
 | 
							<!-- Side slide menus for colors, tags, images and other options -->
 | 
				
			||||||
		<side-slide-menu v-if="colors" v-on:close="colors = false" name="colors">
 | 
					<!-- 		<side-slide-menu v-if="colors" v-on:close="colors = false" name="colors">
 | 
				
			||||||
			<color-picker
 | 
								<color-picker
 | 
				
			||||||
				@changeColor="onChangeColor"
 | 
									@changeColor="onChangeColor"
 | 
				
			||||||
				@close="colors = false; $router.go(-1)"
 | 
									@close="colors = false; $router.go(-1)"
 | 
				
			||||||
				:style-object="styleObject"
 | 
									:style-object="styleObject"
 | 
				
			||||||
			/>
 | 
								/>
 | 
				
			||||||
		</side-slide-menu>
 | 
							</side-slide-menu> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<side-slide-menu v-if="tags" v-on:close="tags = false; fetchNoteTags()" name="tags" :style-object="styleObject">
 | 
							<!-- tag edit menu -->
 | 
				
			||||||
 | 
							<side-slide-menu v-if="tags" v-on:close="tags = false; fetchNoteTags()" name="tags">
 | 
				
			||||||
			<div class="ui basic segment">
 | 
								<div class="ui basic segment">
 | 
				
			||||||
				<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
 | 
									<note-tag-edit :noteId="noteid" :key="'tags-for-note-'+noteid"/>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</side-slide-menu>
 | 
							</side-slide-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<side-slide-menu v-if="images" v-on:close="images = false" name="images" :style-object="styleObject">
 | 
							<!-- images menu -->
 | 
				
			||||||
 | 
							<side-slide-menu v-if="images" v-on:close="images = false" name="images">
 | 
				
			||||||
			<div class="ui basic segment">
 | 
								<div class="ui basic segment">
 | 
				
			||||||
				<simple-attachment-note
 | 
									<simple-attachment-note
 | 
				
			||||||
					:note-id="noteid" 
 | 
										:note-id="noteid" 
 | 
				
			||||||
@@ -224,67 +232,81 @@
 | 
				
			|||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</side-slide-menu>
 | 
							</side-slide-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<side-slide-menu v-if="options" v-on:close="options = false" name="note-options" :style-object="styleObject">
 | 
							<side-slide-menu v-if="options" v-on:close="options = false" name="note-options">
 | 
				
			||||||
			<div class="ui basic padded segment">
 | 
								<div class="ui basic padded segment">
 | 
				
			||||||
				<div class="ui grid">
 | 
									<div class="ui grid">
 | 
				
			||||||
					<div class="sixteen wide column">
 | 
					
 | 
				
			||||||
						<h3>Note Options</h3>
 | 
					 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
					<div class="eight wide column">
 | 
										<div class="eight wide column">
 | 
				
			||||||
 | 
											<div class="ui dividing header">
 | 
				
			||||||
 | 
												Note Options
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
		 				<div class="ui labeled icon fluid basic button" v-on:click="onToggleArchived()">
 | 
							 				<div class="ui labeled icon fluid basic button" v-on:click="onToggleArchived()">
 | 
				
			||||||
		 					<i class="archive icon" :class="{'green':(archived == 1)}"></i>
 | 
							 					<i class="archive icon" :class="{'green':(archived == 1)}"></i>
 | 
				
			||||||
							<span v-if="archived == 1">Un-Archive Note</span>
 | 
												<span v-if="archived == 1">Un-Archive Note</span>
 | 
				
			||||||
							<span v-if="archived != 1">Archive Note</span>
 | 
												<span v-if="archived != 1">Archive Note</span>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
					<div class="eight wide column">
 | 
					 | 
				
			||||||
						<div class="ui labeled icon fluid basic button" v-on:click="onTogglePinned">
 | 
											<div class="ui labeled icon fluid basic button" v-on:click="onTogglePinned">
 | 
				
			||||||
							<i class="pin icon" :class="{'green':(pinned == 1)}"></i>
 | 
												<i class="pin icon" :class="{'green':(pinned == 1)}"></i>
 | 
				
			||||||
							<span v-if="pinned == 1">Un-Pin Note</span>
 | 
												<span v-if="pinned == 1">Un-Pin Note</span>
 | 
				
			||||||
							<span v-if="pinned != 1">Pin Note</span>
 | 
												<span v-if="pinned != 1">Pin Note</span>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="sixteen wide column">
 | 
					
 | 
				
			||||||
						<h3>List Options</h3>
 | 
										<div class="eight wide column">
 | 
				
			||||||
					</div>
 | 
											<div class="ui dividing header">
 | 
				
			||||||
					<div class="sixteen wide column">
 | 
												List Options
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
						<div class="ui labeled icon fluid basic button" v-on:click="sortList">
 | 
											<div class="ui labeled icon fluid basic button" v-on:click="sortList">
 | 
				
			||||||
							<i class="sort amount up icon"></i>
 | 
												<i class="sort amount up icon"></i>
 | 
				
			||||||
							Sort List
 | 
												Sort List (Complete to bottom)
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<div class="ui labeled icon fluid basic button" v-on:click="uncheckAllListItems">
 | 
				
			||||||
 | 
												<i class="list ul icon"></i>
 | 
				
			||||||
 | 
												Uncheck All
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
					<div class="eight wide column">
 | 
					 | 
				
			||||||
						<div class="ui labeled icon fluid basic button" v-on:click="deleteCompletedListItems">
 | 
											<div class="ui labeled icon fluid basic button" v-on:click="deleteCompletedListItems">
 | 
				
			||||||
							<i class="trash icon"></i>
 | 
												<i class="trash icon"></i>
 | 
				
			||||||
							Delete Checked
 | 
												Delete Checked
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<div class="eight wide column">
 | 
										<div class="eight wide column">
 | 
				
			||||||
						<div class="ui labeled icon fluid basic button" v-on:click="uncheckAllListItems">
 | 
											<div class="ui dividing header">
 | 
				
			||||||
							<i class="list ul icon"></i>
 | 
												Calculate Line
 | 
				
			||||||
							Uncheck All
 | 
					 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
											<p>
 | 
				
			||||||
					<div class="sixteen wide column">
 | 
												Calculates algebra before '='
 | 
				
			||||||
						<h3>Misc Options</h3>
 | 
											</p>
 | 
				
			||||||
					</div>
 | 
											<div class="ui labeled icon fluid basic button" v-on:click="calculateMath">
 | 
				
			||||||
					<div class="eight wide column">
 | 
					 | 
				
			||||||
						<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>
 | 
				
			||||||
							Simple Math
 | 
												Calculate 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>
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										<div class="eight wide column">
 | 
				
			||||||
 | 
											<!-- data-tooltip="Files on note" -->
 | 
				
			||||||
 | 
											<div class="ui dividing header">
 | 
				
			||||||
 | 
												Note Attachments & Links
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
											<p>
 | 
				
			||||||
 | 
												Attachment & Link Count {{ attachmentCount }}
 | 
				
			||||||
 | 
											</p>
 | 
				
			||||||
 | 
											<div v-on:click="openEditAttachment"  class="ui labeled icon fluid basic button">
 | 
				
			||||||
 | 
												<i class="folder icon"></i>
 | 
				
			||||||
 | 
												View all Attachments & Links 
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										<color-picker
 | 
				
			||||||
 | 
											@changeColor="onChangeColor"
 | 
				
			||||||
 | 
											@close="colors = false; $router.go(-1)"
 | 
				
			||||||
 | 
											:style-object="styleObject"
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<div class="sixteen wide column" v-if="rawTextId > 0">
 | 
										<div class="sixteen wide column" v-if="rawTextId > 0">
 | 
				
			||||||
						<h3>Share Note</h3>
 | 
											<div class="ui dividing header">
 | 
				
			||||||
 | 
												Share Note
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
						<share-note-component 
 | 
											<share-note-component 
 | 
				
			||||||
							:note-id="noteid"
 | 
												:note-id="noteid"
 | 
				
			||||||
							:raw-text-id="rawTextId"
 | 
												:raw-text-id="rawTextId"
 | 
				
			||||||
@@ -296,7 +318,7 @@
 | 
				
			|||||||
		</side-slide-menu>
 | 
							</side-slide-menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<!-- create table option  -->
 | 
							<!-- create table option  -->
 | 
				
			||||||
		<side-slide-menu v-if="table" v-on:close="table = false; fetchNoteTags()" name="table" :style-object="styleObject">
 | 
							<side-slide-menu v-if="table" v-on:close="table = false;" name="table" :style-object="styleObject">
 | 
				
			||||||
			<div class="ui basic segment">
 | 
								<div class="ui basic segment">
 | 
				
			||||||
				<h2>Insert Table</h2>
 | 
									<h2>Insert Table</h2>
 | 
				
			||||||
				<div class="table-tic-table">
 | 
									<div class="table-tic-table">
 | 
				
			||||||
@@ -521,77 +543,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				}, totalTime + 40)
 | 
									}, totalTime + 40)
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			removeTag(tagId){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				this.allTags = []
 | 
					 | 
				
			||||||
				let entryId = 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				//Find fucking note tag for removal
 | 
					 | 
				
			||||||
				this.noteTags.forEach(noteTag => {
 | 
					 | 
				
			||||||
					if(noteTag['tagId'] == tagId){
 | 
					 | 
				
			||||||
						entryId = noteTag['entryId']
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				let postData = {
 | 
					 | 
				
			||||||
					'tagId':entryId,
 | 
					 | 
				
			||||||
					'noteId':this.noteid
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				axios.post('/api/tag/removefromnote', postData)
 | 
					 | 
				
			||||||
				.then(response => {
 | 
					 | 
				
			||||||
					this.fetchNoteTags()
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				.catch(error => { this.$bus.$emit('notification', 'Failed to Remove Tag') })
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			addTag(tagText){
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				this.allTags = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				let postData = {
 | 
					 | 
				
			||||||
					'tagText':tagText,
 | 
					 | 
				
			||||||
					'noteId':this.noteid
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				axios.post('/api/tag/addtonote', postData)
 | 
					 | 
				
			||||||
				.then(response => {
 | 
					 | 
				
			||||||
					this.fetchNoteTags()
 | 
					 | 
				
			||||||
				})
 | 
					 | 
				
			||||||
				.catch(error => { this.$bus.$emit('notification', 'Failed to Add Tag') })
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			fetchNoteTags(){
 | 
								fetchNoteTags(){
 | 
				
			||||||
				axios.post('/api/tag/get', {'noteId': this.noteid})
 | 
									axios.post('/api/tag/fornote', {'noteId': this.noteid})
 | 
				
			||||||
				.then(({data}) => {
 | 
									.then(({data}) => {
 | 
				
			||||||
					this.allTags = data.allTags
 | 
					 | 
				
			||||||
					this.noteTags = data.noteTagIds
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					//Stick used tags at top.
 | 
										//Setup note tags from string
 | 
				
			||||||
					if(this.noteTags.length > 0){
 | 
										this.allTags = data.tags ? data.tags.split(',') : []
 | 
				
			||||||
 | 
										
 | 
				
			||||||
						let frontTags = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						for (var i = this.allTags.length - 1; i >= 0; i--) {
 | 
					 | 
				
			||||||
							this.noteTags.forEach(noteTag => {
 | 
					 | 
				
			||||||
								if(this.allTags[i]['id'] == noteTag['tagId']){
 | 
					 | 
				
			||||||
									frontTags.push(this.allTags[i])
 | 
					 | 
				
			||||||
									this.allTags.splice(i,1)
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							})
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						this.allTags.unshift(...frontTags)
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			isTagOnNote(id){
 | 
					 | 
				
			||||||
				for (let i = 0; i < this.noteTags.length; i++) {
 | 
					 | 
				
			||||||
					const current = this.noteTags[i]
 | 
					 | 
				
			||||||
					if(current && current['tagId'] == id){
 | 
					 | 
				
			||||||
						return true
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				return false
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			initSquire(){
 | 
								initSquire(){
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				//Set up squire and load note text
 | 
									//Set up squire and load note text
 | 
				
			||||||
@@ -604,10 +564,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//Load tags on mobile
 | 
					 | 
				
			||||||
				this.fetchNoteTags()
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				//Set up websockets after squire is set up
 | 
									//Set up websockets after squire is set up
 | 
				
			||||||
				setTimeout(() => {
 | 
									setTimeout(() => {
 | 
				
			||||||
					this.setupWebSockets()
 | 
										this.setupWebSockets()
 | 
				
			||||||
@@ -783,6 +739,9 @@
 | 
				
			|||||||
						this.lastNoteHash = this.hashString( response.data.text )
 | 
											this.lastNoteHash = this.hashString( response.data.text )
 | 
				
			||||||
						// this.diffNoteText = response.data.text
 | 
											// this.diffNoteText = response.data.text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											//Setup note tags
 | 
				
			||||||
 | 
											this.allTags = response.data.tags ? response.data.tags.split(','):[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						//Set up note colors
 | 
											//Set up note colors
 | 
				
			||||||
						if(response.data.color){
 | 
											if(response.data.color){
 | 
				
			||||||
							this.styleObject = JSON.parse(response.data.color)
 | 
												this.styleObject = JSON.parse(response.data.color)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,27 +21,9 @@
 | 
				
			|||||||
					class="big-text"><p>{{ note.title }}</p></span>
 | 
										class="big-text"><p>{{ note.title }}</p></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<span class="tags" v-if="note.tags">
 | 
									<span class="tags" v-if="note.tags">
 | 
				
			||||||
						<span  v-for="tag in (note.tags.split(','))" class="little-tag" v-on:click="$emit('tagClick', tag.split(':')[1] )">#{{ tag.split(':')[0] }}</span>
 | 
										<span  v-for="tag in (note.tags.split(','))" class="little-tag" v-on:click="$emit('tagClick', tag.split(':')[1] )">#{{ tag.split(':')[0] }}</span>
 | 
				
			||||||
						<br>
 | 
										<br>
 | 
				
			||||||
					</span>
 | 
									</span>
 | 
				
			||||||
 | 
					 | 
				
			||||||
				<!-- Sub text display -->
 | 
					 | 
				
			||||||
				<span v-if="note.subtext.length > 0"
 | 
					 | 
				
			||||||
					class="small-text"
 | 
					 | 
				
			||||||
					v-html="note.subtext"></span>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				<!-- Not indexed warning -->
 | 
					 | 
				
			||||||
<!-- 				<span v-if="note.indexed != 1">
 | 
					 | 
				
			||||||
					<span class="green label">Not Indexed</span>
 | 
					 | 
				
			||||||
				</span> -->
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				
 | 
					 | 
				
			||||||
				<div class="ui fluid basic button" v-if="note.encrypted == 1">
 | 
					 | 
				
			||||||
					<i class="green lock icon"></i>
 | 
					 | 
				
			||||||
					Locked
 | 
					 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<!-- Shared Details -->
 | 
									<!-- Shared Details -->
 | 
				
			||||||
				<span class="subtext" v-if="note.shared == 2">
 | 
									<span class="subtext" v-if="note.shared == 2">
 | 
				
			||||||
@@ -62,23 +44,71 @@
 | 
				
			|||||||
					</span>
 | 
										</span>
 | 
				
			||||||
				</span>
 | 
									</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			</div>
 | 
									<!-- Sub text display -->
 | 
				
			||||||
 | 
									<span v-if="note.subtext.length > 0"
 | 
				
			||||||
 | 
										class="small-text"
 | 
				
			||||||
 | 
										v-html="note.subtext"></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<!-- Not indexed warning -->
 | 
				
			||||||
 | 
					<!-- 				<span v-if="note.indexed != 1">
 | 
				
			||||||
 | 
										<span class="green label">Not Indexed</span>
 | 
				
			||||||
 | 
									</span> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
			<div v-if="titleView" class="single-line-text" @click="cardClicked">
 | 
					<!-- 				<div class="ui fluid basic button" v-if="note.encrypted == 1">
 | 
				
			||||||
				<span class="title-line" v-if="note.title.length > 0">{{ note.title }}<br></span>
 | 
										<i class="green lock icon"></i>
 | 
				
			||||||
				<span class="sub-line" v-if="note.subtext.length > 0">{{ removeHtml(note.subtext) }}</span>
 | 
										Locked
 | 
				
			||||||
				<span v-if="note.title.length == 0 && note.title.length == 0">Empty Note</span>
 | 
									</div> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								<!-- slim card view  -->
 | 
				
			||||||
 | 
								<div v-if="titleView" class="thin-container" @click="cardClicked">
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
									<!-- icon -->
 | 
				
			||||||
 | 
									<span v-if="noteIcon" class="thin-icon">
 | 
				
			||||||
 | 
										<i :class="`${noteIcon} icon`" :style="{ 'color':iconColor }"></i>
 | 
				
			||||||
 | 
									</span>
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									<!-- title -->
 | 
				
			||||||
 | 
									<span class="thin-title" v-if="note.title.length > 0">{{ note.title }}</span>
 | 
				
			||||||
 | 
									
 | 
				
			||||||
 | 
									<!-- snippet  -->
 | 
				
			||||||
 | 
									<span class="thin-sub" v-if="note.subtext.length > 0">{{ removeHtml(note.subtext) }}</span>
 | 
				
			||||||
 | 
									<span v-if="note.title.length == 0 && removeHtml(note.subtext).length == 0">Empty Note</span>
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
									<!-- tags -->
 | 
				
			||||||
 | 
									<span v-if="note.tags" class="thin-tags" >
 | 
				
			||||||
 | 
										<span  v-for="tag in (note.tags.split(','))" class="little-tag" v-on:click="$emit('tagClick', tag.split(':')[1] )">#{{ tag.split(':')[0] }}
 | 
				
			||||||
 | 
										</span>
 | 
				
			||||||
 | 
									</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<!-- edited -->
 | 
				
			||||||
 | 
									<span class="thin-right">
 | 
				
			||||||
 | 
										{{$helpers.timeAgo( note.updated )}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										<i class="green link ellipsis vertical icon"></i>
 | 
				
			||||||
 | 
									</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
			<!-- Toolbar on the bottom  -->
 | 
								<!-- Toolbar on the bottom  -->
 | 
				
			||||||
			<div class="tool-bar" @click.self="cardClicked" v-if="!titleView">
 | 
								<div class="tool-bar" @click.self="cardClicked" v-if="!titleView">
 | 
				
			||||||
				<div class="icon-bar">
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<span class="time-ago-display" :class="{ 'hover-hide':(!$store.getters.getIsUserOnMobile) }">
 | 
									<div v-if="getThumbs.length > 0">
 | 
				
			||||||
 | 
										<div class="tiny-thumb-box" v-on:click="openEditAttachment">
 | 
				
			||||||
 | 
											<img v-for="thumb in getThumbs" class="tiny-thumb" :src="`/api/static/thumb_${thumb}`">
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									<div class="icon-bar" :class="{ 'hover-hide':(!$store.getters.getIsUserOnMobile) }">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										<span class="time-ago-display">
 | 
				
			||||||
						{{$helpers.timeAgo( note.updated )}}
 | 
											{{$helpers.timeAgo( note.updated )}}
 | 
				
			||||||
					</span>
 | 
										</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					<span class="teeny-buttons" :class="{ 'hover-hide':(!$store.getters.getIsUserOnMobile) }">
 | 
										<span class="teeny-buttons">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						<span v-if="!note.trashed">
 | 
											<span v-if="!note.trashed">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -115,19 +145,13 @@
 | 
				
			|||||||
							</i>
 | 
												</i>
 | 
				
			||||||
							<delete-button class="teeny-button" :note-id="note.id" />
 | 
												<delete-button class="teeny-button" :note-id="note.id" />
 | 
				
			||||||
						</span>
 | 
											</span>
 | 
				
			||||||
 | 
					 | 
				
			||||||
						
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					</span>
 | 
										</span>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<div v-if="getThumbs.length > 0">
 | 
									
 | 
				
			||||||
					<div class="tiny-thumb-box" v-on:click="openEditAttachment">
 | 
					 | 
				
			||||||
						<img v-for="thumb in getThumbs" class="tiny-thumb" :src="`/api/static/thumb_${thumb}`">
 | 
					 | 
				
			||||||
					</div>
 | 
					 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								<!-- tag edit menu -->
 | 
				
			||||||
			<side-slide-menu v-if="showTagSlideMenu" v-on:close="toggleTags(false)" :full-shadow="true" :skip-history="true">
 | 
								<side-slide-menu v-if="showTagSlideMenu" v-on:close="toggleTags(false)" :full-shadow="true" :skip-history="true">
 | 
				
			||||||
				<div class="ui basic segment">
 | 
									<div class="ui basic segment">
 | 
				
			||||||
					<note-tag-edit :noteId="note.id" :key="'display-tags-for-note-'+note.id"/>
 | 
										<note-tag-edit :noteId="note.id" :key="'display-tags-for-note-'+note.id"/>
 | 
				
			||||||
@@ -333,13 +357,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	.teeny-buttons {
 | 
						.teeny-buttons {
 | 
				
			||||||
		float: right;
 | 
							float: right;
 | 
				
			||||||
		width: 65%;
 | 
					 | 
				
			||||||
		text-align: right;
 | 
							text-align: right;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.time-ago-display {
 | 
						.time-ago-display {
 | 
				
			||||||
		width: 35%;
 | 
							font-size: 11px;
 | 
				
			||||||
		float: left;
 | 
							font-weight: bold;
 | 
				
			||||||
		text-align: center;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.tags {
 | 
						.tags {
 | 
				
			||||||
		width: 100%;
 | 
							width: 100%;
 | 
				
			||||||
@@ -364,9 +386,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/*Strict font sizes for card display*/
 | 
						/*Strict font sizes for card display*/
 | 
				
			||||||
	.small-text {
 | 
						.small-text {
 | 
				
			||||||
		max-height: 267px;
 | 
					 | 
				
			||||||
		width: 100%;
 | 
							width: 100%;
 | 
				
			||||||
		overflow: hidden;
 | 
					 | 
				
			||||||
		display: inline-block;
 | 
							display: inline-block;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.small-text, .small-text > p, .small-text > h1, .small-text > h2 {
 | 
						.small-text, .small-text > p, .small-text > h1, .small-text > h2 {
 | 
				
			||||||
@@ -426,7 +446,7 @@
 | 
				
			|||||||
		/*width: calc(33.333% - 10px);*/
 | 
							/*width: calc(33.333% - 10px);*/
 | 
				
			||||||
		width: calc(25% - 10px);
 | 
							width: calc(25% - 10px);
 | 
				
			||||||
		/*min-width: 190px;*/
 | 
							/*min-width: 190px;*/
 | 
				
			||||||
		min-height: 130px;
 | 
							/*min-height: 130px;*/
 | 
				
			||||||
		/*transition: box-shadow 0.3s;*/
 | 
							/*transition: box-shadow 0.3s;*/
 | 
				
			||||||
		box-sizing: border-box;
 | 
							box-sizing: border-box;
 | 
				
			||||||
		cursor: pointer;
 | 
							cursor: pointer;
 | 
				
			||||||
@@ -435,7 +455,11 @@
 | 
				
			|||||||
		letter-spacing: 0.05rem;
 | 
							letter-spacing: 0.05rem;
 | 
				
			||||||
		display: flex;
 | 
							display: flex;
 | 
				
			||||||
		flex-direction: column;
 | 
							flex-direction: column;
 | 
				
			||||||
 | 
							align-items: stretch;
 | 
				
			||||||
		text-align: left;
 | 
							text-align: left;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							min-height: 100px;
 | 
				
			||||||
 | 
							max-height: 450px;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.note-title-display-card:hover {
 | 
						.note-title-display-card:hover {
 | 
				
			||||||
		/*box-shadow: 0px 2px 2px 1px rgba(210, 211, 211, 0.8);*/
 | 
							/*box-shadow: 0px 2px 2px 1px rgba(210, 211, 211, 0.8);*/
 | 
				
			||||||
@@ -446,21 +470,49 @@
 | 
				
			|||||||
		width: 100%;
 | 
							width: 100%;
 | 
				
			||||||
		min-height: 20px;
 | 
							min-height: 20px;
 | 
				
			||||||
		max-width: none;
 | 
							max-width: none;
 | 
				
			||||||
 | 
							padding: 10px;
 | 
				
			||||||
 | 
							margin: 0;
 | 
				
			||||||
 | 
							overflow: hidden;
 | 
				
			||||||
 | 
							border-radius: 0;
 | 
				
			||||||
 | 
							border: none;
 | 
				
			||||||
		/*box-shadow: 0px 0px 1px 1px rgba(210, 211, 211, 0.46);*/
 | 
							/*box-shadow: 0px 0px 1px 1px rgba(210, 211, 211, 0.46);*/
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		
 | 
						.title-view + .title-view {
 | 
				
			||||||
	.single-line-text {
 | 
							border-top: 1px solid var(--border_color);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.thin-container.single-line-text {
 | 
				
			||||||
		width: calc(100% - 25px);
 | 
							width: calc(100% - 25px);
 | 
				
			||||||
		margin: 5px 10px;
 | 
							/*margin: 5px 10px;*/
 | 
				
			||||||
		white-space: nowrap;
 | 
							white-space: nowrap;
 | 
				
			||||||
		overflow: hidden;
 | 
							overflow: hidden;
 | 
				
			||||||
		text-overflow: ellipsis;
 | 
							text-overflow: ellipsis;
 | 
				
			||||||
		box-sizing: border-box;
 | 
							box-sizing: border-box;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.title-line {
 | 
					
 | 
				
			||||||
 | 
						.thin-container .thin-title {
 | 
				
			||||||
		font-weight: bold;
 | 
							font-weight: bold;
 | 
				
			||||||
		font-size: 1.2em;
 | 
							font-size: 1.2em;
 | 
				
			||||||
		padding: 0 20px 0 0;
 | 
						}
 | 
				
			||||||
 | 
						.thin-container .thin-sub {
 | 
				
			||||||
 | 
							overflow: hidden;
 | 
				
			||||||
 | 
							text-overflow: ellipsis;
 | 
				
			||||||
 | 
							display: -webkit-box;
 | 
				
			||||||
 | 
							-webkit-line-clamp: 2;
 | 
				
			||||||
 | 
							line-clamp: 2; 
 | 
				
			||||||
 | 
							-webkit-box-orient: vertical;
 | 
				
			||||||
 | 
							opacity: 0.85;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						.thin-container .thin-tags {
 | 
				
			||||||
 | 
							float: left;
 | 
				
			||||||
 | 
							margin-top: 3px;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						.thin-container .thin-right {
 | 
				
			||||||
 | 
							float: right;
 | 
				
			||||||
 | 
							color: var(--dark_border_color);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						.thin-container .thin-icon {
 | 
				
			||||||
 | 
							float: right;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	.icon-bar {
 | 
						.icon-bar {
 | 
				
			||||||
@@ -468,6 +520,7 @@
 | 
				
			|||||||
		padding: 5px 10px 0;
 | 
							padding: 5px 10px 0;
 | 
				
			||||||
		opacity: 1;
 | 
							opacity: 1;
 | 
				
			||||||
		width: 100%;
 | 
							width: 100%;
 | 
				
			||||||
 | 
							background-color: rgba(200, 200, 200, 0.2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	.hover-hide {
 | 
						.hover-hide {
 | 
				
			||||||
		opacity: 0.0;
 | 
							opacity: 0.0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -191,11 +191,24 @@
 | 
				
			|||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								<!-- Overview -->
 | 
				
			||||||
 | 
								<div class="middle aligned centered row">
 | 
				
			||||||
 | 
									<div class="six wide column">
 | 
				
			||||||
 | 
										<h2 class="ui dividing header">Powerful text editing and privacy</h2>
 | 
				
			||||||
 | 
										<h3>Easily edit, share and organize thousands of notes.</h3>
 | 
				
			||||||
 | 
										<h3>Feel safe knowing no one can read your notes but you.</h3>
 | 
				
			||||||
 | 
										<!-- <h3>Tools to organize and collaborate on thousands of notes while maintaining security and respecting your privacy.</h3> -->
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<div class="four wide column">
 | 
				
			||||||
 | 
										<img loading="lazy" width="100%" src="/api/static/assets/marketing/idea.svg" alt="Explosion of New Ideas">
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<!-- theme selector -->
 | 
								<!-- theme selector -->
 | 
				
			||||||
			<div class="ui white row">
 | 
								<div class="ui white row">
 | 
				
			||||||
				<div class="sixteen wide middle aligned column">
 | 
									<div class="sixteen wide middle aligned column">
 | 
				
			||||||
					<div class="ui container">
 | 
										<div class="ui container">
 | 
				
			||||||
						<h2>
 | 
											<h2 style="color: var(--main-accent);">
 | 
				
			||||||
							Pick your theme
 | 
												Pick your theme
 | 
				
			||||||
						</h2>
 | 
											</h2>
 | 
				
			||||||
						<h3 v-if="$parent.loggedIn">Go to settings to change theme</h3>
 | 
											<h3 v-if="$parent.loggedIn">Go to settings to change theme</h3>
 | 
				
			||||||
@@ -211,19 +224,6 @@
 | 
				
			|||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<!-- Overview -->
 | 
					 | 
				
			||||||
			<div class="middle aligned centered row">
 | 
					 | 
				
			||||||
				<div class="six wide column">
 | 
					 | 
				
			||||||
					<h2 class="ui dividing header">Powerful text editing and privacy</h2>
 | 
					 | 
				
			||||||
					<h3>Easily edit, share and organize thousands of notes.</h3>
 | 
					 | 
				
			||||||
					<h3>Feel safe knowing no one can read your notes but you.</h3>
 | 
					 | 
				
			||||||
					<!-- <h3>Tools to organize and collaborate on thousands of notes while maintaining security and respecting your privacy.</h3> -->
 | 
					 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
				<div class="four wide column">
 | 
					 | 
				
			||||||
					<img loading="lazy" width="100%" src="/api/static/assets/marketing/idea.svg" alt="Explosion of New Ideas">
 | 
					 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
			</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			<!-- features list -->
 | 
								<!-- features list -->
 | 
				
			||||||
			<div class="top aligned centered row">
 | 
								<div class="top aligned centered row">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -355,7 +355,7 @@
 | 
				
			|||||||
								<i class="grey lock icon"></i> 
 | 
													<i class="grey lock icon"></i> 
 | 
				
			||||||
								<i class="bottom left corner yellow key icon"></i> 
 | 
													<i class="bottom left corner yellow key icon"></i> 
 | 
				
			||||||
							</i>
 | 
												</i>
 | 
				
			||||||
							All Note Text is Encrypted
 | 
												Secure Notes
 | 
				
			||||||
							<div class="sub header">All note text is encrypted. No one can read your notes. None of your data is shared.</div>
 | 
												<div class="sub header">All note text is encrypted. No one can read your notes. None of your data is shared.</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</h2>
 | 
										</h2>
 | 
				
			||||||
@@ -365,7 +365,7 @@
 | 
				
			|||||||
								<i class="grey search icon"></i> 
 | 
													<i class="grey search icon"></i> 
 | 
				
			||||||
								<i class="bottom left corner orange font icon"></i> 
 | 
													<i class="bottom left corner orange font icon"></i> 
 | 
				
			||||||
							</i>
 | 
												</i>
 | 
				
			||||||
							Note Search is Encrypted
 | 
												Private Search
 | 
				
			||||||
							<div class="sub header">Search the contents of all your notes without compromising security.</div>
 | 
												<div class="sub header">Search the contents of all your notes without compromising security.</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</h2>
 | 
										</h2>
 | 
				
			||||||
@@ -375,7 +375,7 @@
 | 
				
			|||||||
								<i class="grey share alternate icon"></i> 
 | 
													<i class="grey share alternate icon"></i> 
 | 
				
			||||||
								<i class="bottom left corner share icon"></i> 
 | 
													<i class="bottom left corner share icon"></i> 
 | 
				
			||||||
							</i>
 | 
												</i>
 | 
				
			||||||
							Encrypted Note Sharing
 | 
												Encrypted Sharing
 | 
				
			||||||
							<div class="sub header">Shared notes are still encrypted, only readable by you and the shared users.</div>
 | 
												<div class="sub header">Shared notes are still encrypted, only readable by you and the shared users.</div>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</h2>
 | 
										</h2>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,9 +27,15 @@
 | 
				
			|||||||
							v-on:tagClick="tagId => toggleTagFilter(tagId)"
 | 
												v-on:tagClick="tagId => toggleTagFilter(tagId)"
 | 
				
			||||||
						/>
 | 
											/>
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
						<div class="ui basic shrinking icon button" v-on:click="toggleTitleView()" v-if="$store.getters.totals && $store.getters.totals['totalNotes'] > 0">
 | 
											<div class="ui right floated basic shrinking icon button" v-on:click="toggleTitleView()" v-if="$store.getters.totals && $store.getters.totals['totalNotes'] > 0">
 | 
				
			||||||
							<i v-if="titleView" class="th icon"></i>
 | 
												<span v-if="titleView">
 | 
				
			||||||
							<i v-if="!titleView" class="bars icon"></i>
 | 
													<i class="th icon"></i> Tiles
 | 
				
			||||||
 | 
												</span>
 | 
				
			||||||
 | 
												<span v-if="!titleView">
 | 
				
			||||||
 | 
													<i  class="list icon"></i> List
 | 
				
			||||||
 | 
												</span>
 | 
				
			||||||
 | 
												
 | 
				
			||||||
 | 
												
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
@@ -223,6 +229,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			this.$parent.loginGateway()
 | 
								this.$parent.loginGateway()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								//If user is on title view, 
 | 
				
			||||||
 | 
								this.titleView = this.$store.getters.getIsUserOnMobile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			this.$io.on('new_note_created', noteId => {
 | 
								this.$io.on('new_note_created', noteId => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				//Do not update note if its open
 | 
									//Do not update note if its open
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,4 +11,5 @@ common.js
 | 
				
			|||||||
bundle.*
 | 
					bundle.*
 | 
				
			||||||
client/dist*
 | 
					client/dist*
 | 
				
			||||||
server/public/*
 | 
					server/public/*
 | 
				
			||||||
client/dist*
 | 
					client/dist*
 | 
				
			||||||
 | 
					*_scrape*
 | 
				
			||||||
@@ -6,6 +6,7 @@ const speakeasy = require('speakeasy')
 | 
				
			|||||||
let Auth = {}
 | 
					let Auth = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const tokenSecretKey = process.env.JSON_KEY
 | 
					const tokenSecretKey = process.env.JSON_KEY
 | 
				
			||||||
 | 
					const sessionTokenUses = 300 //Defines number of uses each session token has before being refreshed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Creates session token 
 | 
					//Creates session token 
 | 
				
			||||||
Auth.createToken = (userId, masterKey, pastId = null, pastCreatedDate = null) => {
 | 
					Auth.createToken = (userId, masterKey, pastId = null, pastCreatedDate = null) => {
 | 
				
			||||||
@@ -26,7 +27,7 @@ Auth.createToken = (userId, masterKey, pastId = null, pastCreatedDate = null) =>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return db.promise().query(
 | 
								return db.promise().query(
 | 
				
			||||||
			'INSERT INTO user_active_session (salt, encrypted_master_password, created, uses, user_hash, session_id) VALUES (?,?,?,?,?,?)', 
 | 
								'INSERT INTO user_active_session (salt, encrypted_master_password, created, uses, user_hash, session_id) VALUES (?,?,?,?,?,?)', 
 | 
				
			||||||
			[salt, encryptedMasterPass, created, 40, userHash, sessionId])
 | 
								[salt, encryptedMasterPass, created, sessionTokenUses, userHash, sessionId])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		.then((r,f) => {
 | 
							.then((r,f) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,7 +54,7 @@ SiteScrape.getCleanUrls = (textBlock) => {
 | 
				
			|||||||
SiteScrape.getHostName = (url) => {
 | 
					SiteScrape.getHostName = (url) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var hostname = 'https://'+(new URL(url)).hostname;
 | 
						var hostname = 'https://'+(new URL(url)).hostname;
 | 
				
			||||||
	console.log('hostname', hostname)
 | 
						// console.log('hostname', hostname)
 | 
				
			||||||
	return hostname
 | 
						return hostname
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,36 +63,95 @@ SiteScrape.getDisplayImage = ($, url) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	const hostname = SiteScrape.getHostName(url)
 | 
						const hostname = SiteScrape.getHostName(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let metaImg = $('meta[property="og:image"]')
 | 
						let metaImg = $('[property="og:image"]')
 | 
				
			||||||
	let shortcutIcon = $('link[rel="shortcut icon"]')
 | 
						let shortcutIcon = $('[rel="shortcut icon"]')
 | 
				
			||||||
	let favicon = $('link[rel="icon"]')
 | 
						let favicon = $('[rel="icon"]')
 | 
				
			||||||
	let randomImg = $('img')
 | 
						let randomImg = $('img')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	console.log('----')
 | 
						//Set of images we may want gathered from various places in source
 | 
				
			||||||
 | 
						let imagesWeWant = []
 | 
				
			||||||
 | 
						let thumbnail = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//Scrape metadata for page image
 | 
						//Scrape metadata for page image
 | 
				
			||||||
	//Grab the first random image we find
 | 
						if(randomImg && randomImg.length > 0){
 | 
				
			||||||
	if(randomImg && randomImg[0] && randomImg[0].attribs){
 | 
					
 | 
				
			||||||
		thumbnail = hostname + randomImg[0].attribs.src
 | 
							let imgSrcs = []
 | 
				
			||||||
		console.log('random img '+thumbnail)
 | 
							for (let i = 0; i < randomImg.length; i++) {
 | 
				
			||||||
 | 
								imgSrcs.push( randomImg[i].attribs.src )
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const half = Math.ceil(imgSrcs.length / 2)
 | 
				
			||||||
 | 
							imagesWeWant = [...imgSrcs.slice(-half), ...imgSrcs.slice(0,half) ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//Grab the favicon of the site
 | 
						//Grab the shortcut icon
 | 
				
			||||||
	if(favicon && favicon[0] && favicon[0].attribs){
 | 
						if(favicon && favicon[0] && favicon[0].attribs){
 | 
				
			||||||
		thumbnail = hostname + favicon[0].attribs.href
 | 
							imagesWeWant.push(favicon[0].attribs.href)
 | 
				
			||||||
		console.log('favicon '+thumbnail)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//Grab the shortcut icon
 | 
						//Grab the shortcut icon
 | 
				
			||||||
	if(shortcutIcon && shortcutIcon[0] && shortcutIcon[0].attribs){
 | 
						if(shortcutIcon && shortcutIcon[0] && shortcutIcon[0].attribs){
 | 
				
			||||||
		thumbnail = hostname + shortcutIcon[0].attribs.href
 | 
							imagesWeWant.push(shortcutIcon[0].attribs.href)
 | 
				
			||||||
		console.log('shortcut '+thumbnail)
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	//Grab the presentation image for the site
 | 
						//Grab the presentation image for the site
 | 
				
			||||||
	if(metaImg && metaImg[0] && metaImg[0].attribs){
 | 
						if(metaImg && metaImg[0] && metaImg[0].attribs){
 | 
				
			||||||
		thumbnail = metaImg[0].attribs.content
 | 
							imagesWeWant.unshift(metaImg[0].attribs.content)
 | 
				
			||||||
		console.log('ogImg '+thumbnail)
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// console.log(imagesWeWant)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//Remove everything that isn't an accepted file format
 | 
				
			||||||
 | 
						for (let i = imagesWeWant.length - 1; i >= 0; i--) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let img = String(imagesWeWant[i])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(
 | 
				
			||||||
 | 
								!img.includes('.jpg') && 
 | 
				
			||||||
 | 
								!img.includes('.jpeg') && 
 | 
				
			||||||
 | 
								!img.includes('.png') && 
 | 
				
			||||||
 | 
								!img.includes('.gif')
 | 
				
			||||||
 | 
							){
 | 
				
			||||||
 | 
								imagesWeWant.splice(i,1)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//Find if we have absolute thumbnails or not
 | 
				
			||||||
 | 
						let foundAbsolute = false
 | 
				
			||||||
 | 
						for (let i = imagesWeWant.length - 1; i >= 0; i--) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let img = imagesWeWant[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//Add host name if its not included
 | 
				
			||||||
 | 
							if(String(img).includes('//') || String(img).includes('http')){
 | 
				
			||||||
 | 
								foundAbsolute = true
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//Go through all found images. Grab the one closest to the top. Closer is better
 | 
				
			||||||
 | 
						for (let i = imagesWeWant.length - 1; i >= 0; i--) {
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							let img = imagesWeWant[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(!String(img).includes('//') && foundAbsolute){
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//Only add host to images if no absolute images were found
 | 
				
			||||||
 | 
							if(!String(img).includes('//') ){
 | 
				
			||||||
 | 
								if(img.indexOf('/') != 0){
 | 
				
			||||||
 | 
									img = '/' + img
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								img = hostname + img
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(img.indexOf('//') == 0){
 | 
				
			||||||
 | 
								img = 'https:' + img //Scrape breaks without protocol 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
							thumbnail = img
 | 
				
			||||||
 | 
							
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	console.log('-----')
 | 
					 | 
				
			||||||
	return thumbnail
 | 
						return thumbnail
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -257,7 +257,6 @@ const printResults = true
 | 
				
			|||||||
let UserTest = require('@models/User')
 | 
					let UserTest = require('@models/User')
 | 
				
			||||||
let NoteTest = require('@models/Note')
 | 
					let NoteTest = require('@models/Note')
 | 
				
			||||||
let AuthTest = require('@helpers/Auth')
 | 
					let AuthTest = require('@helpers/Auth')
 | 
				
			||||||
 | 
					 | 
				
			||||||
Auth.test()
 | 
					Auth.test()
 | 
				
			||||||
UserTest.keyPairTest('genMan30', '1', printResults)
 | 
					UserTest.keyPairTest('genMan30', '1', printResults)
 | 
				
			||||||
.then( ({testUserId, masterKey}) => NoteTest.test(testUserId, masterKey, printResults))
 | 
					.then( ({testUserId, masterKey}) => NoteTest.test(testUserId, masterKey, printResults))
 | 
				
			||||||
@@ -266,7 +265,6 @@ UserTest.keyPairTest('genMan30', '1', printResults)
 | 
				
			|||||||
	Auth.testTwoFactor()
 | 
						Auth.testTwoFactor()
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
//Test 
 | 
					//Test 
 | 
				
			||||||
app.get('/api', (req, res) => res.send('Solidscribe API is up and running'))
 | 
					app.get('/api', (req, res) => res.send('Solidscribe API is up and running'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -325,14 +325,14 @@ Attachment.downloadFileFromUrl = (url) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return new Promise((resolve, reject) => {
 | 
						return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(url == null){
 | 
								if(url == null || url == undefined || url == ''){
 | 
				
			||||||
				resolve(null)
 | 
									resolve(null)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const random = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
 | 
								const random = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
 | 
				
			||||||
			const extension = '.'+url.split('.').pop() //This is throwing an error
 | 
								let extension = ''
 | 
				
			||||||
			let fileName = random+'_scrape'+extension
 | 
								let fileName = random+'_scrape'
 | 
				
			||||||
			const thumbPath = 'thumb_'+fileName
 | 
								let thumbPath = 'thumb_'+fileName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			console.log('Scraping image url')
 | 
								console.log('Scraping image url')
 | 
				
			||||||
			console.log(url)
 | 
								console.log(url)
 | 
				
			||||||
@@ -347,6 +347,8 @@ Attachment.downloadFileFromUrl = (url) => {
 | 
				
			|||||||
				.on('response', res => {
 | 
									.on('response', res => {
 | 
				
			||||||
					console.log(res.statusCode)
 | 
										console.log(res.statusCode)
 | 
				
			||||||
					console.log(res.headers['content-type'])
 | 
										console.log(res.headers['content-type'])
 | 
				
			||||||
 | 
										//Get mime type from header content type
 | 
				
			||||||
 | 
										// extension = '.'+String(res.headers['content-type']).split('/').pop()
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
				.pipe(fs.createWriteStream(filePath+thumbPath))
 | 
									.pipe(fs.createWriteStream(filePath+thumbPath))
 | 
				
			||||||
				.on('close', () => {
 | 
									.on('close', () => {
 | 
				
			||||||
@@ -354,14 +356,17 @@ Attachment.downloadFileFromUrl = (url) => {
 | 
				
			|||||||
					//resize image if its real big
 | 
										//resize image if its real big
 | 
				
			||||||
					gm(filePath+thumbPath)
 | 
										gm(filePath+thumbPath)
 | 
				
			||||||
					.resize(550) //Resize to width of 550 px 
 | 
										.resize(550) //Resize to width of 550 px 
 | 
				
			||||||
					.quality(75) //compression level 0 - 100 (best)
 | 
										.quality(85) //compression level 0 - 100 (best)
 | 
				
			||||||
					.write(filePath+thumbPath, function (err) {
 | 
										.write(filePath+thumbPath, function (err) {
 | 
				
			||||||
						if(err){ console.log(err) }
 | 
											if(err){ 
 | 
				
			||||||
 | 
												console.log(err) 
 | 
				
			||||||
 | 
												return resolve(null)
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											console.log('Saved Image')
 | 
				
			||||||
 | 
											return resolve(fileName)
 | 
				
			||||||
					})
 | 
										})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
					console.log('Saved Image')
 | 
					 | 
				
			||||||
					resolve(fileName)
 | 
					 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -396,7 +401,7 @@ Attachment.processUrl = (userId, noteId, url) => {
 | 
				
			|||||||
		.query(`INSERT INTO attachment 
 | 
							.query(`INSERT INTO attachment 
 | 
				
			||||||
			(note_id, user_id, attachment_type, text, url, last_indexed, file_location) 
 | 
								(note_id, user_id, attachment_type, text, url, last_indexed, file_location) 
 | 
				
			||||||
			VALUES (?, ?, ?, ?, ?, ?, ?)`, 
 | 
								VALUES (?, ?, ?, ?, ?, ?, ?)`, 
 | 
				
			||||||
			[noteId, userId, 1, 'Processing...', url, created, null])
 | 
								[noteId, userId, 1, url, url, created, null])
 | 
				
			||||||
		.then((rows, fields) => {
 | 
							.then((rows, fields) => {
 | 
				
			||||||
			//Set two bigger variables then return request for processing
 | 
								//Set two bigger variables then return request for processing
 | 
				
			||||||
			request = rp(options)
 | 
								request = rp(options)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -681,6 +681,7 @@ Note.get = (userId, noteId, masterKey) => {
 | 
				
			|||||||
					note_raw_text.text, 
 | 
										note_raw_text.text, 
 | 
				
			||||||
					note_raw_text.salt, 
 | 
										note_raw_text.salt, 
 | 
				
			||||||
					note_raw_text.updated as updated,
 | 
										note_raw_text.updated as updated,
 | 
				
			||||||
 | 
										GROUP_CONCAT(DISTINCT(tag.text) ORDER BY tag.text DESC) AS tags,
 | 
				
			||||||
					note.id,
 | 
										note.id,
 | 
				
			||||||
					note.user_id,
 | 
										note.user_id,
 | 
				
			||||||
					note.created,
 | 
										note.created,
 | 
				
			||||||
@@ -697,7 +698,9 @@ Note.get = (userId, noteId, masterKey) => {
 | 
				
			|||||||
				JOIN note_raw_text ON (note_raw_text.id = note.note_raw_text_id)
 | 
									JOIN note_raw_text ON (note_raw_text.id = note.note_raw_text_id)
 | 
				
			||||||
				LEFT JOIN attachment ON (note.id = attachment.note_id)
 | 
									LEFT JOIN attachment ON (note.id = attachment.note_id)
 | 
				
			||||||
				LEFT JOIN user as shareUser ON (note.share_user_id = shareUser.id)
 | 
									LEFT JOIN user as shareUser ON (note.share_user_id = shareUser.id)
 | 
				
			||||||
				WHERE note.user_id = ? AND note.id = ? LIMIT 1`, [userId, noteId])
 | 
									LEFT JOIN note_tag ON (note.id = note_tag.note_id AND note_tag.user_id = ?)
 | 
				
			||||||
 | 
									LEFT JOIN tag ON (note_tag.tag_id = tag.id)
 | 
				
			||||||
 | 
									WHERE note.user_id = ? AND note.id = ? LIMIT 1`, [userId, userId, noteId])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		.then((rows, fields) => {
 | 
							.then((rows, fields) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,6 +138,33 @@ Tag.get = (userId, noteId) => {
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Get just tag string for note
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					Tag.fornote = (userId, noteId) => {
 | 
				
			||||||
 | 
						return new Promise((resolve, reject) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
								db.promise()
 | 
				
			||||||
 | 
								.query(`SELECT GROUP_CONCAT(DISTINCT(tag.text) ORDER BY tag.text DESC) AS tags 
 | 
				
			||||||
 | 
										FROM note_tag
 | 
				
			||||||
 | 
										LEFT JOIN tag ON (note_tag.tag_id = tag.id)
 | 
				
			||||||
 | 
										WHERE note_tag.note_id = ?
 | 
				
			||||||
 | 
										AND user_id = ?;
 | 
				
			||||||
 | 
										`, [noteId,userId])
 | 
				
			||||||
 | 
								.then((rows, fields) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									//pull IDs out of returned results
 | 
				
			||||||
 | 
									// let ids = rows[0].map( item => {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									resolve( rows[0][0] ) //Return all tags found by query
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								.catch(console.log)
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Get all tags for a note and concatinate into a string 'all, tags, like, this'
 | 
					// Get all tags for a note and concatinate into a string 'all, tags, like, this'
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ const speakeasy = require('speakeasy')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
let User = module.exports = {}
 | 
					let User = module.exports = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const version = '3.3.1'
 | 
					const version = '3.3.3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Login a user, if that user does not exist create them
 | 
					//Login a user, if that user does not exist create them
 | 
				
			||||||
//Issues login token
 | 
					//Issues login token
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,6 +50,12 @@ router.post('/get', function (req, res) {
 | 
				
			|||||||
	.then( data => res.send(data) )
 | 
						.then( data => res.send(data) )
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//Get the latest notes the user has created
 | 
				
			||||||
 | 
					router.post('/fornote', function (req, res) {
 | 
				
			||||||
 | 
						Tags.fornote(userId, req.body.noteId)
 | 
				
			||||||
 | 
						.then( data => res.send(data) )
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Get all the tags for this user in order of usage
 | 
					//Get all the tags for this user in order of usage
 | 
				
			||||||
router.post('/usertags', function (req, res) {
 | 
					router.post('/usertags', function (req, res) {
 | 
				
			||||||
	Tags.userTags(userId, req.body.searchQuery, req.body.searchTags, req.body.fastFilters)
 | 
						Tags.userTags(userId, req.body.searchQuery, req.body.searchTags, req.body.fastFilters)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user