aboutsummaryrefslogtreecommitdiffhomepage
path: root/desktop/sources/scripts/lib
diff options
context:
space:
mode:
authorneauoire <[email protected]>2019-11-05 17:06:33 -0500
committerneauoire <[email protected]>2019-11-05 17:06:33 -0500
commitadeb472132cb0851eb430fa17c6105ec1bdbbfe3 (patch)
tree108dba74ec70aad2fa5232d1af485ccbc6b3e406 /desktop/sources/scripts/lib
parentf3abf65191e9e0d6059cd95d4ed7d4e818424fa9 (diff)
downloadOrca-adeb472132cb0851eb430fa17c6105ec1bdbbfe3.tar.gz
Orca-adeb472132cb0851eb430fa17c6105ec1bdbbfe3.zip
Working on web version
Diffstat (limited to 'desktop/sources/scripts/lib')
-rw-r--r--desktop/sources/scripts/lib/acels.js123
-rw-r--r--desktop/sources/scripts/lib/controller.js81
-rw-r--r--desktop/sources/scripts/lib/history.js74
-rw-r--r--desktop/sources/scripts/lib/theme.js58
4 files changed, 224 insertions, 112 deletions
diff --git a/desktop/sources/scripts/lib/acels.js b/desktop/sources/scripts/lib/acels.js
new file mode 100644
index 0000000..962d58e
--- /dev/null
+++ b/desktop/sources/scripts/lib/acels.js
@@ -0,0 +1,123 @@
+'use strict'
+
+function Acels () {
+ this.all = {}
+ this.pipe = null
+
+ this.install = (host = window) => {
+ host.addEventListener('keydown', this.onKeyDown, false)
+ host.addEventListener('keyup', this.onKeyUp, false)
+ }
+
+ this.set = (cat, name, accelerator, downfn, upfn) => {
+ if (this.all[accelerator]) { console.warn('Acels', `Trying to overwrite ${this.all[accelerator].name}, with ${name}.`) }
+ this.all[accelerator] = { cat, name, downfn, upfn, accelerator }
+ }
+
+ this.get = (accelerator) => {
+ return this.all[accelerator]
+ }
+
+ this.sort = () => {
+ const h = {}
+ for (const item of Object.values(this.all)) {
+ if (!h[item.cat]) { h[item.cat] = [] }
+ h[item.cat].push(item)
+ }
+ return h
+ }
+
+ this.convert = (event) => {
+ const accelerator = event.key === ' ' ? 'Space' : event.key.substr(0, 1).toUpperCase() + event.key.substr(1)
+ if ((event.ctrlKey || event.metaKey) && event.shiftKey) {
+ return `CmdOrCtrl+Shift+${accelerator}`
+ }
+ if (event.shiftKey) {
+ return `Shift+${accelerator}`
+ }
+ if (event.altKey) {
+ return `Alt+${accelerator}`
+ }
+ if (event.ctrlKey || event.metaKey) {
+ return `CmdOrCtrl+${accelerator}`
+ }
+ return accelerator
+ }
+
+ this.pipe = (obj) => {
+ this.pipe = obj
+ }
+
+ this.onKeyDown = (e) => {
+ const target = this.get(this.convert(e))
+ if (!target || !target.downfn) { return this.pipe ? this.pipe.onKeyDown(e) : null }
+ target.downfn()
+ e.preventDefault()
+ }
+
+ this.onKeyUp = (e) => {
+ const target = this.get(this.convert(e))
+ if (!target || !target.upfn) { return this.pipe ? this.pipe.onKeyUp(e) : null }
+ target.upfn()
+ e.preventDefault()
+ }
+
+ this.toMarkdown = () => {
+ const cats = this.sort()
+ let text = ''
+ for (const cat in cats) {
+ text += `\n### ${cat}\n\n`
+ for (const item of cats[cat]) {
+ text += `- \`${item.accelerator}\`: ${item.info}\n`
+ }
+ }
+ return text.trim()
+ }
+
+ this.toString = () => {
+ const cats = this.sort()
+ let text = ''
+ for (const cat in cats) {
+ for (const item of cats[cat]) {
+ text += `${cat}: ${item.name} | ${item.accelerator}\n`
+ }
+ }
+ return text.trim()
+ }
+
+ // Electron specifics
+
+ this.inject = (name = 'Untitled') => {
+ const app = require('electron').remote.app
+ const injection = []
+
+ injection.push({
+ label: name,
+ submenu: [
+ { label: 'About', click: () => { require('electron').shell.openExternal('https://github.com/hundredrabbits/' + name) } },
+ { label: 'Download Themes', click: () => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes') } },
+ { label: 'Fullscreen', accelerator: 'CmdOrCtrl+Enter', click: () => { app.toggleFullscreen() } },
+ { label: 'Hide', accelerator: 'CmdOrCtrl+H', click: () => { app.toggleVisible() } },
+ { label: 'Toggle Menubar', accelerator: 'Alt+H', click: () => { app.toggleMenubar() } },
+ { label: 'Inspect', accelerator: 'CmdOrCtrl+.', click: () => { app.inspect() } },
+ { label: 'Quit', accelerator: 'CmdOrCtrl+Q', click: () => { app.exit() } }
+ ]
+ })
+
+ const sorted = this.sort()
+ for (const cat of Object.keys(sorted)) {
+ const submenu = []
+ for (const option of sorted[cat]) {
+ if (option.role) {
+ submenu.push({ role: option.role })
+ } else if (option.type) {
+ submenu.push({ type: option.type })
+ } else {
+ submenu.push({ label: option.name, accelerator: option.accelerator, click: option.downfn })
+ }
+ }
+ injection.push({ label: cat, submenu: submenu })
+ }
+ app.injectMenu(injection)
+ }
+}
diff --git a/desktop/sources/scripts/lib/controller.js b/desktop/sources/scripts/lib/controller.js
deleted file mode 100644
index 6b81027..0000000
--- a/desktop/sources/scripts/lib/controller.js
+++ /dev/null
@@ -1,81 +0,0 @@
-'use strict'
-
-export default function Controller () {
- this.menu = { default: {} }
- this.mode = 'default'
- this.app = require('electron').remote.app
-
- this.start = function () {
- }
-
- this.add = function (mode, cat, label, fn, accelerator) {
- if (!this.menu[mode]) { this.menu[mode] = {} }
- if (!this.menu[mode][cat]) { this.menu[mode][cat] = {} }
- this.menu[mode][cat][label] = {
- fn: function (_menuItem, browserWindow) {
- browserWindow.webContents.focus()
- fn.apply(this, arguments)
- },
- accelerator: accelerator
- }
- }
-
- this.addRole = function (mode, cat, label) {
- if (!this.menu[mode]) { this.menu[mode] = {} }
- if (!this.menu[mode][cat]) { this.menu[mode][cat] = {} }
- this.menu[mode][cat][label] = { role: label }
- }
-
- this.addSpacer = function (mode, cat, label, type = 'separator') {
- if (!this.menu[mode]) { this.menu[mode] = {} }
- if (!this.menu[mode][cat]) { this.menu[mode][cat] = {} }
- this.menu[mode][cat][label] = { type: type }
- }
-
- this.clearCat = function (mode, cat) {
- if (this.menu[mode]) { this.menu[mode][cat] = {} }
- }
-
- this.set = function (mode = 'default') {
- this.mode = mode
- this.commit()
- }
-
- this.format = function () {
- const f = []
- const m = this.menu[this.mode]
- for (const cat in m) {
- const submenu = []
- for (const name in m[cat]) {
- const option = m[cat][name]
- if (option.role) {
- submenu.push({ role: option.role })
- } else if (option.type) {
- submenu.push({ type: option.type })
- } else {
- submenu.push({ label: name, accelerator: option.accelerator, click: option.fn })
- }
- }
- f.push({ label: cat, submenu: submenu })
- }
- return f
- }
-
- this.commit = function () {
- console.log('Controller', 'Changing..')
- this.app.injectMenu(this.format())
- }
-
- this.accelerator = function (key, menu) {
- const acc = { basic: null, ctrl: null }
- for (const cat in menu) {
- const options = menu[cat]
- for (const id in options.submenu) {
- const option = options.submenu[id]; if (option.role) { continue }
- acc.basic = (option.accelerator.toLowerCase() === key.toLowerCase()) ? option.label.toUpperCase().replace('TOGGLE ', '').substr(0, 8).trim() : acc.basic
- acc.ctrl = (option.accelerator.toLowerCase() === ('CmdOrCtrl+' + key).toLowerCase()) ? option.label.toUpperCase().replace('TOGGLE ', '').substr(0, 8).trim() : acc.ctrl
- }
- }
- return acc
- }
-}
diff --git a/desktop/sources/scripts/lib/history.js b/desktop/sources/scripts/lib/history.js
new file mode 100644
index 0000000..1bbf0ae
--- /dev/null
+++ b/desktop/sources/scripts/lib/history.js
@@ -0,0 +1,74 @@
+'use strict'
+
+function History () {
+ this.index = 0
+ this.frames = []
+ this.host = null
+ this.key = null
+
+ this.bind = function (host, key) {
+ console.log('History is recording..')
+ this.host = host
+ this.key = key
+ this.reset()
+ }
+
+ this.reset = function () {
+ this.index = 0
+ this.frames = []
+ }
+
+ this.record = function (data) {
+ if (this.index === this.frames.length) {
+ this.append(data)
+ } else {
+ this.fork(data)
+ }
+ this.trim()
+ this.index = this.frames.length
+ }
+
+ this.undo = function () {
+ if (this.index === 0) { console.warn('History', 'Reached beginning'); return }
+ this.index = clamp(this.index - 1, 0, this.frames.length - 2)
+ this.apply(this.frames[this.index])
+ }
+
+ this.redo = function () {
+ if (this.index + 1 > this.frames.length - 1) { console.warn('History', 'Reached end'); return }
+ this.index = clamp(this.index + 1, 0, this.frames.length - 1)
+ this.apply(this.frames[this.index])
+ }
+
+ this.apply = function (f) {
+ if (!this.host[this.key]) { console.log(`Unknown binding to key ${this.key}`); return }
+ if (!f || f.length !== this.host[this.key].length) { return }
+ this.host[this.key] = this.frames[this.index]
+ }
+
+ this.append = function (data) {
+ if (!data) { return }
+ if (this.frames[this.index - 1] && this.frames[this.index - 1] === data) { return }
+ this.frames.push(data)
+ }
+
+ this.fork = function (data) {
+ this.frames = this.frames.slice(0, this.index + 1)
+ this.append(data)
+ }
+
+ this.trim = function (limit = 30) {
+ if (this.frames.length < limit) { return }
+ this.frames.shift()
+ }
+
+ this.last = function () {
+ return this.frames[this.index - 1]
+ }
+
+ this.length = function () {
+ return this.frames.length
+ }
+
+ function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
+}
diff --git a/desktop/sources/scripts/lib/theme.js b/desktop/sources/scripts/lib/theme.js
index a2777fe..94061ed 100644
--- a/desktop/sources/scripts/lib/theme.js
+++ b/desktop/sources/scripts/lib/theme.js
@@ -1,20 +1,25 @@
'use strict'
-export default function Theme (_default) {
- const fs = require('fs')
- const url = require('url')
+/* global localStorage */
+/* global FileReader */
+/* global DOMParser */
- this.active = _default
+function Theme () {
+ const themer = this
+
+ this.default = { background: '#eee', f_high: '#000', f_med: '#999', f_low: '#ccc', f_inv: '#000', b_high: '#000', b_med: '#888', b_low: '#aaa', b_inv: '#ffb545' }
+ this.active = {}
this.el = document.createElement('style')
this.el.type = 'text/css'
- this.install = function (host = document.body, callback) {
+ this.install = (host = document.body, callback) => {
host.appendChild(this.el)
this.callback = callback
}
- this.start = function () {
+ this.start = () => {
+ this.active = this.default
console.log('Theme', 'Starting..')
if (isJson(localStorage.theme)) {
const storage = JSON.parse(localStorage.theme)
@@ -24,12 +29,12 @@ export default function Theme (_default) {
return
}
}
- this.load(_default)
+ this.load(this.active)
}
- this.load = function (data) {
+ this.load = (data) => {
const theme = parse(data)
- if (!validate(theme)) { console.warn('Theme', 'Not a theme', theme); return }
+ if (!validate(theme)) { return }
console.log('Theme', 'Loaded theme!')
this.el.innerHTML = `:root { --background: ${theme.background}; --f_high: ${theme.f_high}; --f_med: ${theme.f_med}; --f_low: ${theme.f_low}; --f_inv: ${theme.f_inv}; --b_high: ${theme.b_high}; --b_med: ${theme.b_med}; --b_low: ${theme.b_low}; --b_inv: ${theme.b_inv}; }`
localStorage.setItem('theme', JSON.stringify(theme))
@@ -39,18 +44,12 @@ export default function Theme (_default) {
}
}
- this.reset = function () {
- this.load(_default)
- }
-
- this.setImage = function (path) {
- document.body.style.backgroundImage = path && fs.existsSync(path) && document.body.style.backgroundImage !== `url(${url.pathToFileURL(path)})` ? `url(${url.pathToFileURL(path)})` : ''
+ this.reset = () => {
+ this.load(this.default)
}
- this.set = function (key, value) {
- if (!this.active[key]) { console.warn('Theme', 'Unknown key ' + key); return }
- if (!isColor(value)) { console.warn('Theme', 'Not a color ' + value); return }
- this.active[key] = '#' + value
+ this.get = (key) => {
+ return this.active[key]
}
function parse (any) {
@@ -60,7 +59,7 @@ export default function Theme (_default) {
// Drag
- this.drag = function (e) {
+ this.drag = (e) => {
e.stopPropagation()
e.preventDefault()
e.dataTransfer.dropEffect = 'copy'
@@ -71,10 +70,10 @@ export default function Theme (_default) {
e.stopPropagation()
const file = e.dataTransfer.files[0]
if (!file || !file.name) { console.warn('Theme', 'Unnamed file.'); return }
- if (file.name.indexOf('.thm') < 0 && file.name.indexOf('.svg') < 0) { console.warn('Theme', 'Skipped, not a theme'); return }
+ if (file.name.indexOf('.thm') < 0 && file.name.indexOf('.svg') < 0) { return }
const reader = new FileReader()
- reader.onload = (e) => {
- this.load(e.target.result)
+ reader.onload = function (e) {
+ themer.load(e.target.result)
}
reader.readAsText(file)
}
@@ -82,11 +81,12 @@ export default function Theme (_default) {
this.open = () => {
const fs = require('fs')
const { dialog, app } = require('electron').remote
- const paths = dialog.showOpenDialogSync(app.win, { properties: ['openFile'], filters: [{ name: 'Themes', extensions: ['svg'] }] })
+ const paths = dialog.showOpenDialog(app.win, { properties: ['openFile'], filters: [{ name: 'Themes', extensions: ['svg'] }] })
if (!paths) { console.log('Nothing to load'); return }
- const data = fs.readFileSync(paths[0], 'utf8')
- if (!data) { return }
- this.load(data)
+ fs.readFile(paths[0], 'utf8', function (err, data) {
+ if (err) throw err
+ themer.load(data)
+ })
}
window.addEventListener('dragover', this.drag)
@@ -131,10 +131,6 @@ export default function Theme (_default) {
try { JSON.parse(text); return true } catch (error) { return false }
}
- function isColor (str) {
- return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test('#' + str)
- }
-
function isHtml (text) {
try { new DOMParser().parseFromString(text, 'text/xml'); return true } catch (error) { return false }
}