2021-01-31 02:43:13 +13:00
< template >
< div id = "q-app" >
2021-02-26 14:50:46 +13:00
< appWindowButtons / >
2021-01-31 02:43:13 +13:00
< router-view / >
2021-06-07 12:57:36 +12:00
< q-window
v - model = "documentPreviewWindowVisible"
no - resize
dark
headless
ref = "documentPreviewWindow"
@ input = "refreshDocumentPreviewWindow"
no - move
: content - class = "{'bg-gunmetal-light text-accent docPreviewWindow': true, '-noBar': disableDocumentControlBar}"
>
< div class = "fit" >
< q-btn
icon = "mdi-close"
color = "secondary"
round
flat
size = "md"
class = "previewCloseButton"
@ click = "refreshDocumentPreviewWindow(false)"
>
< q-tooltip
: delay = "500"
anchor = "bottom middle"
self = "top middle"
>
Close document preview
< / q-tooltip >
< / q-btn >
< documentPreview
: document - id = "documentPreviewElementID"
: display - mode = "'document'"
/ >
< / div >
< / q-window >
< q-window
2021-04-13 13:32:59 +12:00
v - model = "advSearchWindowVisible"
2021-04-13 07:27:44 +12:00
no - resize
2021-04-18 02:43:13 +12:00
dark
2021-04-13 07:27:44 +12:00
title = "Advanced Search Cheatsheet"
2021-05-06 11:59:10 +12:00
: height = "625"
2021-05-04 07:49:11 +12:00
: width = "500"
2021-04-13 13:32:59 +12:00
: start - x = "50"
2021-04-29 05:33:51 +12:00
: start - y = "150"
2021-05-02 02:31:33 +12:00
: actions = "['pin', 'close']"
2021-04-13 13:32:59 +12:00
content - class = "bg-gunmetal-light text-accent advSearchWindow"
2021-04-13 07:27:44 +12:00
>
< div class = "q-pa-md fit" >
< q-markdown no -heading -anchor -links >
{ { $t ( 'documents.advancedSearchCheatSheet' ) } }
< / q-markdown >
< / div >
< / q-window >
2021-05-02 02:31:33 +12:00
< q-window
v - model = "corkboardWindowVisible"
dark
title = "Note board"
gripper - border - color = "primary"
gripper - background - color = "primary"
: height = "600"
: width = "350"
: start - x = "350"
: start - y = "100"
: actions = "['pin', 'close']"
2021-05-02 05:07:03 +12:00
content - class = "bg-gunmetal-light text-accent noteBoardWindow"
2021-05-02 02:31:33 +12:00
>
2021-06-07 12:57:36 +12:00
< form
class = "corkboardInput"
autocorrect = "off"
autocapitalize = "off"
autocomplete = "off"
spellcheck = "false"
>
< q-input
v - model = "corkboardContent"
filled
dark
@ keyup = "processCorkboardInput"
type = "textarea"
/ >
< / form >
2021-05-02 02:31:33 +12:00
< / q-window >
2021-06-07 12:57:36 +12:00
2021-01-31 02:43:13 +13:00
< / div >
< / template >
< script lang = "ts" >
import BaseClass from "src/BaseClass"
2021-03-18 10:26:08 +13:00
import { Component , Watch } from "vue-property-decorator"
2021-02-26 14:50:46 +13:00
import { defaultKeybinds } from "src/scripts/appSettings/defaultKeybinds"
import appWindowButtons from "src/components/appHeader/AppWindowButtons.vue"
2021-03-18 10:26:08 +13:00
import PouchDB from "pouchdb"
import { OptionsStateInteface } from "./store/module-options/state"
import { colors } from "quasar"
2021-03-21 07:13:46 +13:00
import { tipsTricks } from "src/scripts/utilities/tipsTricks"
2021-03-22 05:06:38 +13:00
import { shell } from "electron"
2021-04-11 13:40:03 +12:00
import { summonAllPlusheForms } from "src/scripts/utilities/plusheMascot"
2021-06-13 08:23:20 +12:00
import { saveCorkboard , retrieveCorkboard , retrieveCurrentProjectName } from "src/scripts/projectManagement/projectManagent"
2021-06-07 12:57:36 +12:00
import documentPreview from "src/components/DocumentPreview.vue"
2021-02-26 14:50:46 +13:00
@ Component ( {
components : {
2021-06-07 12:57:36 +12:00
documentPreview : documentPreview ,
2021-02-26 14:50:46 +13:00
appWindowButtons : appWindowButtons
}
} )
2021-01-31 02:43:13 +13:00
export default class App extends BaseClass {
2021-04-06 01:28:33 +12:00
/****************************************************************/
// APP START & END SETUP
/****************************************************************/
2021-05-04 07:49:11 +12:00
async created ( ) {
2021-04-06 01:28:33 +12:00
// Catch middle clicks
2021-02-23 11:30:18 +13:00
window . addEventListener ( "auxclick" , this . reactToMiddleClick )
2021-04-06 01:28:33 +12:00
// Add a secondary blocker to prevent the middle-mouse button scrolling
2021-02-23 11:30:18 +13:00
document . body . onmousedown = function ( e ) {
if ( e . button === 1 ) {
e . preventDefault ( )
return false
}
}
2021-04-06 01:28:33 +12:00
// Load settings
2021-05-04 07:49:11 +12:00
await this . loadSettings ( )
2021-04-06 01:28:33 +12:00
2021-05-04 07:49:11 +12:00
await this . loadCorkboardCotent ( )
2021-04-06 01:28:33 +12:00
2021-06-13 08:23:20 +12:00
const currentProjectName = await retrieveCurrentProjectName ( )
this . SSET _setProjectName ( currentProjectName )
2021-05-14 05:51:35 +12:00
// Load the popup hint on
2021-03-21 07:13:46 +13:00
this . loadHintPopup ( )
2021-05-02 02:31:33 +12:00
2021-05-04 07:49:11 +12:00
// React to keybind presses
window . addEventListener ( "keydown" , this . triggerKeyPush )
// Catch normal clicks inside wysiwyg
window . addEventListener ( "click" , this . openWysiwygLink )
2021-03-21 07:13:46 +13:00
}
2021-04-06 01:28:33 +12:00
destroyed ( ) {
window . removeEventListener ( "auxclick" , this . reactToMiddleClick )
this . deregisterCustomKeybinds ( )
this . deregisterDefaultKeybinds ( )
window . removeEventListener ( "keydown" , this . triggerKeyPush )
2021-03-22 05:06:38 +13:00
}
2021-04-06 01:28:33 +12:00
/****************************************************************/
// START NOTIFICATION
/****************************************************************/
2021-03-21 07:13:46 +13:00
2021-04-06 01:28:33 +12:00
/ * *
* Model for the startup notification
* /
2021-03-21 13:55:17 +13:00
starupNotif = null as any
2021-04-06 01:28:33 +12:00
/ * *
* Notification checker
* Can go up to 3
* /
popupCheck = 0
/ * *
* Show the actual popup
* /
2021-03-21 07:13:46 +13:00
loadHintPopup ( ) {
const options = this . SGET _options
// Considering there is a bit of a delay between the initial load of the store DB content, we give the program 3 attempts to load the data over 3 seconds. If no is loaded in that time, we assume that the settings are not set at all and display the hint as normal.
if ( ( ! options . _id || ! options . _rev ) && this . popupCheck < 3 ) {
setTimeout ( ( ) => {
this . popupCheck ++
this . loadHintPopup ( )
} , 1000 )
return
}
if ( options . hideTooltipsStart ) {
return
}
const messageToShow = tipsTricks [ Math . floor ( Math . random ( ) * tipsTricks . length ) ]
2021-04-11 13:40:03 +12:00
const plusheForm = summonAllPlusheForms [ Math . floor ( Math . random ( ) * summonAllPlusheForms . length ) ]
2021-03-21 13:55:17 +13:00
this . starupNotif = this . $q . notify ( {
2021-04-11 13:40:03 +12:00
2021-03-21 07:13:46 +13:00
timeout : 15000 ,
2021-04-11 13:40:03 +12:00
icon : ( this . hidePlushes ) ? "mdi-help" : undefined ,
color : "info" ,
2021-03-21 07:13:46 +13:00
message : "Did you know?" ,
2021-04-11 13:40:03 +12:00
avatar : ( ! this . hidePlushes ) ? plusheForm : undefined ,
2021-03-21 07:13:46 +13:00
caption : messageToShow ,
actions : [ { icon : "mdi-close" , color : "white" } ]
} )
2021-02-26 14:50:46 +13:00
}
2021-04-06 01:28:33 +12:00
/ * *
* Hide the startup notification if the user changed the route before it disappeared
* /
2021-03-21 13:55:17 +13:00
@ Watch ( "$route" , { deep : true } )
onUrlChange ( ) {
2021-03-22 05:06:38 +13:00
if ( typeof this . starupNotif === "function" ) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
this . starupNotif ( )
}
2021-03-21 13:55:17 +13:00
}
2021-04-06 01:28:33 +12:00
/****************************************************************/
// KEYBIND HANDLING
/****************************************************************/
/ * *
* React to keybind combinations being pushed and submit them to the store
* /
2021-02-26 14:50:46 +13:00
triggerKeyPush ( e : any ) {
2021-03-08 11:07:40 +13:00
// console.log("")
// console.log(`Key: ${e.key}`)
// console.log(`Ctrl: ${e.ctrlKey}`)
// console.log(`Shift: ${e.shiftKey}`)
// console.log(`Alt: ${e.altKey}`)
// console.log(e)
2021-02-26 14:50:46 +13:00
if ( e ? . altKey === true || e ? . ctrlKey || e ? . shiftKey ) {
const ouputKeycombo = {
altKey : e . altKey ,
ctrlKey : e . ctrlKey ,
shiftKey : e . shiftKey ,
2021-03-18 10:26:08 +13:00
which : e . which
2021-02-26 14:50:46 +13:00
}
this . SSET _updatePressedKey ( ouputKeycombo )
}
2021-02-23 11:30:18 +13:00
}
2021-04-06 01:28:33 +12:00
/ * *
* Registers a default keybind into the store
* /
2021-02-23 11:30:18 +13:00
registerDefaultKeybinds ( ) {
2021-04-10 12:36:36 +12:00
// @ts-ignore
2021-02-23 11:30:18 +13:00
defaultKeybinds . forEach ( e => this . SSET _registerDefaultKeybind ( e ) )
}
2021-01-31 02:43:13 +13:00
2021-04-06 01:28:33 +12:00
/ * *
* Removes a default keybind from the store
* /
2021-02-23 11:30:18 +13:00
deregisterDefaultKeybinds ( ) {
2021-04-10 12:36:36 +12:00
// @ts-ignore
2021-02-23 11:30:18 +13:00
defaultKeybinds . forEach ( e => this . SSET _deregisterDefaultKeybind ( e ) )
}
2021-03-18 10:26:08 +13:00
2021-04-06 01:28:33 +12:00
/ * *
* Registers a custom keybind into the store
* /
2021-03-18 10:26:08 +13:00
registerCustomKeybinds ( ) {
setTimeout ( ( ) => {
this . SGET _options . userKeybindList . forEach ( e => this . SSET _registerUserKeybind ( e ) )
} , 1000 )
}
2021-04-06 01:28:33 +12:00
/ * *
* Removes a custom keybind from the store
* /
2021-03-18 10:26:08 +13:00
deregisterCustomKeybinds ( ) {
2021-04-10 12:36:36 +12:00
// @ts-ignore
2021-03-18 10:26:08 +13:00
defaultKeybinds . forEach ( e => this . SSET _deregisterUserKeybind ( e ) )
}
2021-04-06 01:28:33 +12:00
/****************************************************************/
// VARIOUS APP FUNCTIONALITY
/****************************************************************/
/ * *
* Open wysiwyg links in default browser window
* /
openWysiwygLink ( event : MouseEvent ) {
2021-04-29 05:33:51 +12:00
event . preventDefault ( )
2021-04-06 01:28:33 +12:00
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if ( event . target && event . target . tagName . toLowerCase ( ) === "a" && event . target . closest ( ".fieldWysiwyg" ) ) {
2021-04-29 05:33:51 +12:00
const isValidHttpUrl = ( string : string ) => {
let url
try {
url = new URL ( string )
}
catch ( _ ) {
return false
}
return url . protocol === "http:" || url . protocol === "https:"
}
// @ts-ignore
if ( isValidHttpUrl ( event . target . href ) ) {
2021-04-06 01:28:33 +12:00
// @ts-ignore
2021-04-29 05:33:51 +12:00
shell . openExternal ( event . target . href ) . catch ( e => console . log ( e ) )
}
2021-04-06 01:28:33 +12:00
}
}
/ * *
* React to middle mouse button clicks
* /
reactToMiddleClick ( e : { button : number , preventDefault : ( ) => void } ) {
if ( e . button === 1 ) {
e . preventDefault ( )
return false
}
}
/ * *
* Load settings for the first time upon app load
* /
2021-03-18 10:26:08 +13:00
async loadSettings ( ) {
const SettingsDB = new PouchDB ( "fa-settings" )
const settingsData = await SettingsDB . allDocs ( { include _docs : true } )
const settings = settingsData ? . rows [ 0 ] ? . doc as unknown as OptionsStateInteface
if ( settings ) {
this . SSET _options ( settings )
}
this . registerDefaultKeybinds ( )
this . registerCustomKeybinds ( )
2021-04-06 01:28:33 +12:00
await SettingsDB . close ( )
2021-03-18 10:26:08 +13:00
}
2021-04-06 01:28:33 +12:00
/ * *
* Update dark / light mode across the app based on what is currently in the store
* /
2021-03-18 10:26:08 +13:00
@ Watch ( "SGET_options" , { deep : true } )
onSettingsChange ( ) {
const options = this . SGET _options
2021-04-11 13:40:03 +12:00
this . hidePlushes = options . hidePlushes
2021-03-18 10:26:08 +13:00
this . $q . dark . set ( options . darkMode )
if ( options . darkMode ) {
colors . setBrand ( "dark" , "#1b333e" )
colors . setBrand ( "primary" , "#ffd673" )
}
else {
colors . setBrand ( "dark" , "#18303a" )
2021-03-21 07:13:46 +13:00
colors . setBrand ( "primary" , "#e8bb50" )
2021-03-18 10:26:08 +13:00
}
2021-06-07 12:57:36 +12:00
this . disableDocumentControlBar = options . disableDocumentControlBar
this . refreshDocumentPreviewWindow ( )
2021-03-18 10:26:08 +13:00
}
2021-04-11 13:40:03 +12:00
2021-06-07 12:57:36 +12:00
disableDocumentControlBar = false
2021-04-11 13:40:03 +12:00
/ * *
* Hides the mascot ... nooo : (
* /
hidePlushes = false
2021-04-13 13:32:59 +12:00
@ Watch ( "SGET_getAdvSearchWindowVisible" )
onAdvSearchWindowOpen ( ) {
this . advSearchWindowVisible = true
}
advSearchWindowVisible = false
2021-04-17 00:46:34 +12:00
2021-06-07 12:57:36 +12:00
@ Watch ( "SGET_getNoteCorkboardWindowVisible" )
2021-05-02 02:31:33 +12:00
onCorkboardWindowOpen ( ) {
this . corkboardWindowVisible = true
}
corkboardWindowVisible = false
corkboardContent = ""
/ * *
* Debounce timer to prevent buggy input sync
* /
corkboardTimer = null as any
processCorkboardInput ( ) {
clearTimeout ( this . corkboardTimer )
this . corkboardTimer = setTimeout ( ( ) => {
saveCorkboard ( this . corkboardContent ) . catch ( e => console . log ( e ) )
} , 1000 )
}
2021-05-04 07:49:11 +12:00
/ * *
* Corkboard checker
* Can go up to 3
* /
2021-05-06 11:59:10 +12:00
corkboardCheck = 0
2021-05-04 07:49:11 +12:00
2021-05-02 02:31:33 +12:00
async loadCorkboardCotent ( ) {
2021-05-04 07:49:11 +12:00
const options = this . SGET _options
2021-05-02 02:31:33 +12:00
this . corkboardContent = await retrieveCorkboard ( )
2021-05-04 07:49:11 +12:00
// Considering there is a bit of a delay between the initial load of the store DB content, we give the program 3 attempts to load the data over 3 seconds. If no is loaded in that time, we assume that the settings are not set at all and display the hint as normal.
if ( ( ! options . _id || ! options . _rev ) && this . corkboardCheck < 3 ) {
setTimeout ( ( ) => {
this . corkboardCheck ++
this . loadCorkboardCotent ( ) . catch ( e => console . log ( e ) )
} , 1000 )
return
}
if ( options . preventFilledNoteBoardPopup ) {
return
}
if ( this . corkboardContent . length ) {
2021-05-02 02:31:33 +12:00
this . corkboardWindowVisible = true
}
}
2021-06-07 12:57:36 +12:00
documentPreviewWindowVisible = false
documentPreviewElementID = ""
@ Watch ( "SGET_getDocumentPreviewWindowID" )
reactToPreviewIDChange ( ) {
this . refreshDocumentPreviewWindow ( )
}
@ Watch ( "SGET_getDocumentPreviewVisible" )
reactToPreviewVisibilityChange ( ) {
if ( this . SGET _getDocumentPreviewVisible !== "" ) {
this . refreshDocumentPreviewWindow ( )
}
}
refreshDocumentPreviewWindow ( input = true ) {
this . documentPreviewElementID = this . SGET _getDocumentPreviewWindowID
const newOpenString = this . SGET _getDocumentPreviewVisible
if ( ! input || newOpenString . length === 0 ) {
this . SSET _setDocumentPreviewWindowVisible ( false )
this . documentPreviewWindowVisible = false
}
else {
this . documentPreviewWindowVisible = true
}
if ( this . documentPreviewWindowVisible ) {
/* eslint-disable */
//@ts-ignore
this . $refs . documentPreviewWindow . setX ( 0 )
//@ts-ignore
this . $refs . documentPreviewWindow . setY ( 95 )
//@ts-ignore
/* eslint-enable */
}
}
2021-04-17 00:46:34 +12:00
/****************************************************************/
// Local keybinds
/****************************************************************/
@ Watch ( "SGET_getCurrentKeyBindData" , { deep : true } )
processKeyPush ( ) {
2021-06-07 12:57:36 +12:00
// Toggle the Advanced search cheatsheet
2021-04-17 00:46:34 +12:00
if ( this . determineKeyBind ( "toggleAdvSearchCheatsheet" ) ) {
this . advSearchWindowVisible = ! this . advSearchWindowVisible
}
2021-05-02 02:31:33 +12:00
// Toggle Note Board - CTRL + ALT + SHIFT + P
if ( this . determineKeyBind ( "toggleNoteCorkboard" ) ) {
this . corkboardWindowVisible = ! this . corkboardWindowVisible
}
2021-04-17 00:46:34 +12:00
}
2021-01-31 02:43:13 +13:00
}
< / script >