diff --git a/README.md b/README.md index dfbbc38..e0103d9 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,18 @@ _runtime.getFileWalker("../", (fileList) => { ## OSX ### Build +Mac and Linux: `./build-app.sh` ### Run `./run-app.sh` + +Windows(Dev): +`run-app-dev.bat` + +Windows(Prod): +`run-app.bat` + +### Debugging in windows +Insert this line of code into any html page that you want to debug +`` diff --git a/app/app.go b/app/app.go new file mode 100644 index 0000000..830ce7f --- /dev/null +++ b/app/app.go @@ -0,0 +1,33 @@ +package app + +import ( + "encoding/json" + "path/filepath" + + "github.com/promignis/knack/constants" + "github.com/promignis/knack/fs" + "github.com/promignis/knack/utils" +) + +type Manifest struct { + AppName string +} + +var manifest Manifest + +func parseManifest() Manifest { + if manifest == (Manifest{}) { + root := utils.GetRootPath() + manifestData := fs.GetFileData(filepath.Join(root, constants.Manifest)) + json.Unmarshal(manifestData, &manifest) + } + return manifest +} + +func GetAppName() string { + return parseManifest().AppName +} + +func GetUserDataPath() string { + return globalSettingFolder +} diff --git a/app/config_darwin.go b/app/config_darwin.go new file mode 100644 index 0000000..217aeeb --- /dev/null +++ b/app/config_darwin.go @@ -0,0 +1,6 @@ +package app + +import "os" + +var systemSettingFolders = []string{"/Library/Application Support"} +var globalSettingFolder = os.Getenv("HOME") + "/Library/Application Support" diff --git a/app/config_windows.go b/app/config_windows.go new file mode 100644 index 0000000..19a4090 --- /dev/null +++ b/app/config_windows.go @@ -0,0 +1,6 @@ +package app + +import "os" + +var systemSettingFolders = []string{os.Getenv("PROGRAMDATA")} +var globalSettingFolder = os.Getenv("APPDATA") diff --git a/app/config_xdg.go b/app/config_xdg.go new file mode 100644 index 0000000..256c854 --- /dev/null +++ b/app/config_xdg.go @@ -0,0 +1,27 @@ +// +build !windows,!darwin + +package app + +import ( + "os" + "path/filepath" + "strings" +) + +// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html + +var systemSettingFolders []string +var globalSettingFolder string + +func init() { + if os.Getenv("XDG_CONFIG_HOME") != "" { + globalSettingFolder = os.Getenv("XDG_CONFIG_HOME") + } else { + globalSettingFolder = filepath.Join(os.Getenv("HOME"), ".config") + } + if os.Getenv("XDG_CONFIG_DIRS") != "" { + systemSettingFolders = strings.Split(os.Getenv("XDG_CONFIG_DIRS"), ":") + } else { + systemSettingFolders = []string{"/etc/xdg"} + } +} diff --git a/bridge/bridge.go b/bridge/bridge.go index ba68f06..5182d17 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -7,6 +7,7 @@ import ( "github.com/promignis/knack/fs" "github.com/promignis/knack/fuzzy" + "github.com/promignis/knack/persistance" "github.com/promignis/knack/utils" "github.com/zserge/webview" @@ -97,6 +98,15 @@ func HandleRPC(w webview.WebView, data string) { utils.CheckErr(err) args := []string{string(stringified)} HandleCallback(w, ffiData, args) + case "set_to_file": + filename := ffiData["filename"].(string) + stringifiedJson := ffiData["stringifiedJson"].(string) + persistance.Set(filename, stringifiedJson) + case "get_from_file": + filename := ffiData["filename"].(string) + stringifiedJson := persistance.Get(filename) + args := []string{stringifiedJson} + HandleCallback(w, ffiData, args) default: fmt.Printf("No such action %s", fnType) } diff --git a/constants/constants.go b/constants/constants.go index 582d023..30c5050 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -8,4 +8,5 @@ const ( ImageFoler = "images" DefaultIndexFile = "index.html" RuntimeJsFile = "runtime.js" + Manifest = "manifest.json" ) diff --git a/js-runtime/runtime.js b/js-runtime/runtime.js index 22c6566..edcd3c7 100644 --- a/js-runtime/runtime.js +++ b/js-runtime/runtime.js @@ -1,9 +1,41 @@ +// TODO: Add webpack to clean up pollyfilling for windows +// Pollyfilling Object.assign +if (typeof Object.assign != 'function') { + Object.defineProperty(Object, "assign", { + value: function assign(target, varArgs) { + 'use strict'; + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { + for (var nextKey in nextSource) { + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }, + writable: true, + configurable: true + }); +} + if(window){ (function(){ window._runtime = Object.assign(window._runtime || {}, JsRuntime()); - if(window.onRuntimeLoad) { - window.onRuntimeLoad(); + window.onload = function() { + if(window.onRuntimeLoad) { + window.onRuntimeLoad(); + } } })(); @@ -54,7 +86,7 @@ function JsRuntime(){ sendAction({type: 'load_html', fileName: viewName}) }, loadImage: function(imageName, imageId) { - sendAction({type: 'load_img', imageName, imageId}) + sendAction({type: 'load_img', imageName: imageName, imageId: imageId}) }, getFileWalker: function(filePath, cb) { return new FileWalker(filePath, cb) @@ -64,7 +96,13 @@ function JsRuntime(){ return new FileStat(filePath, cb) }, fuzzyMatch: function(dict, word, distance, cb) { - sendAction({type: 'fuzzy_match', dict: JSON.stringify(dict), word, distance, callbackId: _runtime.getCbId(cb)}) + sendAction({type: 'fuzzy_match', dict: JSON.stringify(dict), word: word, distance: distance, callbackId: _runtime.getCbId(cb)}) + }, + setToFile: function(filename, stringifiedJson) { + sendAction({type: 'set_to_file', filename: filename, stringifiedJson: stringifiedJson}) + }, + getFromFile: function(filename, cb) { + sendAction({type: 'get_from_file', filename: filename, callbackId: _runtime.getCbId(cb)}) } } } @@ -74,9 +112,10 @@ function FileWalker(filePath, cb) { this.filePath = filePath this.cbId = _runtime.getCbId(cb) - - this.fileStat = new FileStat(filePath, (fileStat) => { - this.fileStat = fileStat + // TODO: Add webpack instead of using _this so that arrow functions can be used in windows + _this = this + this.fileStat = new FileStat(filePath, function(fileStat, _this){ + _this.fileStat = fileStat }) this.walk() } @@ -92,7 +131,8 @@ function FileStat(filePath, cb) { } FileStat.prototype.getFileStat = function() { - sendAction({type: 'file_stat', filePath: this.filePath, callbackId: this.cbId}, (fileStat) => { - this.fileStat = fileStat + _this = this + sendAction({type: 'file_stat', filePath: this.filePath, callbackId: this.cbId}, function(fileStat){ + _this.fileStat = fileStat }) } diff --git a/js/bundle.js b/js/bundle.js index 5c7bb44..8eda2d8 100644 --- a/js/bundle.js +++ b/js/bundle.js @@ -1,6 +1,9 @@ var input = document.getElementById('alertText') var btn = document.getElementById('btn') var changeViewBtn = document.getElementById('changeView') +var persistToFileBtn = document.getElementById('persistToFile') +var getFromFileBtn = document.getElementById('getFromFile') + var currentText = "" input.addEventListener("change", function(ev) { @@ -15,3 +18,14 @@ changeViewBtn.addEventListener('click', function(e) { _runtime.loadView('index2.html') }, false) +persistToFileBtn.addEventListener('click', function() { + _runtime.setToFile("testfile", JSON.stringify({a:1})) +}) + +getFromFileBtn.addEventListener('click', function() { + _runtime.getFromFile("testfile", function(stringifiedJson) { + alert(stringifiedJson) + console.log(JSON.parse(stringifiedJson)) + }) +}) + diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..844e62f --- /dev/null +++ b/manifest.json @@ -0,0 +1,3 @@ +{ + "appName": "test-app" +} diff --git a/persistance/jsonPersistance.go b/persistance/jsonPersistance.go new file mode 100644 index 0000000..2829828 --- /dev/null +++ b/persistance/jsonPersistance.go @@ -0,0 +1,42 @@ +package persistance + +import ( + "os" + "path/filepath" + "sync" + + "github.com/promignis/knack/app" + "github.com/promignis/knack/fs" +) + +var lock sync.Mutex +var userdataFilePath = filepath.Join(app.GetUserDataPath(), "/", app.GetAppName()) + +func init() { + + // In case the directory does not exist , create it before we start creating files inside it + if _, err := os.Stat(userdataFilePath); os.IsNotExist(err) { + err = os.MkdirAll(userdataFilePath, os.ModePerm) + if err != nil { + panic(err) + } + } +} + +func Set(filename string, stringifiedJson string) { + // Putting this here so that read and write on the same file can not happen. Can be clenaed up in future. + lock.Lock() + defer lock.Unlock() + name := filename + ".json" + path := filepath.Join(userdataFilePath, name) + fs.WriteFileData(path, []byte(stringifiedJson)) +} + +func Get(filename string) string { + lock.Lock() + defer lock.Unlock() + name := filename + ".json" + path := filepath.Join(userdataFilePath, name) + stringifiedJson := fs.GetFileData(path) + return string(stringifiedJson) +} diff --git a/run-app-dev.bat b/run-app-dev.bat new file mode 100644 index 0000000..c9055ae --- /dev/null +++ b/run-app-dev.bat @@ -0,0 +1,2 @@ +go build -o output-dev.exe +output-dev.exe diff --git a/run-app.bat b/run-app.bat new file mode 100644 index 0000000..637aedb --- /dev/null +++ b/run-app.bat @@ -0,0 +1,2 @@ +go build -ldflags="-H windowsgui" -o output.exe +output.exe diff --git a/views/index.html b/views/index.html index eba3687..1328d07 100644 --- a/views/index.html +++ b/views/index.html @@ -1,12 +1,13 @@ - +