diff --git a/.github/workflows/windows-release.yml b/.github/workflows/windows-release.yml
new file mode 100644
index 0000000..3980832
--- /dev/null
+++ b/.github/workflows/windows-release.yml
@@ -0,0 +1,48 @@
+name: Release Build (Windows)
+
+on:
+ push:
+ branches:
+ - "release/**"
+
+jobs:
+ build-and-merge:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout the release branch
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract version from branch name
+ id: extract
+ shell: bash
+ run: |
+ version="${GITHUB_REF##*/}"
+ echo "version=$version" >> $GITHUB_OUTPUT
+
+ - name: Set up Git
+ shell: bash
+ run: |
+ git config user.name "github-actions"
+ git config user.email "github-actions@github.com"
+
+ - name: Run build script
+ shell: cmd
+ run: .\build-scripts\windows-build.bat
+
+ - name: Commit and push build artifacts
+ shell: bash
+ run: |
+ git add -A
+ git commit -m "Automated release build for version: ${{ steps.extract.outputs.version }}" || echo "No changes to commit"
+ git push origin ${{ github.ref }}
+
+ - name: Fetch and force merge into main
+ shell: bash
+ run: |
+ git fetch origin main
+ git checkout main
+ git merge -X theirs ${{ github.ref }} -m "Merging release version ${{ steps.extract.outputs.version }} into main"
+ git push origin main
diff --git a/.gitignore b/.gitignore
index 345ff6f..2f5a024 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,13 +2,19 @@
config.js
devices/*
-tmp/
+tmp
log.txt
Macrame.exe
-public
+public/*
+
macros/*
+!macros/TEST-*
+
+panels/*
+!panels/test_panel
+
builds
node_modules
ToDo.md
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2f69d0a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# Macrame
+
+*The current release isn't yet public.*
+
+Turn Any Device into a button panel. Open-source, easy, and built to supercharge your workflow or gaming.
+Macrame is released under the GPL V3 licence. More information can be found at: [Macrame License](https://macrame-app.github.io/license.html)
+
+Macrame is small application that can be used to record keyboard macros.
+The macros can be linked to button panels and the panels can be used by devices on the same network.
+
+## Getting Started
+
+Read the [official documentation](https://macrame-app.github.io/) about the Macrame app to get started.
diff --git a/app/helper/env-helper.go b/app/helper/env-helper.go
index 28af4d4..0eb5e1e 100644
--- a/app/helper/env-helper.go
+++ b/app/helper/env-helper.go
@@ -36,7 +36,7 @@ func EnvGet(key string) string {
if !configFileExists() {
CreateConfigFile(configPath)
- CheckFeDevDir()
+ CheckUIDevDir()
}
data, err := os.ReadFile(configPath)
@@ -63,12 +63,12 @@ func configFileExists() bool {
return err == nil
}
-func CheckFeDevDir() {
+func CheckUIDevDir() {
log.Println("Checking FE dev directory...")
- _, err := os.Stat("fe")
+ _, err := os.Stat("ui")
if err != nil {
- log.Println("Error checking FE dev directory:", err)
+ log.Println("Error checking ui dev directory:", err)
return
}
@@ -83,7 +83,7 @@ func copyConfigToFe() {
return
}
- if err := os.WriteFile("fe/config.js", data, 0644); err != nil {
+ if err := os.WriteFile("ui/config.js", data, 0644); err != nil {
log.Println("Error writing config.js:", err)
}
}
diff --git a/build-scripts/windows-build.bat b/build-scripts/windows-build.bat
new file mode 100644
index 0000000..3dfd88f
--- /dev/null
+++ b/build-scripts/windows-build.bat
@@ -0,0 +1,52 @@
+@echo off
+setlocal enabledelayedexpansion
+
+REM Step 1: Build Macrame Go application for Windows
+echo Building Macrame Go Application for Windows...
+
+go build -ldflags "-H=windowsgui" -o Macrame.exe main.go
+
+IF %ERRORLEVEL% NEQ 0 (
+ echo Go build failed!
+ exit /b %ERRORLEVEL%
+) ELSE (
+ echo Go build was successful!
+)
+
+REM Step 2: Build Macrame Vue UI
+echo Moving to ui directory and building Vue UI
+cd ui
+
+echo Running npm install...
+call npm install
+IF %ERRORLEVEL% NEQ 0 (
+ echo npm install failed!
+ exit /b %ERRORLEVEL%
+)
+
+echo Running npm run build...
+call npm run build
+IF %ERRORLEVEL% NEQ 0 (
+ echo npm run build failed!
+ exit /b %ERRORLEVEL%
+)
+
+cd ..
+
+REM Step 3: Cleanup root directory of build files.
+echo Cleaning up root directory...
+
+echo Removing directories: app, ui, and build-scripts
+rmdir /s /q app
+rmdir /s /q ui
+rmdir /s /q build-scripts
+
+for %%F in (*) do (
+ set "file=%%~nxF"
+ if /I not "!file!"=="Macrame.exe" if /I not "!file!"=="favicon.ico" if /I not "!file!"=="README.md" (
+ echo Deleting !file!
+ del /f /q "%%F"
+ )
+)
+
+echo Build and cleanup complete.
diff --git a/build.sh b/build.sh
deleted file mode 100644
index 65eb876..0000000
--- a/build.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-# Set the name of the build directory
-BUILD_DIR="Macrame_$(date +'%m%d%H%M%S')"
-
-# Build the Go application
-go build -ldflags "-H=windowsgui" -o Macrame.exe main.go
-
-# Build the frontend
-cd fe
-npm run build
-
-cd ../builds
-
-# Create the new build directory
-mkdir $BUILD_DIR
-mkdir $BUILD_DIR/macros
-mkdir $BUILD_DIR/panels
-mkdir $BUILD_DIR/panels/test_panel
-mkdir $BUILD_DIR/public
-mkdir $BUILD_DIR/public/assets
-
-# Move the generated files to the new build directory
-cp ../Macrame.exe $BUILD_DIR/Macrame.exe
-cp ../favicon.ico $BUILD_DIR/favicon.ico
-find ../macros -type f ! -name 'ED-*' -exec cp --parents {} "$BUILD_DIR/macros/" \;
-cp -r ../panels/test_panel/* $BUILD_DIR/panels/test_panel/
-mv ../public/* $BUILD_DIR/public/
-
-# cp ../install.bat $BUILD_DIR/install.bat
-
-powershell -Command "Compress-Archive -Path $BUILD_DIR/* -DestinationPath $BUILD_DIR.zip -Force"
-
-# Print the path to the new build directory
-echo "Build directory: ../$BUILD_DIR"
\ No newline at end of file
diff --git a/macros/TEST-Close_Application.json b/macros/TEST-Close_Application.json
new file mode 100644
index 0000000..c481f1b
--- /dev/null
+++ b/macros/TEST-Close_Application.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lalt", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "f4", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lalt", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "f4", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Close_Browser_Window.json b/macros/TEST-Close_Browser_Window.json
new file mode 100644
index 0000000..63cb228
--- /dev/null
+++ b/macros/TEST-Close_Browser_Window.json
@@ -0,0 +1,13 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "w", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "w", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Close_Tab.json b/macros/TEST-Close_Tab.json
new file mode 100644
index 0000000..577aa88
--- /dev/null
+++ b/macros/TEST-Close_Tab.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "w", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "w", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Displays.json b/macros/TEST-Displays.json
new file mode 100644
index 0000000..80ba168
--- /dev/null
+++ b/macros/TEST-Displays.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "p", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "p", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Files.json b/macros/TEST-Files.json
new file mode 100644
index 0000000..be664ab
--- /dev/null
+++ b/macros/TEST-Files.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "e", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "e", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Fullscreen.json b/macros/TEST-Fullscreen.json
new file mode 100644
index 0000000..16aa578
--- /dev/null
+++ b/macros/TEST-Fullscreen.json
@@ -0,0 +1 @@
+[{"code":"f11","direction":"down","type":"key"},{"type":"delay","value":15},{"code":"f11","direction":"up","type":"key"}]
\ No newline at end of file
diff --git a/macros/TEST-Home.json b/macros/TEST-Home.json
new file mode 100644
index 0000000..4782647
--- /dev/null
+++ b/macros/TEST-Home.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lalt", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "home", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "home", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lalt", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-New_Desktop.json b/macros/TEST-New_Desktop.json
new file mode 100644
index 0000000..9ade4e0
--- /dev/null
+++ b/macros/TEST-New_Desktop.json
@@ -0,0 +1,13 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 50 },
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 50 },
+ { "code": "d", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 50 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 50 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 50 },
+ { "code": "d", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-New_Tab.json b/macros/TEST-New_Tab.json
new file mode 100644
index 0000000..f62acf0
--- /dev/null
+++ b/macros/TEST-New_Tab.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "t", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "t", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-New_Window.json b/macros/TEST-New_Window.json
new file mode 100644
index 0000000..8880f54
--- /dev/null
+++ b/macros/TEST-New_Window.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "n", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "n", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Next_Tab.json b/macros/TEST-Next_Tab.json
new file mode 100644
index 0000000..1ee9641
--- /dev/null
+++ b/macros/TEST-Next_Tab.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-PlayPause.json b/macros/TEST-PlayPause.json
new file mode 100644
index 0000000..5471bd1
--- /dev/null
+++ b/macros/TEST-PlayPause.json
@@ -0,0 +1 @@
+[{"code":"audio_play|audio_pause","direction":"down","type":"key"},{"type":"delay","value":15},{"code":"audio_play|audio_pause","direction":"up","type":"key"}]
\ No newline at end of file
diff --git a/macros/TEST-Previous_Tab.json b/macros/TEST-Previous_Tab.json
new file mode 100644
index 0000000..57dfb44
--- /dev/null
+++ b/macros/TEST-Previous_Tab.json
@@ -0,0 +1,13 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-RunDialog.json b/macros/TEST-RunDialog.json
new file mode 100644
index 0000000..4b73502
--- /dev/null
+++ b/macros/TEST-RunDialog.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "r", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "r", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Settings.json b/macros/TEST-Settings.json
new file mode 100644
index 0000000..fdc8f80
--- /dev/null
+++ b/macros/TEST-Settings.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "i", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "i", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Task_manager.json b/macros/TEST-Task_manager.json
new file mode 100644
index 0000000..732e5df
--- /dev/null
+++ b/macros/TEST-Task_manager.json
@@ -0,0 +1,13 @@
+[
+ { "code": "lctrl", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "esc", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "esc", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lshift", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lctrl", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-Task_view.json b/macros/TEST-Task_view.json
new file mode 100644
index 0000000..65901ec
--- /dev/null
+++ b/macros/TEST-Task_view.json
@@ -0,0 +1,9 @@
+[
+ { "code": "lcmd", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "down", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "lcmd", "direction": "up", "type": "key" },
+ { "type": "delay", "value": 15 },
+ { "code": "tab", "direction": "up", "type": "key" }
+]
diff --git a/macros/TEST-desktop.json b/macros/TEST-desktop.json
new file mode 100644
index 0000000..03341e3
--- /dev/null
+++ b/macros/TEST-desktop.json
@@ -0,0 +1 @@
+[{"type":"key","key":"Meta","code":"MetaLeft","location":1,"direction":"down","value":0},{"type":"delay","key":"","code":"","location":0,"direction":"","value":240},{"type":"key","key":"d","code":"KeyD","location":0,"direction":"down","value":0},{"type":"delay","key":"","code":"","location":0,"direction":"","value":10},{"type":"key","key":"d","code":"KeyD","location":0,"direction":"up","value":0},{"type":"delay","key":"","code":"","location":0,"direction":"","value":10},{"type":"key","key":"Meta","code":"MetaLeft","location":1,"direction":"up","value":0}]
\ No newline at end of file
diff --git a/panels/Elite_Dangerous/index.html b/panels/Elite_Dangerous/index.html
deleted file mode 100644
index 2d230d9..0000000
--- a/panels/Elite_Dangerous/index.html
+++ /dev/null
@@ -1,913 +0,0 @@
-
-
-
L?ve(f,b,y,!0,!1,P):Se(u,p,_,b,y,S,w,E,P)},Ge=(f,u,p,_,b,y,S,w,E)=>{let x=0;const L=u.length;let P=f.length-1,F=L-1;for(;x<=P&&x<=F;){const $=f[x],U=u[x]=E?Ye(u[x]):Fe(u[x]);if(Ct($,U))A($,U,p,null,b,y,S,w,E);else break;x++}for(;x<=P&&x<=F;){const $=f[P],U=u[F]=E?Ye(u[F]):Fe(u[F]);if(Ct($,U))A($,U,p,null,b,y,S,w,E);else break;P--,F--}if(x>P){if(x<=F){const $=F+1,U=$