Added Wails3/HTMX example GUI

This commit is contained in:
2024-11-05 05:17:27 -07:00
parent d99293dba1
commit 90a87af526
31 changed files with 1481 additions and 47 deletions

53
desktop/.gitignore vendored Normal file
View File

@ -0,0 +1,53 @@
# Fichiers et répertoires spécifiques à Go
/bin
/pkg
/vendor
# Log files
*.log
# OS-specific files
.DS_Store
Thumbs.db
# IDEs et éditeurs
.idea/
.vscode/
*.swp
*.swo
# Coverage reports
coverage.out
# Node.js / NPM
node_modules/
npm-debug.log
yarn-error.log
.pnp
.pnp.js
# Svelte
public/build/
__sapper__/
.svelte-kit/
# TypeScript
*.tsbuildinfo
# Misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.task
.env.production.local
# Frontend specific
frontend/dist
*.bak
*_templ.go
*.out.css
test

8
desktop/LICENSE Normal file
View File

@ -0,0 +1,8 @@
The MIT License (MIT)
Copyright © 2024 VAN DE MERGHEL Robin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

56
desktop/README.md Normal file
View File

@ -0,0 +1,56 @@
# WailsV3 Project with HTMX and Templ
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
Welcome to the WailsV3 project template integrating HTMX and Templ, inspired by [this project](https://gitlab.isima.fr/rovandemer/astroproject). This template provides a starting point for building modern web applications with Go, leveraging the power of Wails, HTMX, and Templ.
## 🚀 Features
- **WailsV3**: A framework for building desktop applications using Go and web technologies.
- **HTMX**: A library that allows you to access AJAX, CSS Transitions, WebSockets, and Server-Sent Events directly in HTML.
- **Templ**: A Go template engine designed for simplicity and ease of use.
## 📋 Requirements
Before you begin, ensure you have the following installed:
- **WailsV3**: [Installation Guide](https://v3alpha.wails.io/getting-started/installation/)
- **Go**: [Download Go](https://go.dev/dl/)
## 📄 Documentation
- **Templ Documentation**: [templ.guide](https://templ.guide)
- **WailsV3 Documentation**: [v3alpha.wails.io](https://v3alpha.wails.io)
## ⚙️ Installation
1. **Clone the Repository**
```bash
git clone https://github.com/OnHenriGolera/Wails3-HTMX-Templ-Template
cd Wails3-HTMX-Templ-Template
```
2. **Install Dependencies and Build the Application**
```bash
wails3 build
```
3. **Run the Application**
```bash
wails3 dev
```
## 📝 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 💡 Inspirations
- Inspired by the [Astroproject](https://gitlab.isima.fr/rovandemer/astroproject).
- Thanks to the developers of Wails, HTMX, and Templ for their amazing tools.
---
Feel free to enhance this template to suit your project's specific needs. Happy coding! 🎉
---

389
desktop/Taskfile.yml Normal file
View File

@ -0,0 +1,389 @@
version: "3"
vars:
APP_NAME: "Peachy"
BIN_DIR: "bin"
tasks:
## -------------------------- Build -------------------------- ##
build:
summary: Builds the application
cmds:
# Build for current OS
- task: build:{{OS}}
# Uncomment to build for specific OSes
# - task: build:linux
# - task: build:windows
# - task: build:darwin
## ------> Windows <-------
build:windows:
summary: Builds the application for Windows
deps:
- task: go:mod:tidy
vars:
BUILD_FLAGS: "{{.BUILD_FLAGS}}"
- task: generate:icons
- task: generate:syso
vars:
ARCH: "{{.ARCH}}"
cmds:
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/Peachy.exe
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l"{{end}}'
env:
GOOS: windows
CGO_ENABLED: 0
GOARCH: "{{.ARCH | default ARCH}}"
PRODUCTION: '{{.PRODUCTION | default "false"}}'
build:windows:prod:arm64:
summary: Creates a production build of the application
cmds:
- task: build:windows
vars:
ARCH: arm64
PRODUCTION: "true"
build:windows:prod:amd64:
summary: Creates a production build of the application
cmds:
- task: build:windows
vars:
ARCH: amd64
PRODUCTION: "true"
build:windows:debug:arm64:
summary: Creates a debug build of the application
cmds:
- task: build:windows
vars:
ARCH: arm64
build:windows:debug:amd64:
summary: Creates a debug build of the application
cmds:
- task: build:windows
vars:
ARCH: amd64
## ------> Darwin <-------
build:darwin:
summary: Creates a production build of the application
deps:
- task: go:mod:tidy
vars:
BUILD_FLAGS: "{{.BUILD_FLAGS}}"
- task: generate:icons
cmds:
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
env:
GOOS: darwin
CGO_ENABLED: 1
GOARCH: "{{.ARCH | default ARCH}}"
CGO_CFLAGS: "-mmacosx-version-min=10.15"
CGO_LDFLAGS: "-mmacosx-version-min=10.15"
MACOSX_DEPLOYMENT_TARGET: "10.15"
PRODUCTION: '{{.PRODUCTION | default "false"}}'
build:darwin:prod:arm64:
summary: Creates a production build of the application
cmds:
- task: build:darwin
vars:
ARCH: arm64
PRODUCTION: "true"
build:darwin:prod:amd64:
summary: Creates a production build of the application
cmds:
- task: build:darwin
vars:
ARCH: amd64
PRODUCTION: "true"
build:darwin:debug:arm64:
summary: Creates a debug build of the application
cmds:
- task: build:darwin
vars:
ARCH: arm64
build:darwin:debug:amd64:
summary: Creates a debug build of the application
cmds:
- task: build:darwin
vars:
ARCH: amd64
## ------> Linux <-------
build:linux:
summary: Builds the application for Linux
deps:
- task: go:mod:tidy
vars:
BUILD_FLAGS: "{{.BUILD_FLAGS}}"
- task: generate:icons
vars:
ARCH: "{{.ARCH}}"
cmds:
- go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/Peachy
vars:
BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}'
env:
GOOS: linux
CGO_ENABLED: 1
GOARCH: "{{.ARCH | default ARCH}}"
PRODUCTION: '{{.PRODUCTION | default "false"}}'
build:linux:prod:arm64:
summary: Creates a production build of the application
cmds:
- task: build:linux
vars:
ARCH: arm64
PRODUCTION: "true"
build:linux:prod:amd64:
summary: Creates a production build of the application
cmds:
- task: build:linux
vars:
ARCH: amd64
PRODUCTION: "true"
build:linux:debug:arm64:
summary: Creates a debug build of the application
cmds:
- task: build:linux
vars:
ARCH: arm64
build:linux:debug:amd64:
summary: Creates a debug build of the application
cmds:
- task: build:linux
vars:
ARCH: amd64
## -------------------------- Package -------------------------- ##
package:
summary: Packages a production build of the application into a bundle
cmds:
# Package for current OS
- task: package:{{OS}}
# Package for specific os/arch
# - task: package:darwin:arm64
# - task: package:darwin:amd64
# - task: package:windows:arm64
# - task: package:windows:amd64
## ------> Windows <------
package:windows:
summary: Packages a production build of the application into a `.exe` bundle
cmds:
- task: create:nsis:installer
vars:
ARCH: "{{.ARCH}}"
vars:
ARCH: "{{.ARCH | default ARCH}}"
package:windows:arm64:
summary: Packages a production build of the application into a `.exe` bundle
cmds:
- task: package:windows
vars:
ARCH: arm64
package:windows:amd64:
summary: Packages a production build of the application into a `.exe` bundle
cmds:
- task: package:windows
vars:
ARCH: amd64
generate:syso:
summary: Generates Windows `.syso` file
dir: build
cmds:
- wails3 generate syso -arch {{.ARCH}} -icon icon.ico -manifest wails.exe.manifest -info info.json -out ../wails.syso
vars:
ARCH: "{{.ARCH | default ARCH}}"
create:nsis:installer:
summary: Creates an NSIS installer
label: "NSIS Installer ({{.ARCH}})"
dir: build/nsis
sources:
- "{{.ROOT_DIR}}\\bin\\{{.APP_NAME}}.exe"
generates:
- "{{.ROOT_DIR}}\\bin\\{{.APP_NAME}}-{{.ARCH}}-installer.exe"
deps:
- task: build:windows
vars:
PRODUCTION: "true"
ARCH: "{{.ARCH}}"
cmds:
- makensis -DARG_WAILS_'{{.ARG_FLAG}}'_BINARY="{{.ROOT_DIR}}\{{.BIN_DIR}}\{{.APP_NAME}}.exe" project.nsi
vars:
ARCH: "{{.ARCH | default ARCH}}"
ARG_FLAG: '{{if eq .ARCH "amd64"}}AMD64{{else}}ARM64{{end}}'
## ------> Darwin <------
package:darwin:
summary: Packages a production build of the application into a `.app` bundle
platforms: [darwin]
deps:
- task: build:darwin
vars:
PRODUCTION: "true"
cmds:
- task: create:app:bundle
package:darwin:arm64:
summary: Packages a production build of the application into a `.app` bundle
platforms: [darwin/arm64]
deps:
- task: package:darwin
vars:
ARCH: arm64
package:darwin:amd64:
summary: Packages a production build of the application into a `.app` bundle
platforms: [darwin/amd64]
deps:
- task: package:darwin
vars:
ARCH: amd64
create:app:bundle:
summary: Creates an `.app` bundle
cmds:
- mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources}
- cp build/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources
- cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS
- cp build/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents
## ------> Linux <------
package:linux:
summary: Packages a production build of the application for Linux
platforms: [linux]
deps:
- task: build:linux
vars:
PRODUCTION: "true"
cmds:
- task: create:appimage
create:appimage:
summary: Creates an AppImage
dir: build/appimage
platforms: [linux]
deps:
- task: build:linux
vars:
PRODUCTION: "true"
- task: generate:linux:dotdesktop
cmds:
# Copy binary + icon to appimage dir
- cp {{.APP_BINARY}} {{.APP_NAME}}
- cp ../appicon.png appicon.png
# Generate AppImage
- wails3 generate appimage -binary {{.APP_NAME}} -icon {{.ICON}} -desktopfile {{.DESKTOP_FILE}} -outputdir {{.OUTPUT_DIR}} -builddir {{.ROOT_DIR}}/build/appimage
vars:
APP_NAME: "{{.APP_NAME}}"
APP_BINARY: "../../bin/{{.APP_NAME}}"
ICON: "../appicon.png"
DESKTOP_FILE: "{{.APP_NAME}}.desktop"
OUTPUT_DIR: "../../bin"
generate:linux:dotdesktop:
summary: Generates a `.desktop` file
dir: build
sources:
- "appicon.png"
generates:
- "{{.ROOT_DIR}}/build/appimage/{{.APP_NAME}}.desktop"
cmds:
- mkdir -p {{.ROOT_DIR}}/build/appimage
# Run `wails3 generate .desktop -help` for all the options
- wails3 generate .desktop -name "{{.APP_NAME}}" -exec "{{.EXEC}}" -icon "{{.ICON}}" -outputfile {{.ROOT_DIR}}/build/appimage/{{.APP_NAME}}.desktop -categories "{{.CATEGORIES}}"
# -comment "A comment"
# -terminal "true"
# -version "1.0"
# -genericname "Generic Name"
# -keywords "keyword1;keyword2;"
# -startupnotify "true"
# -mimetype "application/x-extension1;application/x-extension2;"
vars:
APP_NAME: "{{.APP_NAME}}"
EXEC: "{{.APP_NAME}}"
ICON: "appicon"
CATEGORIES: "Development;"
OUTPUTFILE: "{{.ROOT_DIR}}/build/appimage/{{.APP_NAME}}.desktop"
## -------------------------- Misc -------------------------- ##
generate:icons:
summary: Generates Windows `.ico` and Mac `.icns` files from an image
dir: build
sources:
- "appicon.png"
generates:
- "icons.icns"
- "icons.ico"
cmds:
# Generates both .ico and .icns files
- wails3 generate icons -input appicon.png
go:mod:tidy:
summary: Runs `go mod tidy`
internal: true
generates:
- go.sum
sources:
- go.mod
cmds:
- go mod tidy
# ----------------------- dev ----------------------- #
run:
summary: Runs the application
cmds:
- task: run:{{OS}}
run:windows:
cmds:
- '{{.BIN_DIR}}\\{{.APP_NAME}}.exe'
run:linux:
cmds:
- "{{.BIN_DIR}}/{{.APP_NAME}}"
run:darwin:
cmds:
- "{{.BIN_DIR}}/{{.APP_NAME}}"
dev:
summary: Runs the application in development mode
cmds:
- wails3 dev -config ./build/devmode.config.yaml -port 9245
dev:reload:
summary: Reloads the application
cmds:
- task: run

View File

@ -0,0 +1,3 @@
package app
// TODO: Add your code here

View File

@ -0,0 +1,32 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>My Product</string>
<key>CFBundleExecutable</key>
<string>YourName</string>
<key>CFBundleIdentifier</key>
<string>com.wails.yourname</string>
<key>CFBundleVersion</key>
<string>0.1.0</string>
<key>CFBundleGetInfoString</key>
<string>This is a comment</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
<string>10.13.0</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>© now, My Company</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
</dict>
</plist>

27
desktop/build/Info.plist Normal file
View File

@ -0,0 +1,27 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleName</key>
<string>My Product</string>
<key>CFBundleExecutable</key>
<string>YourName</string>
<key>CFBundleIdentifier</key>
<string>com.wails.yourname</string>
<key>CFBundleVersion</key>
<string>0.1.0</string>
<key>CFBundleGetInfoString</key>
<string>This is a comment</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<key>CFBundleIconFile</key>
<string>icons</string>
<key>LSMinimumSystemVersion</key>
<string>10.13.0</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>NSHumanReadableCopyright</key>
<string>© now, My Company</string>
</dict>
</plist>

BIN
desktop/build/appicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Copyright (c) 2018-Present Lea Anthony
# SPDX-License-Identifier: MIT
# Fail script on any error
set -euxo pipefail
# Define variables
APP_DIR="${APP_NAME}.AppDir"
# Create AppDir structure
mkdir -p "${APP_DIR}/usr/bin"
cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/"
cp "${ICON_PATH}" "${APP_DIR}/"
cp "${DESKTOP_FILE}" "${APP_DIR}/"
# Download linuxdeploy and make it executable
wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
# Run linuxdeploy to bundle the application
./linuxdeploy-x86_64.AppImage --appdir "${APP_DIR}" --output appimage
# Rename the generated AppImage
mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage"

View File

@ -0,0 +1,24 @@
config:
root_path: .
log_level: warn
debounce: 1000
ignore:
dir:
- .git
- node_modules
- frontend
- bin
file:
- .DS_Store
- .gitignore
- .gitkeep
watched_extension:
- "*.go"
git_ignore: true
executes:
- cmd: go mod tidy
type: blocking
- cmd: wails3 task build
type: blocking
- cmd: wails3 task run
type: primary

BIN
desktop/build/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
desktop/build/icons.icns Normal file

Binary file not shown.

15
desktop/build/info.json Normal file
View File

@ -0,0 +1,15 @@
{
"fixed": {
"file_version": "0.1.0"
},
"info": {
"0000": {
"ProductVersion": "0.1.0",
"CompanyName": "Your Company",
"FileDescription": "Your application description",
"LegalCopyright": "Your Company",
"ProductName": "Your Product Name",
"Comments": "Your comments"
}
}
}

View File

@ -0,0 +1,108 @@
Unicode true
####
## Please note: Template replacements don't work in this file. They are provided with default defines like
## mentioned underneath.
## If the keyword is not defined, "wails_tools.nsh" will populate them.
## If they are defined here, "wails_tools.nsh" will not touch them. This allows you to use this project.nsi manually
## from outside of Wails for debugging and development of the installer.
##
## For development first make a wails nsis build to populate the "wails_tools.nsh":
## > wails build --target windows/amd64 --nsis
## Then you can call makensis on this file with specifying the path to your binary:
## For a AMD64 only installer:
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe
## For a ARM64 only installer:
## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe
## For a installer with both architectures:
## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe
####
## The following information is taken from the wails_tools.nsh file, but they can be overwritten here.
####
## !define INFO_PROJECTNAME "my-project" # Default "YourProject"
## !define INFO_COMPANYNAME "My Company" # Default "My Company"
## !define INFO_PRODUCTNAME "My Product Name" # Default "My Product"
## !define INFO_PRODUCTVERSION "1.0.0" # Default "0.1.0"
## !define INFO_COPYRIGHT "(c) Now, My Company" # Default "© now, My Company"
###
## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe"
## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
####
## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html
####
## Include the wails tools
####
!include "wails_tools.nsh"
# The version information for this two must consist of 4 parts
VIProductVersion "${INFO_PRODUCTVERSION}.0"
VIFileVersion "${INFO_PRODUCTVERSION}.0"
VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}"
VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer"
VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}"
VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}"
VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}"
VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}"
# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware
ManifestDPIAware true
!include "MUI.nsh"
!define MUI_ICON "..\icon.ico"
!define MUI_UNICON "..\icon.ico"
# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314
!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps
!define MUI_ABORTWARNING # This will warn the user if they exit from the installer.
!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page.
# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer
!insertmacro MUI_PAGE_DIRECTORY # In which folder install page.
!insertmacro MUI_PAGE_INSTFILES # Installing page.
!insertmacro MUI_PAGE_FINISH # Finished installation page.
!insertmacro MUI_UNPAGE_INSTFILES # Uninstalling page
!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer
## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1
#!uninstfinalize 'signtool --file "%1"'
#!finalize 'signtool --file "%1"'
Name "${INFO_PRODUCTNAME}"
OutFile "..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file.
InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder).
ShowInstDetails show # This will always show the installation details.
Function .onInit
!insertmacro wails.checkArchitecture
FunctionEnd
Section
!insertmacro wails.setShellContext
!insertmacro wails.webview2runtime
SetOutPath $INSTDIR
!insertmacro wails.files
CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
!insertmacro wails.writeUninstaller
SectionEnd
Section "uninstall"
!insertmacro wails.setShellContext
RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath
RMDir /r $INSTDIR
Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk"
Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk"
!insertmacro wails.deleteUninstaller
SectionEnd

View File

@ -0,0 +1,179 @@
# DO NOT EDIT - Generated automatically by `wails build`
!include "x64.nsh"
!include "WinVer.nsh"
!include "FileFunc.nsh"
!ifndef INFO_PROJECTNAME
!define INFO_PROJECTNAME "Peachy"
!endif
!ifndef INFO_COMPANYNAME
!define INFO_COMPANYNAME "My Company"
!endif
!ifndef INFO_PRODUCTNAME
!define INFO_PRODUCTNAME "Peachy"
!endif
!ifndef INFO_PRODUCTVERSION
!define INFO_PRODUCTVERSION "0.1.0"
!endif
!ifndef INFO_COPYRIGHT
!define INFO_COPYRIGHT "© now, My Company"
!endif
!ifndef PRODUCT_EXECUTABLE
!define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe"
!endif
!ifndef UNINST_KEY_NAME
!define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}"
!endif
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}"
!ifndef REQUEST_EXECUTION_LEVEL
!define REQUEST_EXECUTION_LEVEL "admin"
!endif
RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
!ifdef ARG_WAILS_AMD64_BINARY
!define SUPPORTS_AMD64
!endif
!ifdef ARG_WAILS_ARM64_BINARY
!define SUPPORTS_ARM64
!endif
!ifdef SUPPORTS_AMD64
!ifdef SUPPORTS_ARM64
!define ARCH "amd64_arm64"
!else
!define ARCH "amd64"
!endif
!else
!ifdef SUPPORTS_ARM64
!define ARCH "arm64"
!else
!error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY"
!endif
!endif
!macro wails.checkArchitecture
!ifndef WAILS_WIN10_REQUIRED
!define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later."
!endif
!ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED
!define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}"
!endif
${If} ${AtLeastWin10}
!ifdef SUPPORTS_AMD64
${if} ${IsNativeAMD64}
Goto ok
${EndIf}
!endif
!ifdef SUPPORTS_ARM64
${if} ${IsNativeARM64}
Goto ok
${EndIf}
!endif
IfSilent silentArch notSilentArch
silentArch:
SetErrorLevel 65
Abort
notSilentArch:
MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}"
Quit
${else}
IfSilent silentWin notSilentWin
silentWin:
SetErrorLevel 64
Abort
notSilentWin:
MessageBox MB_OK "${WAILS_WIN10_REQUIRED}"
Quit
${EndIf}
ok:
!macroend
!macro wails.files
!ifdef SUPPORTS_AMD64
${if} ${IsNativeAMD64}
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}"
${EndIf}
!endif
!ifdef SUPPORTS_ARM64
${if} ${IsNativeARM64}
File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}"
${EndIf}
!endif
!macroend
!macro wails.writeUninstaller
WriteUninstaller "$INSTDIR\uninstall.exe"
SetRegView 64
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}"
WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}"
WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S"
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0"
!macroend
!macro wails.deleteUninstaller
Delete "$INSTDIR\uninstall.exe"
SetRegView 64
DeleteRegKey HKLM "${UNINST_KEY}"
!macroend
!macro wails.setShellContext
${If} ${REQUEST_EXECUTION_LEVEL} == "admin"
SetShellVarContext all
${else}
SetShellVarContext current
${EndIf}
!macroend
# Install webview2 by launching the bootstrapper
# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment
!macro wails.webview2runtime
!ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT
!define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime"
!endif
SetRegView 64
# If the admin key exists and is not empty then webview2 is already installed
ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
${If} $0 != ""
Goto ok
${EndIf}
${If} ${REQUEST_EXECUTION_LEVEL} == "user"
# If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed
ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv"
${If} $0 != ""
Goto ok
${EndIf}
${EndIf}
SetDetailsPrint both
DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}"
SetDetailsPrint listonly
InitPluginsDir
CreateDirectory "$pluginsdir\webview2bootstrapper"
SetOutPath "$pluginsdir\webview2bootstrapper"
File "MicrosoftEdgeWebview2Setup.exe"
ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install'
SetDetailsPrint both
ok:
!macroend

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity type="win32" name="com.wails.yourname" version="0.1.0" processorArchitecture="*"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
</dependentAssembly>
</dependency>
<asmv3:application>
<asmv3:windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware> <!-- fallback for Windows 7 and 8 -->
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness> <!-- falls back to per-monitor if per-monitor v2 is not supported -->
</asmv3:windowsSettings>
</asmv3:application>
</assembly>

View File

@ -0,0 +1,14 @@
package components
import (
h "git.codemonkeysoftware.net/b/hatmill"
a "git.codemonkeysoftware.net/b/hatmill/attribute"
e "git.codemonkeysoftware.net/b/hatmill/element"
)
func HelloWorld() h.Term {
return h.Terms{
e.H2()(h.Text("In French, we say \"Baguette\"")),
e.Img(a.Src("/static/img/baguette.svg"), a.Alt("A baguette"), a.Style("max-width: 100px")),
}
}

52
desktop/main.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"embed"
"log"
"net/http"
"git.codemonkeysoftware.net/b/peachy-go/desktop/routes"
"github.com/wailsapp/wails/v3/pkg/application"
)
//go:embed all:static
var assets embed.FS
func main() {
r := routes.NewChiRouter()
// Create the application
app := application.New(application.Options{
Name: "Peachy",
Description: "A demo of using raw HTML & CSS", // Description of the application
Assets: application.AssetOptions{ // Assets to embed (our static files)
Handler: application.AssetFileServerFS(assets),
Middleware: func(next http.Handler) http.Handler {
r.NotFound(next.ServeHTTP)
return r
},
},
Mac: application.MacOptions{
ApplicationShouldTerminateAfterLastWindowClosed: true,
},
})
// V3 introduces multiple windows, so we need to create a window
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
Title: "Your Project",
Mac: application.MacWindow{
Backdrop: application.MacBackdropTranslucent,
},
URL: "/", // URL to load when the window is created
Width: 1080, // Width of the window
Height: 720, // Height of the window
Centered: false,
})
err := app.Run()
if err != nil {
log.Fatal(err)
}
}

40
desktop/pages/HomePage.go Normal file
View File

@ -0,0 +1,40 @@
package pages
import (
h "git.codemonkeysoftware.net/b/hatmill"
a "git.codemonkeysoftware.net/b/hatmill/attribute"
e "git.codemonkeysoftware.net/b/hatmill/element"
)
func hxGet(url string) h.Attrib {
return h.Attrib{
Key: "hx-get",
Value: a.String(url),
}
}
func hxTrigger(event string) h.Attrib {
return h.Attrib{
Key: "hx-trigger",
Value: a.String(event),
}
}
func hxTarget(target string) h.Attrib {
return h.Attrib{
Key: "hx-target",
Value: a.String(target),
}
}
func HomePage() h.ParentElement {
return e.Div()(
e.Button(
a.Type("button"),
hxGet("/hello"),
hxTrigger("click"),
hxTarget("#hello"),
)(h.Text("Click Here!")),
e.Div(a.Id("hello"))(),
)
}

26
desktop/pages/Page.go Normal file
View File

@ -0,0 +1,26 @@
package pages
import (
h "git.codemonkeysoftware.net/b/hatmill"
a "git.codemonkeysoftware.net/b/hatmill/attribute"
e "git.codemonkeysoftware.net/b/hatmill/element"
)
func Head() h.ParentElement {
return e.Head()(
e.Meta(a.Charset("utf-8")),
e.Meta(a.Name("viewport"), a.Content("width=device-width, initial-scale=1")),
e.Title()(h.Text("Peachy")),
e.Link(a.Rel("stylesheet"), a.Href("/static/css/main.css")),
e.Script(a.Src("/static/js/htmx-2.0.3.min.js"))(), // TODO change to pack it with the app
)
}
func Page[T h.Term](contents func() T) h.ParentElement {
return e.Html()(
Head(),
e.Body()(
contents(),
),
)
}

68
desktop/routes/app.go Normal file
View File

@ -0,0 +1,68 @@
package routes
import (
"log/slog"
"net/http"
"git.codemonkeysoftware.net/b/peachy-go/desktop/components"
"git.codemonkeysoftware.net/b/peachy-go/desktop/pages"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httplog/v2"
)
/*
Create a new chi router, configure it and return it.
*/
func NewChiRouter() *chi.Mux {
r := chi.NewRouter()
// Useful middleware, see : https://pkg.go.dev/github.com/go-chi/httplog/v2@v2.1.1#NewLogger
logger := httplog.NewLogger("app-logger", httplog.Options{
// All log
LogLevel: slog.LevelInfo,
Concise: true,
})
// Use the logger and recoverer middleware.
r.Use(httplog.RequestLogger(logger))
r.Use(middleware.Recoverer)
/*
// ULTRA IMPORTANT : This middleware is used to prevent caching of the pages.
// Sometimes, HX requests may be cached by the browser, which may cause unexpected behavior.
r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store")
next.ServeHTTP(w, r)
})
})
*/
// Serve static files.
r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
// Home page
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
// Render home page
HXRender(w, r, pages.HomePage)
// 200 OK status
w.WriteHeader(http.StatusOK)
})
// Hello page
r.Get("/hello", func(w http.ResponseWriter, r *http.Request) {
// Render hello
HXRender(w, r, components.HelloWorld)
// 200 OK status
w.WriteHeader(http.StatusOK)
})
// Listen to port 3000.
go http.ListenAndServe(":9245", r)
return r
}

27
desktop/routes/util.go Normal file
View File

@ -0,0 +1,27 @@
package routes
import (
"net/http"
"git.codemonkeysoftware.net/b/hatmill"
"git.codemonkeysoftware.net/b/peachy-go/desktop/pages"
"github.com/mavolin/go-htmx"
)
/*
Render the component, and if it's an HX request, only render the component.
*/
func HXRender[T hatmill.Term](w http.ResponseWriter, r *http.Request, component func() T) {
hxRequest := htmx.Request(r)
w.Header().Set("Content-Type", "text/html")
// If it's an HX request, we only render the component.
// If it's not, we render the whole page.
if hxRequest == nil {
hatmill.WriteDocument(w, pages.Page(component))
pages.Page(component)
} else {
component().WriteTo(w)
}
}

View File

@ -0,0 +1,57 @@
:root {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
"Helvetica Neue", sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: black;
background-color: #e5e5f7a5;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
* {
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
text-align: center;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
button {
padding: 10px;
border: none;
border-radius: 5px;
background-color: #003566;
color: white;
text-align: center;
}

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--twemoji" preserveAspectRatio="xMidYMid meet"><path fill="#EDB980" d="M12.697 31.165c-3.785 3.785-8.273 3.838-9.841 2.271c-1.568-1.568-1.514-6.056 2.271-9.841L24.052 4.67c3.785-3.784 8.271-3.838 9.84-2.271c1.567 1.568 1.515 6.056-2.271 9.841L12.697 31.165z"></path><path d="M24.322 7.969c1.568 1.568 2.758 2.917 3.595 2.082c.152-.152.241-.349.301-.565a.477.477 0 0 1-.041-.136c-.128-1.148-2.41-3.641-4.08-4.721l-.045.042l-1.474 1.474c.438.539 1.064 1.144 1.744 1.824zm-4.543 4.542c1.568 1.568 2.76 2.917 3.597 2.082c.152-.152.241-.35.301-.567c-.018-.043-.036-.086-.041-.135c-.127-1.148-2.411-3.643-4.083-4.722l-1.517 1.517c.437.54 1.063 1.145 1.743 1.825zm-4.54 4.542c1.567 1.568 2.759 2.918 3.595 2.081c.152-.152.241-.349.301-.565a.513.513 0 0 1-.042-.136c-.128-1.148-2.412-3.642-4.083-4.721l-1.517 1.517c.439.539 1.065 1.144 1.746 1.824zm-4.542 4.542c1.567 1.567 2.759 2.919 3.596 2.082c.152-.152.241-.35.301-.566a.513.513 0 0 1-.042-.136c-.127-1.148-2.411-3.643-4.082-4.722L8.953 19.77c.437.54 1.063 1.145 1.744 1.825zm-4.542 4.541c1.567 1.568 2.759 2.919 3.596 2.082c.152-.152.241-.35.301-.566c-.018-.043-.036-.086-.042-.135c-.128-1.148-2.412-3.643-4.083-4.722l-.801.801c-.246.246-.475.496-.691.747c.437.532 1.053 1.126 1.72 1.793z" fill="#E5A157"></path><path d="M24.859 3.932c-.126.106-.634.569-.762.696c1.67 1.08 3.952 3.574 4.08 4.721a.449.449 0 0 0 .042.136a.497.497 0 0 0 .455.309l.057-.003a.5.5 0 0 0 .441-.553c-.164-1.452-2.382-4-4.313-5.306zm-4.583 4.514l-.724.724c1.671 1.079 3.956 3.574 4.083 4.722c.005.049.023.092.041.135c.076.183.252.31.455.31l.057-.003a.5.5 0 0 0 .441-.552c-.162-1.464-2.411-4.04-4.353-5.336zm-4.541 4.541l-.724.724c1.671 1.079 3.955 3.574 4.083 4.721a.449.449 0 0 0 .042.136a.497.497 0 0 0 .454.309l.057-.003a.5.5 0 0 0 .441-.552c-.163-1.463-2.412-4.038-4.353-5.335zm-4.542 4.541l-.724.724c1.671 1.079 3.955 3.574 4.082 4.722a.449.449 0 0 0 .042.136a.496.496 0 0 0 .455.309l.056-.003a.5.5 0 0 0 .442-.552c-.163-1.463-2.411-4.039-4.353-5.336zm-4.542 4.543l-.724.724c1.671 1.079 3.955 3.574 4.083 4.722a.443.443 0 0 0 .042.135a.497.497 0 0 0 .953-.247c-.164-1.462-2.413-4.038-4.354-5.334z" fill="#FFD983"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

16
desktop/static/index.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

File diff suppressed because one or more lines are too long

1
desktop/static/js/htmx-2.0.3.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
desktop/wails.syso Normal file

Binary file not shown.