From 7a258d28a25c5ae1fe14e8f834dabd0a292d6f47 Mon Sep 17 00:00:00 2001 From: nite Date: Thu, 5 Feb 2026 15:28:49 +0800 Subject: [PATCH] remove: android, ios taskfile --- README.md | 1 + Taskfile.yml | 6 +- build/Taskfile.yml | 66 +--- build/android/Taskfile.yml | 237 ------------- build/android/app/build.gradle | 63 ---- build/android/app/proguard-rules.pro | 12 - .../android/app/src/main/AndroidManifest.xml | 30 -- .../main/java/com/wails/app/MainActivity.java | 198 ----------- .../main/java/com/wails/app/WailsBridge.java | 214 ------------ .../java/com/wails/app/WailsJSBridge.java | 142 -------- .../java/com/wails/app/WailsPathHandler.java | 118 ------- .../app/src/main/res/layout/activity_main.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 2338 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 2338 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 1652 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 1652 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 3276 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 3276 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 5202 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 5202 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 7198 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 7198 -> 0 bytes .../app/src/main/res/values/colors.xml | 8 - .../app/src/main/res/values/strings.xml | 4 - .../app/src/main/res/values/themes.xml | 14 - build/android/build.gradle | 4 - build/android/gradle.properties | 26 -- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 45633 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 - build/android/gradlew | 248 -------------- build/android/gradlew.bat | 93 ----- build/android/main_android.go | 11 - build/android/scripts/deps/install_deps.go | 151 --------- build/android/settings.gradle | 18 - build/config.yml | 21 +- build/ios/Assets.xcassets | 116 ------- build/ios/Info.dev.plist | 62 ---- build/ios/Info.plist | 59 ---- build/ios/LaunchScreen.storyboard | 53 --- build/ios/Taskfile.yml | 293 ---------------- build/ios/app_options_default.go | 10 - build/ios/app_options_ios.go | 11 - build/ios/build.sh | 72 ---- build/ios/entitlements.plist | 21 -- build/ios/icon.png | 3 - build/ios/main.m | 23 -- build/ios/main_ios.go | 24 -- build/ios/project.pbxproj | 222 ------------ build/ios/scripts/deps/install_deps.go | 319 ------------------ build/windows/Taskfile.yml | 2 +- .../mesh-drop/internal/discovery/service.ts | 22 +- .../mesh-drop/internal/transfer/models.ts | 8 + 52 files changed, 33 insertions(+), 2991 deletions(-) delete mode 100644 build/android/Taskfile.yml delete mode 100644 build/android/app/build.gradle delete mode 100644 build/android/app/proguard-rules.pro delete mode 100644 build/android/app/src/main/AndroidManifest.xml delete mode 100644 build/android/app/src/main/java/com/wails/app/MainActivity.java delete mode 100644 build/android/app/src/main/java/com/wails/app/WailsBridge.java delete mode 100644 build/android/app/src/main/java/com/wails/app/WailsJSBridge.java delete mode 100644 build/android/app/src/main/java/com/wails/app/WailsPathHandler.java delete mode 100644 build/android/app/src/main/res/layout/activity_main.xml delete mode 100644 build/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 build/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 build/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 build/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 build/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 build/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 build/android/app/src/main/res/values/colors.xml delete mode 100644 build/android/app/src/main/res/values/strings.xml delete mode 100644 build/android/app/src/main/res/values/themes.xml delete mode 100644 build/android/build.gradle delete mode 100644 build/android/gradle.properties delete mode 100644 build/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 build/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 build/android/gradlew delete mode 100644 build/android/gradlew.bat delete mode 100644 build/android/main_android.go delete mode 100644 build/android/scripts/deps/install_deps.go delete mode 100644 build/android/settings.gradle delete mode 100644 build/ios/Assets.xcassets delete mode 100644 build/ios/Info.dev.plist delete mode 100644 build/ios/Info.plist delete mode 100644 build/ios/LaunchScreen.storyboard delete mode 100644 build/ios/Taskfile.yml delete mode 100644 build/ios/app_options_default.go delete mode 100644 build/ios/app_options_ios.go delete mode 100644 build/ios/build.sh delete mode 100644 build/ios/entitlements.plist delete mode 100644 build/ios/icon.png delete mode 100644 build/ios/main.m delete mode 100644 build/ios/main_ios.go delete mode 100644 build/ios/project.pbxproj delete mode 100644 build/ios/scripts/deps/install_deps.go diff --git a/README.md b/README.md index 3d4ce0a..5ba8b26 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ 1. **Go** (版本 >= 1.25) 2. **Node.js** 3. **Wails CLI** +4. **UPX** ### 安装依赖 diff --git a/Taskfile.yml b/Taskfile.yml index 76efbe2..4df283f 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,17 +1,15 @@ -version: '3' +version: "3" includes: common: ./build/Taskfile.yml windows: ./build/windows/Taskfile.yml darwin: ./build/darwin/Taskfile.yml linux: ./build/linux/Taskfile.yml - ios: ./build/ios/Taskfile.yml - android: ./build/android/Taskfile.yml vars: APP_NAME: "mesh-drop" BIN_DIR: "bin" - VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}' + VITE_PORT: "{{.WAILS_VITE_PORT | default 9245}}" tasks: build: diff --git a/build/Taskfile.yml b/build/Taskfile.yml index 60f77d8..d2d3204 100644 --- a/build/Taskfile.yml +++ b/build/Taskfile.yml @@ -1,4 +1,4 @@ -version: '3' +version: "3" tasks: go:mod:tidy: @@ -42,7 +42,6 @@ tasks: vars: BUILD_COMMAND: '{{if eq .DEV "true"}}build:dev{{else}}build{{end}}' - frontend:vendor:puppertino: summary: Fetches Puppertino CSS into frontend/public for consistent mobile styling sources: @@ -78,7 +77,6 @@ tasks: sed -E -i'' 's/class=\"btn\"/class=\"p-btn p-prim-col\"/g' "$INDEX_HTML" || true fi - generate:bindings: label: generate:bindings (BUILD_FLAGS={{.BUILD_FLAGS}}) summary: Generates bindings for the frontend @@ -87,7 +85,7 @@ tasks: sources: - "**/*.[jt]s" - exclude: frontend/**/* - - frontend/bindings/**/* # Rerun when switching between dev/production mode causes changes in output + - frontend/bindings/**/* # Rerun when switching between dev/production mode causes changes in output - "**/*.go" - go.mod - go.sum @@ -190,63 +188,3 @@ tasks: preconditions: - sh: docker info > /dev/null 2>&1 msg: "Docker is required. Please install Docker first." - - ios:device:list: - summary: Lists connected iOS devices (UDIDs) - cmds: - - xcrun xcdevice list - - ios:run:device: - summary: Build, install, and launch on a physical iPhone using Apple tools (xcodebuild/devicectl) - vars: - PROJECT: '{{.PROJECT}}' # e.g., build/ios/xcode/.xcodeproj - SCHEME: '{{.SCHEME}}' # e.g., ios.dev - CONFIG: '{{.CONFIG | default "Debug"}}' - DERIVED: '{{.DERIVED | default "build/ios/DerivedData"}}' - UDID: '{{.UDID}}' # from `task ios:device:list` - BUNDLE_ID: '{{.BUNDLE_ID}}' # e.g., com.yourco.wails.ios.dev - TEAM_ID: '{{.TEAM_ID}}' # optional, if your project is not already set up for signing - preconditions: - - sh: xcrun -f xcodebuild - msg: "xcodebuild not found. Please install Xcode." - - sh: xcrun -f devicectl - msg: "devicectl not found. Please update to Xcode 15+ (which includes devicectl)." - - sh: test -n '{{.PROJECT}}' - msg: "Set PROJECT to your .xcodeproj path (e.g., PROJECT=build/ios/xcode/App.xcodeproj)." - - sh: test -n '{{.SCHEME}}' - msg: "Set SCHEME to your app scheme (e.g., SCHEME=ios.dev)." - - sh: test -n '{{.UDID}}' - msg: "Set UDID to your device UDID (see: task ios:device:list)." - - sh: test -n '{{.BUNDLE_ID}}' - msg: "Set BUNDLE_ID to your app's bundle identifier (e.g., com.yourco.wails.ios.dev)." - cmds: - - | - set -euo pipefail - echo "Building for device: UDID={{.UDID}} SCHEME={{.SCHEME}} PROJECT={{.PROJECT}}" - XCB_ARGS=( - -project "{{.PROJECT}}" - -scheme "{{.SCHEME}}" - -configuration "{{.CONFIG}}" - -destination "id={{.UDID}}" - -derivedDataPath "{{.DERIVED}}" - -allowProvisioningUpdates - -allowProvisioningDeviceRegistration - ) - # Optionally inject signing identifiers if provided - if [ -n '{{.TEAM_ID}}' ]; then XCB_ARGS+=(DEVELOPMENT_TEAM={{.TEAM_ID}}); fi - if [ -n '{{.BUNDLE_ID}}' ]; then XCB_ARGS+=(PRODUCT_BUNDLE_IDENTIFIER={{.BUNDLE_ID}}); fi - xcodebuild "${XCB_ARGS[@]}" build | xcpretty || true - # If xcpretty isn't installed, run without it - if [ "${PIPESTATUS[0]}" -ne 0 ]; then - xcodebuild "${XCB_ARGS[@]}" build - fi - # Find built .app - APP_PATH=$(find "{{.DERIVED}}/Build/Products" -type d -name "*.app" -maxdepth 3 | head -n 1) - if [ -z "$APP_PATH" ]; then - echo "Could not locate built .app under {{.DERIVED}}/Build/Products" >&2 - exit 1 - fi - echo "Installing: $APP_PATH" - xcrun devicectl device install app --device "{{.UDID}}" "$APP_PATH" - echo "Launching: {{.BUNDLE_ID}}" - xcrun devicectl device process launch --device "{{.UDID}}" --stderr console --stdout console "{{.BUNDLE_ID}}" diff --git a/build/android/Taskfile.yml b/build/android/Taskfile.yml deleted file mode 100644 index aca62e4..0000000 --- a/build/android/Taskfile.yml +++ /dev/null @@ -1,237 +0,0 @@ -version: '3' - -includes: - common: ../Taskfile.yml - -vars: - APP_ID: '{{.APP_ID | default "com.wails.app"}}' - MIN_SDK: '21' - TARGET_SDK: '34' - NDK_VERSION: 'r26d' - -tasks: - install:deps: - summary: Check and install Android development dependencies - cmds: - - go run build/android/scripts/deps/install_deps.go - env: - TASK_FORCE_YES: '{{if .YES}}true{{else}}false{{end}}' - prompt: This will check and install Android development dependencies. Continue? - - build: - summary: Creates a build of the application for Android - deps: - - task: common:go:mod:tidy - - task: generate:android:bindings - vars: - BUILD_FLAGS: - ref: .BUILD_FLAGS - - task: common:build:frontend - vars: - BUILD_FLAGS: - ref: .BUILD_FLAGS - PRODUCTION: - ref: .PRODUCTION - - task: common:generate:icons - cmds: - - echo "Building Android app {{.APP_NAME}}..." - - task: compile:go:shared - vars: - ARCH: '{{.ARCH | default "arm64"}}' - vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production,android -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-tags android,debug -buildvcs=false -gcflags=all="-l"{{end}}' - env: - PRODUCTION: '{{.PRODUCTION | default "false"}}' - - compile:go:shared: - summary: Compile Go code to shared library (.so) - cmds: - - | - NDK_ROOT="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/{{.NDK_VERSION}}}" - if [ ! -d "$NDK_ROOT" ]; then - echo "Error: Android NDK not found at $NDK_ROOT" - echo "Please set ANDROID_NDK_HOME or install NDK {{.NDK_VERSION}} via Android Studio" - exit 1 - fi - - # Determine toolchain based on host OS - case "$(uname -s)" in - Darwin) HOST_TAG="darwin-x86_64" ;; - Linux) HOST_TAG="linux-x86_64" ;; - *) echo "Unsupported host OS"; exit 1 ;; - esac - - TOOLCHAIN="$NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG" - - # Set compiler based on architecture - case "{{.ARCH}}" in - arm64) - export CC="$TOOLCHAIN/bin/aarch64-linux-android{{.MIN_SDK}}-clang" - export CXX="$TOOLCHAIN/bin/aarch64-linux-android{{.MIN_SDK}}-clang++" - export GOARCH=arm64 - JNI_DIR="arm64-v8a" - ;; - amd64|x86_64) - export CC="$TOOLCHAIN/bin/x86_64-linux-android{{.MIN_SDK}}-clang" - export CXX="$TOOLCHAIN/bin/x86_64-linux-android{{.MIN_SDK}}-clang++" - export GOARCH=amd64 - JNI_DIR="x86_64" - ;; - *) - echo "Unsupported architecture: {{.ARCH}}" - exit 1 - ;; - esac - - export CGO_ENABLED=1 - export GOOS=android - - mkdir -p {{.BIN_DIR}} - mkdir -p build/android/app/src/main/jniLibs/$JNI_DIR - - go build -buildmode=c-shared {{.BUILD_FLAGS}} \ - -o build/android/app/src/main/jniLibs/$JNI_DIR/libwails.so - vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production,android -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-tags android,debug -buildvcs=false -gcflags=all="-l"{{end}}' - - compile:go:all-archs: - summary: Compile Go code for all Android architectures (fat APK) - cmds: - - task: compile:go:shared - vars: - ARCH: arm64 - - task: compile:go:shared - vars: - ARCH: amd64 - - package: - summary: Packages a production build of the application into an APK - deps: - - task: build - vars: - PRODUCTION: "true" - cmds: - - task: assemble:apk - - package:fat: - summary: Packages a production build for all architectures (fat APK) - cmds: - - task: compile:go:all-archs - - task: assemble:apk - - assemble:apk: - summary: Assembles the APK using Gradle - cmds: - - | - cd build/android - ./gradlew assembleDebug - cp app/build/outputs/apk/debug/app-debug.apk "../../{{.BIN_DIR}}/{{.APP_NAME}}.apk" - echo "APK created: {{.BIN_DIR}}/{{.APP_NAME}}.apk" - - assemble:apk:release: - summary: Assembles a release APK using Gradle - cmds: - - | - cd build/android - ./gradlew assembleRelease - cp app/build/outputs/apk/release/app-release-unsigned.apk "../../{{.BIN_DIR}}/{{.APP_NAME}}-release.apk" - echo "Release APK created: {{.BIN_DIR}}/{{.APP_NAME}}-release.apk" - - generate:android:bindings: - internal: true - summary: Generates bindings for Android - sources: - - "**/*.go" - - go.mod - - go.sum - generates: - - frontend/bindings/**/* - cmds: - - wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true - env: - GOOS: android - CGO_ENABLED: 1 - GOARCH: '{{.ARCH | default "arm64"}}' - - ensure-emulator: - internal: true - summary: Ensure Android Emulator is running - silent: true - cmds: - - | - # Check if an emulator is already running - if adb devices | grep -q "emulator"; then - echo "Emulator already running" - exit 0 - fi - - # Get first available AVD - AVD_NAME=$(emulator -list-avds | head -1) - if [ -z "$AVD_NAME" ]; then - echo "No Android Virtual Devices found." - echo "Create one using: Android Studio > Tools > Device Manager" - exit 1 - fi - - echo "Starting emulator: $AVD_NAME" - emulator -avd "$AVD_NAME" -no-snapshot-load & - - # Wait for emulator to boot (max 60 seconds) - echo "Waiting for emulator to boot..." - adb wait-for-device - - for i in {1..60}; do - BOOT_COMPLETED=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r') - if [ "$BOOT_COMPLETED" = "1" ]; then - echo "Emulator booted successfully" - exit 0 - fi - sleep 1 - done - - echo "Emulator boot timeout" - exit 1 - preconditions: - - sh: command -v adb - msg: "adb not found. Please install Android SDK and add platform-tools to PATH" - - sh: command -v emulator - msg: "emulator not found. Please install Android SDK and add emulator to PATH" - - deploy-emulator: - summary: Deploy to Android Emulator - deps: [package] - cmds: - - adb uninstall {{.APP_ID}} 2>/dev/null || true - - adb install "{{.BIN_DIR}}/{{.APP_NAME}}.apk" - - adb shell am start -n {{.APP_ID}}/.MainActivity - - run: - summary: Run the application in Android Emulator - deps: - - task: ensure-emulator - - task: build - vars: - ARCH: x86_64 - cmds: - - task: assemble:apk - - adb uninstall {{.APP_ID}} 2>/dev/null || true - - adb install "{{.BIN_DIR}}/{{.APP_NAME}}.apk" - - adb shell am start -n {{.APP_ID}}/.MainActivity - - logs: - summary: Stream Android logcat filtered to this app - cmds: - - adb logcat -v time | grep -E "(Wails|{{.APP_NAME}})" - - logs:all: - summary: Stream all Android logcat (verbose) - cmds: - - adb logcat -v time - - clean: - summary: Clean build artifacts - cmds: - - rm -rf {{.BIN_DIR}} - - rm -rf build/android/app/build - - rm -rf build/android/app/src/main/jniLibs/*/libwails.so - - rm -rf build/android/.gradle diff --git a/build/android/app/build.gradle b/build/android/app/build.gradle deleted file mode 100644 index 78fdbf7..0000000 --- a/build/android/app/build.gradle +++ /dev/null @@ -1,63 +0,0 @@ -plugins { - id 'com.android.application' -} - -android { - namespace 'com.wails.app' - compileSdk 34 - - buildFeatures { - buildConfig = true - } - - defaultConfig { - applicationId "com.wails.app" - minSdk 21 - targetSdk 34 - versionCode 1 - versionName "1.0" - - // Configure supported ABIs - ndk { - abiFilters 'arm64-v8a', 'x86_64' - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - debug { - debuggable true - } - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 - } - - // Source sets configuration - sourceSets { - main { - // JNI libraries are in jniLibs folder - jniLibs.srcDirs = ['src/main/jniLibs'] - // Assets for the WebView - assets.srcDirs = ['src/main/assets'] - } - } - - // Packaging options - packagingOptions { - // Don't strip Go symbols in debug builds - doNotStrip '*/arm64-v8a/libwails.so' - doNotStrip '*/x86_64/libwails.so' - } -} - -dependencies { - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.webkit:webkit:1.9.0' - implementation 'com.google.android.material:material:1.11.0' -} diff --git a/build/android/app/proguard-rules.pro b/build/android/app/proguard-rules.pro deleted file mode 100644 index 8b88c3d..0000000 --- a/build/android/app/proguard-rules.pro +++ /dev/null @@ -1,12 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. - -# Keep native methods --keepclasseswithmembernames class * { - native ; -} - -# Keep Wails bridge classes --keep class com.wails.app.WailsBridge { *; } --keep class com.wails.app.WailsJSBridge { *; } diff --git a/build/android/app/src/main/AndroidManifest.xml b/build/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 6c7982a..0000000 --- a/build/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/build/android/app/src/main/java/com/wails/app/MainActivity.java b/build/android/app/src/main/java/com/wails/app/MainActivity.java deleted file mode 100644 index 3067fee..0000000 --- a/build/android/app/src/main/java/com/wails/app/MainActivity.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.wails.app; - -import android.annotation.SuppressLint; -import android.os.Bundle; -import android.util.Log; -import android.webkit.WebResourceRequest; -import android.webkit.WebResourceResponse; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.webkit.WebViewAssetLoader; -import com.wails.app.BuildConfig; - -/** - * MainActivity hosts the WebView and manages the Wails application lifecycle. - * It uses WebViewAssetLoader to serve assets from the Go library without - * requiring a network server. - */ -public class MainActivity extends AppCompatActivity { - private static final String TAG = "WailsActivity"; - private static final String WAILS_SCHEME = "https"; - private static final String WAILS_HOST = "wails.localhost"; - - private WebView webView; - private WailsBridge bridge; - private WebViewAssetLoader assetLoader; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // Initialize the native Go library - bridge = new WailsBridge(this); - bridge.initialize(); - - // Set up WebView - setupWebView(); - - // Load the application - loadApplication(); - } - - @SuppressLint("SetJavaScriptEnabled") - private void setupWebView() { - webView = findViewById(R.id.webview); - - // Configure WebView settings - WebSettings settings = webView.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setDomStorageEnabled(true); - settings.setDatabaseEnabled(true); - settings.setAllowFileAccess(false); - settings.setAllowContentAccess(false); - settings.setMediaPlaybackRequiresUserGesture(false); - settings.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW); - - // Enable debugging in debug builds - if (BuildConfig.DEBUG) { - WebView.setWebContentsDebuggingEnabled(true); - } - - // Set up asset loader for serving local assets - assetLoader = new WebViewAssetLoader.Builder() - .setDomain(WAILS_HOST) - .addPathHandler("/", new WailsPathHandler(bridge)) - .build(); - - // Set up WebView client to intercept requests - webView.setWebViewClient(new WebViewClient() { - @Nullable - @Override - public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { - String url = request.getUrl().toString(); - Log.d(TAG, "Intercepting request: " + url); - - // Handle wails.localhost requests - if (request.getUrl().getHost() != null && - request.getUrl().getHost().equals(WAILS_HOST)) { - - // For wails API calls (runtime, capabilities, etc.), we need to pass the full URL - // including query string because WebViewAssetLoader.PathHandler strips query params - String path = request.getUrl().getPath(); - if (path != null && path.startsWith("/wails/")) { - // Get full path with query string for runtime calls - String fullPath = path; - String query = request.getUrl().getQuery(); - if (query != null && !query.isEmpty()) { - fullPath = path + "?" + query; - } - Log.d(TAG, "Wails API call detected, full path: " + fullPath); - - // Call bridge directly with full path - byte[] data = bridge.serveAsset(fullPath, request.getMethod(), "{}"); - if (data != null && data.length > 0) { - java.io.InputStream inputStream = new java.io.ByteArrayInputStream(data); - java.util.Map headers = new java.util.HashMap<>(); - headers.put("Access-Control-Allow-Origin", "*"); - headers.put("Cache-Control", "no-cache"); - headers.put("Content-Type", "application/json"); - - return new WebResourceResponse( - "application/json", - "UTF-8", - 200, - "OK", - headers, - inputStream - ); - } - // Return error response if data is null - return new WebResourceResponse( - "application/json", - "UTF-8", - 500, - "Internal Error", - new java.util.HashMap<>(), - new java.io.ByteArrayInputStream("{}".getBytes()) - ); - } - - // For regular assets, use the asset loader - return assetLoader.shouldInterceptRequest(request.getUrl()); - } - - return super.shouldInterceptRequest(view, request); - } - - @Override - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - Log.d(TAG, "Page loaded: " + url); - // Inject Wails runtime - bridge.injectRuntime(webView, url); - } - }); - - // Add JavaScript interface for Go communication - webView.addJavascriptInterface(new WailsJSBridge(bridge, webView), "wails"); - } - - private void loadApplication() { - // Load the main page from the asset server - String url = WAILS_SCHEME + "://" + WAILS_HOST + "/"; - Log.d(TAG, "Loading URL: " + url); - webView.loadUrl(url); - } - - /** - * Execute JavaScript in the WebView from the Go side - */ - public void executeJavaScript(final String js) { - runOnUiThread(() -> { - if (webView != null) { - webView.evaluateJavascript(js, null); - } - }); - } - - @Override - protected void onResume() { - super.onResume(); - if (bridge != null) { - bridge.onResume(); - } - } - - @Override - protected void onPause() { - super.onPause(); - if (bridge != null) { - bridge.onPause(); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (bridge != null) { - bridge.shutdown(); - } - if (webView != null) { - webView.destroy(); - } - } - - @Override - public void onBackPressed() { - if (webView != null && webView.canGoBack()) { - webView.goBack(); - } else { - super.onBackPressed(); - } - } -} diff --git a/build/android/app/src/main/java/com/wails/app/WailsBridge.java b/build/android/app/src/main/java/com/wails/app/WailsBridge.java deleted file mode 100644 index 3dab652..0000000 --- a/build/android/app/src/main/java/com/wails/app/WailsBridge.java +++ /dev/null @@ -1,214 +0,0 @@ -package com.wails.app; - -import android.content.Context; -import android.util.Log; -import android.webkit.WebView; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * WailsBridge manages the connection between the Java/Android side and the Go native library. - * It handles: - * - Loading and initializing the native Go library - * - Serving asset requests from Go - * - Passing messages between JavaScript and Go - * - Managing callbacks for async operations - */ -public class WailsBridge { - private static final String TAG = "WailsBridge"; - - static { - // Load the native Go library - System.loadLibrary("wails"); - } - - private final Context context; - private final AtomicInteger callbackIdGenerator = new AtomicInteger(0); - private final ConcurrentHashMap pendingAssetCallbacks = new ConcurrentHashMap<>(); - private final ConcurrentHashMap pendingMessageCallbacks = new ConcurrentHashMap<>(); - private WebView webView; - private volatile boolean initialized = false; - - // Native methods - implemented in Go - private static native void nativeInit(WailsBridge bridge); - private static native void nativeShutdown(); - private static native void nativeOnResume(); - private static native void nativeOnPause(); - private static native void nativeOnPageFinished(String url); - private static native byte[] nativeServeAsset(String path, String method, String headers); - private static native String nativeHandleMessage(String message); - private static native String nativeGetAssetMimeType(String path); - - public WailsBridge(Context context) { - this.context = context; - } - - /** - * Initialize the native Go library - */ - public void initialize() { - if (initialized) { - return; - } - - Log.i(TAG, "Initializing Wails bridge..."); - try { - nativeInit(this); - initialized = true; - Log.i(TAG, "Wails bridge initialized successfully"); - } catch (Exception e) { - Log.e(TAG, "Failed to initialize Wails bridge", e); - } - } - - /** - * Shutdown the native Go library - */ - public void shutdown() { - if (!initialized) { - return; - } - - Log.i(TAG, "Shutting down Wails bridge..."); - try { - nativeShutdown(); - initialized = false; - } catch (Exception e) { - Log.e(TAG, "Error during shutdown", e); - } - } - - /** - * Called when the activity resumes - */ - public void onResume() { - if (initialized) { - nativeOnResume(); - } - } - - /** - * Called when the activity pauses - */ - public void onPause() { - if (initialized) { - nativeOnPause(); - } - } - - /** - * Serve an asset from the Go asset server - * @param path The URL path requested - * @param method The HTTP method - * @param headers The request headers as JSON - * @return The asset data, or null if not found - */ - public byte[] serveAsset(String path, String method, String headers) { - if (!initialized) { - Log.w(TAG, "Bridge not initialized, cannot serve asset: " + path); - return null; - } - - Log.d(TAG, "Serving asset: " + path); - try { - return nativeServeAsset(path, method, headers); - } catch (Exception e) { - Log.e(TAG, "Error serving asset: " + path, e); - return null; - } - } - - /** - * Get the MIME type for an asset - * @param path The asset path - * @return The MIME type string - */ - public String getAssetMimeType(String path) { - if (!initialized) { - return "application/octet-stream"; - } - - try { - String mimeType = nativeGetAssetMimeType(path); - return mimeType != null ? mimeType : "application/octet-stream"; - } catch (Exception e) { - Log.e(TAG, "Error getting MIME type for: " + path, e); - return "application/octet-stream"; - } - } - - /** - * Handle a message from JavaScript - * @param message The message from JavaScript (JSON) - * @return The response to send back to JavaScript (JSON) - */ - public String handleMessage(String message) { - if (!initialized) { - Log.w(TAG, "Bridge not initialized, cannot handle message"); - return "{\"error\":\"Bridge not initialized\"}"; - } - - Log.d(TAG, "Handling message from JS: " + message); - try { - return nativeHandleMessage(message); - } catch (Exception e) { - Log.e(TAG, "Error handling message", e); - return "{\"error\":\"" + e.getMessage() + "\"}"; - } - } - - /** - * Inject the Wails runtime JavaScript into the WebView. - * Called when the page finishes loading. - * @param webView The WebView to inject into - * @param url The URL that finished loading - */ - public void injectRuntime(WebView webView, String url) { - this.webView = webView; - // Notify Go side that page has finished loading so it can inject the runtime - Log.d(TAG, "Page finished loading: " + url + ", notifying Go side"); - if (initialized) { - nativeOnPageFinished(url); - } - } - - /** - * Execute JavaScript in the WebView (called from Go side) - * @param js The JavaScript code to execute - */ - public void executeJavaScript(String js) { - if (webView != null) { - webView.post(() -> webView.evaluateJavascript(js, null)); - } - } - - /** - * Called from Go when an event needs to be emitted to JavaScript - * @param eventName The event name - * @param eventData The event data (JSON) - */ - public void emitEvent(String eventName, String eventData) { - String js = String.format("window.wails && window.wails._emit('%s', %s);", - escapeJsString(eventName), eventData); - executeJavaScript(js); - } - - private String escapeJsString(String str) { - return str.replace("\\", "\\\\") - .replace("'", "\\'") - .replace("\n", "\\n") - .replace("\r", "\\r"); - } - - // Callback interfaces - public interface AssetCallback { - void onAssetReady(byte[] data, String mimeType); - void onAssetError(String error); - } - - public interface MessageCallback { - void onResponse(String response); - void onError(String error); - } -} diff --git a/build/android/app/src/main/java/com/wails/app/WailsJSBridge.java b/build/android/app/src/main/java/com/wails/app/WailsJSBridge.java deleted file mode 100644 index 98ae5b2..0000000 --- a/build/android/app/src/main/java/com/wails/app/WailsJSBridge.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.wails.app; - -import android.util.Log; -import android.webkit.JavascriptInterface; -import android.webkit.WebView; -import com.wails.app.BuildConfig; - -/** - * WailsJSBridge provides the JavaScript interface that allows the web frontend - * to communicate with the Go backend. This is exposed to JavaScript as the - * `window.wails` object. - * - * Similar to iOS's WKScriptMessageHandler but using Android's addJavascriptInterface. - */ -public class WailsJSBridge { - private static final String TAG = "WailsJSBridge"; - - private final WailsBridge bridge; - private final WebView webView; - - public WailsJSBridge(WailsBridge bridge, WebView webView) { - this.bridge = bridge; - this.webView = webView; - } - - /** - * Send a message to Go and return the response synchronously. - * Called from JavaScript: wails.invoke(message) - * - * @param message The message to send (JSON string) - * @return The response from Go (JSON string) - */ - @JavascriptInterface - public String invoke(String message) { - Log.d(TAG, "Invoke called: " + message); - return bridge.handleMessage(message); - } - - /** - * Send a message to Go asynchronously. - * The response will be sent back via a callback. - * Called from JavaScript: wails.invokeAsync(callbackId, message) - * - * @param callbackId The callback ID to use for the response - * @param message The message to send (JSON string) - */ - @JavascriptInterface - public void invokeAsync(final String callbackId, final String message) { - Log.d(TAG, "InvokeAsync called: " + message); - - // Handle in background thread to not block JavaScript - new Thread(() -> { - try { - String response = bridge.handleMessage(message); - sendCallback(callbackId, response, null); - } catch (Exception e) { - Log.e(TAG, "Error in async invoke", e); - sendCallback(callbackId, null, e.getMessage()); - } - }).start(); - } - - /** - * Log a message from JavaScript to Android's logcat - * Called from JavaScript: wails.log(level, message) - * - * @param level The log level (debug, info, warn, error) - * @param message The message to log - */ - @JavascriptInterface - public void log(String level, String message) { - switch (level.toLowerCase()) { - case "debug": - Log.d(TAG + "/JS", message); - break; - case "info": - Log.i(TAG + "/JS", message); - break; - case "warn": - Log.w(TAG + "/JS", message); - break; - case "error": - Log.e(TAG + "/JS", message); - break; - default: - Log.v(TAG + "/JS", message); - break; - } - } - - /** - * Get the platform name - * Called from JavaScript: wails.platform() - * - * @return "android" - */ - @JavascriptInterface - public String platform() { - return "android"; - } - - /** - * Check if we're running in debug mode - * Called from JavaScript: wails.isDebug() - * - * @return true if debug build, false otherwise - */ - @JavascriptInterface - public boolean isDebug() { - return BuildConfig.DEBUG; - } - - /** - * Send a callback response to JavaScript - */ - private void sendCallback(String callbackId, String result, String error) { - final String js; - if (error != null) { - js = String.format( - "window.wails && window.wails._callback('%s', null, '%s');", - escapeJsString(callbackId), - escapeJsString(error) - ); - } else { - js = String.format( - "window.wails && window.wails._callback('%s', %s, null);", - escapeJsString(callbackId), - result != null ? result : "null" - ); - } - - webView.post(() -> webView.evaluateJavascript(js, null)); - } - - private String escapeJsString(String str) { - if (str == null) return ""; - return str.replace("\\", "\\\\") - .replace("'", "\\'") - .replace("\n", "\\n") - .replace("\r", "\\r"); - } -} diff --git a/build/android/app/src/main/java/com/wails/app/WailsPathHandler.java b/build/android/app/src/main/java/com/wails/app/WailsPathHandler.java deleted file mode 100644 index 326fa9b..0000000 --- a/build/android/app/src/main/java/com/wails/app/WailsPathHandler.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.wails.app; - -import android.net.Uri; -import android.util.Log; -import android.webkit.WebResourceResponse; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.webkit.WebViewAssetLoader; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -/** - * WailsPathHandler implements WebViewAssetLoader.PathHandler to serve assets - * from the Go asset server. This allows the WebView to load assets without - * using a network server, similar to iOS's WKURLSchemeHandler. - */ -public class WailsPathHandler implements WebViewAssetLoader.PathHandler { - private static final String TAG = "WailsPathHandler"; - - private final WailsBridge bridge; - - public WailsPathHandler(WailsBridge bridge) { - this.bridge = bridge; - } - - @Nullable - @Override - public WebResourceResponse handle(@NonNull String path) { - Log.d(TAG, "Handling path: " + path); - - // Normalize path - if (path.isEmpty() || path.equals("/")) { - path = "/index.html"; - } - - // Get asset from Go - byte[] data = bridge.serveAsset(path, "GET", "{}"); - - if (data == null || data.length == 0) { - Log.w(TAG, "Asset not found: " + path); - return null; // Return null to let WebView handle 404 - } - - // Determine MIME type - String mimeType = bridge.getAssetMimeType(path); - Log.d(TAG, "Serving " + path + " with type " + mimeType + " (" + data.length + " bytes)"); - - // Create response - InputStream inputStream = new ByteArrayInputStream(data); - Map headers = new HashMap<>(); - headers.put("Access-Control-Allow-Origin", "*"); - headers.put("Cache-Control", "no-cache"); - - return new WebResourceResponse( - mimeType, - "UTF-8", - 200, - "OK", - headers, - inputStream - ); - } - - /** - * Determine MIME type from file extension - */ - private String getMimeType(String path) { - String lowerPath = path.toLowerCase(); - - if (lowerPath.endsWith(".html") || lowerPath.endsWith(".htm")) { - return "text/html"; - } else if (lowerPath.endsWith(".js") || lowerPath.endsWith(".mjs")) { - return "application/javascript"; - } else if (lowerPath.endsWith(".css")) { - return "text/css"; - } else if (lowerPath.endsWith(".json")) { - return "application/json"; - } else if (lowerPath.endsWith(".png")) { - return "image/png"; - } else if (lowerPath.endsWith(".jpg") || lowerPath.endsWith(".jpeg")) { - return "image/jpeg"; - } else if (lowerPath.endsWith(".gif")) { - return "image/gif"; - } else if (lowerPath.endsWith(".svg")) { - return "image/svg+xml"; - } else if (lowerPath.endsWith(".ico")) { - return "image/x-icon"; - } else if (lowerPath.endsWith(".woff")) { - return "font/woff"; - } else if (lowerPath.endsWith(".woff2")) { - return "font/woff2"; - } else if (lowerPath.endsWith(".ttf")) { - return "font/ttf"; - } else if (lowerPath.endsWith(".eot")) { - return "application/vnd.ms-fontobject"; - } else if (lowerPath.endsWith(".xml")) { - return "application/xml"; - } else if (lowerPath.endsWith(".txt")) { - return "text/plain"; - } else if (lowerPath.endsWith(".wasm")) { - return "application/wasm"; - } else if (lowerPath.endsWith(".mp3")) { - return "audio/mpeg"; - } else if (lowerPath.endsWith(".mp4")) { - return "video/mp4"; - } else if (lowerPath.endsWith(".webm")) { - return "video/webm"; - } else if (lowerPath.endsWith(".webp")) { - return "image/webp"; - } - - return "application/octet-stream"; - } -} diff --git a/build/android/app/src/main/res/layout/activity_main.xml b/build/android/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index f278384..0000000 --- a/build/android/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - diff --git a/build/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/build/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 9409abebe25727f478a6088b9f350d7092f1c42f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2338 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 CP9Qq~ diff --git a/build/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/build/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 9409abebe25727f478a6088b9f350d7092f1c42f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2338 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 CP9Qq~ diff --git a/build/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/build/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 5b6acc0486f8ee63587fec8ea1cfbd285914a513..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1652 zcmV-)28;QLP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw0000) zWmrjOO-%qQ0000800D<-00aO40096102%-Q00003paB2_0000100961paK8{00001 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 Z*S8+|O3lyg+5Y_+Xshe1Ro+8I{s*@`184vM diff --git a/build/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/build/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 1c2c66452d8942ef1a2b3e8afa5f161183503775..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3276 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 Z*S8+|O3lyg+5Y_+Xshe1Ro+8I{s*@`184vM diff --git a/build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index be557d8973cd5835b1aaac9f15f2f0eac20bad7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5202 zcmb7oXHXMP(051zgg_vG^cISs)X=4e4oVY2>4YLhKv58+6A4XPP+G(iI!JHQOXy8{ z7X$uH&iIPO1!P>{x- zI^XL_4D70Is15*BCQ+X|kdt(Tlb)#|01zk$0EA-!fK$>`_yz#*90>qyq5%NK3;=+| z`(5K*WzvGyLkoQuLqmWtNrnK(qTK;tl0-%#b`k*qAOaZxMB-%s%@KhAvx*~t{#X8Q zqna8t1^{48(AQEodqK8iYw3ASmtA~`J6@8)u@gv^IV-RNfhVHHGdsg2*T}rC#nv@v zr5;v|3lH3>d7}TVPv^#~l<0&ik!!r#B0HKj8bo-EWIEC4mWEsgKU};T{+;pbS(wUh ze|D!LhgV|=FF zVWhV9J*jw2x1-RI6&5e!^Q({JqNXkSZs?nQH6VgEab?WO?e`niHEmhUVUZrWZ@6-# zZ;Gs(oDp6%Bv4dHh%#4-K@w>EQI)IS_t$v2>+rh(l%-l02po937r}){O)2DqkCQog zr-Ys#^cHVzZDoE8SjYe9?(R-)XlT&(wKKO%Nujp`Z$vA}+`9Ewq(4bO?CfOk>ZIUf zXkg?A9zxDXTHMVX;1^Q^-MP#st(N{r>tDj?wC}Q#ExzSlf0S=>6M~adw6L|c)%222rmg2@qpzs@y;HaJ7;(68`(~a( zmMl>1e7}?IQ5)XZfWZHZhiTpwsL!0i(57TvoPg>@i(}*N()nF|J4KgK}!4j@6^`%9{@dcyveb zN!#iO$wCV&E2}@#)=#GHjS9DIqA)~akkgyy4P~Ty~VTP+CcVFC^{-?w#2e}mg7k?(GYQtzCjaZm=WIZ zt-!|3?NVtGzcW{@E6z(SsO25)ie;qgdmY}^Gil`%>@%LLU&Nw3%&G7U3!|m2U=Y@X zlVL`~n^!-LGP`~qv3f|8kLgLPYHRygYF(G8a&>;>B!N9QKe;nVKVW}((shUAdGU7d)n%XCwT$BUQ28ucCBN-u!3z7p=9yZ49Q)}g zTp?Lf4wHnMDYJEY|DJ0+q5lrI%y8`IH`@miZ8zM#aRpV`uVp7^jy^Y4oz?J~RF-0{ znI&Wwhyo8znR}CXTo>thq};^VDi;F3)}81V?sUceb>#SX_Cmaqv#iYe%O#SL7&-Qe z(-AsorKOTyulOJ*LKLQ@N|nT^8hmT4V6|cC4|j&$VblJ{kLMb13tC#*nh|GkO@<$xRT*^X7p_lTpZ zuQP+s%k9b0t*8%0_X(tk$qfq;nX3yQdU~9Sr-6Zbn=_jo#<7UlYwp_b*7h47u z6_pzLcG88!mYvPb%{~8YPKDM*`Pp&+G0OkQy@jXT2^vyyzt$ES{QQmzKK2FopYiqe zJ|j5vj`#gbr1iV{rt*uMr;2cW&~vpXfhM8?&)@}d_CPQ()38H8Z~i$mO!PZQ+3)j? z%Lg=GY3FO55|n=DK`F!;&q)r2EcZCFGVf1|hJ=J{Z_L#uUqzuDG{^ZitV{{2WdXHqj!w4#Sp&+ME zSR|yZc!m$haYL(P?FHrbZA7HIH5$L!-fuxi%fQCLQD^b?zWDV9QnbT$Fk--)6%J2f zT8x?QI%$$G^pwnVr&zN`Pu&soIngSi=X#39lTRG`wLW`&l^f#|ZnNhAk_G=21L#`a zpc;w~qM}$rp3%06+;+dnPleG9&d{yLF@vmhQ-1gl-r)ddc@N0I@kHMvG}4wu+{R=) z)rdm&{T0Z||8&UxdO%08tgP1qx$R^d%CR<5*t?N0>_#)+(M7m@)J~3<>evD4dChRrj?7&eAJ2B??3uH&TO)=DSy{8~ zWC`qC(a_RVH#?78qzJCmUW;JbSa(dX_jQ{#XVhOnHJxcsmhl;Cbx1 zom3RvH>LNK3vQNwdjawrCqvYSF70PJ!%U-+IekYKb+hRYVhH}mQB=+u{doU6$4Aa^zf*BK5QV4f{I+&LWTT*79)I#`8Ukbru zw3wtby^)KJ2hsh(4sdaUr^j8(HTJE(mTyr=dykp2+F$~5P~z?9``{`WTsl9|Qks<^ z9%<}d(uZPU&ljLMddTucpZi_!?{1LP`>GZ}?7Iz@R+F};x`+}HO{Z>0rw2iPrf`;N z#{;7e9e9@K8;cOFrjC0v9OVTN@zJ+FKZhUIu?IX zv%s_Z5K%Yb40U=2460w?F z`u<0Ilr>-CP(fa@UE;Fg=Le?|)icrVJ4YT#&W8xsp$6L)XsJ+LFl8J_it84$uGAm< zQV1A^eJ`mM`e#^p#S;8esJyTK*$-$_Fn%eSD>sG+} z?jd}<3}M!lj@pf1rTh#*kVz$iUxF zfSkZ=P*p#uUBaebFCxw2fS%K_%cSk^_c+g$?8sm9$efv%GvZjsuk3nVd)~~T5yuhF zrY4dZ$zv1rDi&z+VwkPdwGc5a33tLqS0gGX!YHIKPjlwGEu)lE|Y$pAGudeYQ2G#Px zYjkXU(8>xK0*o7%7iZIY6<)*VrkseQNb?U!`_7sLHuu<=9nfOlRKe`gm|&$I`*92F zS-`Kn>(g=}#|m6({~bYBgF`pvEkj{o44XPDc{$JP^f$e7bL(+XGGHu?=e+9ZzoVaX z5tMYf`4R+JW@cvYxE`4xmhqHc@7X9U;jwXUkG#<`2L#(wR9J#8zVWRmt)AlcdxyGm zB{eUg!>Pt3Sg;`S!|J5_y?&OjDZy5QZM6cp!e4qi%p)COhaWfD8NT-HLxyG!e+;s< zgh)PZa#KJ;pc4@XJTxv8OkFDFHkGfx;H8D!7?M>Am@vqgm=788gt1C{=^@B{^<3-s zih?|W!@D6X%H#A$;TueeGMBy=r_ZC9Sf$>Rtt~X?1Q;CnUSxA&mfK=358n{U|Bj+E zly~-c^jg>c$s6=sn}i(*5b7I%W3gzxiJ$TPQmcSpT=6Zt(|H{)_bV5`BniJ=GBDf;CJ&_ z!cT{6~W$p0kuFS|7(E?4q*s>B#GfF%aE>~~Om_P@S9%;$Dxs|0jF-0h;GeYKCoOLSeLFGVJR zK(EF58?vD(MT&0vgd6P@evO2aqQKJH+Zh!&>WE+(Z1rsg{kZ1Tnp8Mscc z{OgIgM%hS*{Z3?pRM_RYulCsSTR-sY_X$7M+20f}$;@C|{F()XVb~9d>E>dK;WhJg z$&o>7L2k$wBaf-1b-c_D3a>Dr5+@5(c)DrIwv8Lm3Vq2L?v=t%MPr8a=FmoF|JdZ33*Zn_AZ zkSGjmN2ei=GF2nPbRr}V6DSkC(Dw?dKkkqojwdXa-2z8ey<3!3{K@Cgn2zXS$QEjz z7k2aC?r0)v6y=anvE&%W?8EEi!80|+iOe}#H=lscn%n#sy$}?mx)wzh*Lzu#Q_r!- zGN!;WD42ZIJmjAOYH4Q(TwQ(v7o);1cBja3D|C%Mg2DbQcpY0`ZaOj~3+l{QOL`Ac z-`atIcbp6hg|{gj3MvtmYS1|J%99h|L2LN|-#i24$ovzSLkPWY>)c>q11b^$Z32&` zW@r0e>2)Tuj3uI2dBwA99fZR!8WbAJL?p63wcrd98H&yBmJeHM`QbWlanK*ry+R=8 z?n^T>XqzAa#yz9aUqpVzF;D5^JuBm*9P0-L)_cpCQ)xU%7qi~vILi@MEB8gl19lj7 z=q5x)ZVZzm!s4mHTzOcAjDBM(iygvxUN@QAIU3h~#r7n7aUBY%zs0R(-SYI_H-E=L>h!!zQvMr2bSWK{Y>s^Y5 zXI&>rj~_oybgm5N5&Tq6vPf#-sur94@5tGlGtJE&At7Y>hM7H=2P0t?dxN;RF+p3M zs~MMHpQzP3-1QMOrz?HAXww;wFTsL?dDh>o6vrAd&I79n;k-C`xpgQdsq^GS;H{hK zk>JCg9-9?ZJ3Iy?;1eeglmfG7?UrU&TI~VfiX`*G3&rvvT6;Mg2_=DoIiqkwQCeuA z0@4mg!9YcS^9H6QUfj0PH(HSDOrsdDe~SSe7!(wiA0M~@=c9uPX%k4L#I_X)Eszy( z76_uRf4()%CahA@U*RU^43Y6AK?*@6fZ*z>^T5eV@m|e!k6ehrd`yRD5G}Xzi#@7zMZ9L=8Td~&mTz7Pa1F-96yzTCVtHy7|@(SNDMI|+Lm;L5fK>UKpRj#d-RS-Ab^;S5^9 zSi<7=-mQYyB`NRdjld|l?+9bs%S(!{2kkd_y6xe g*8c~=VtDt%T*)evu-5@v{{eLR+D2Ms8t9k*4~QCl3;+NC diff --git a/build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/build/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index be557d8973cd5835b1aaac9f15f2f0eac20bad7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5202 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 diff --git a/build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4507f32a51ac2cf9d0cde23d75f51d685905a706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7198 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 diff --git a/build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/build/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 4507f32a51ac2cf9d0cde23d75f51d685905a706..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7198 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 diff --git a/build/android/app/src/main/res/values/colors.xml b/build/android/app/src/main/res/values/colors.xml deleted file mode 100644 index dd33f3b..0000000 --- a/build/android/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - #3574D4 - #2C5FB8 - #1B2636 - #FFFFFFFF - #FF000000 - diff --git a/build/android/app/src/main/res/values/strings.xml b/build/android/app/src/main/res/values/strings.xml deleted file mode 100644 index 3ed9e47..0000000 --- a/build/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - Wails App - diff --git a/build/android/app/src/main/res/values/themes.xml b/build/android/app/src/main/res/values/themes.xml deleted file mode 100644 index be8a282..0000000 --- a/build/android/app/src/main/res/values/themes.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/build/android/build.gradle b/build/android/build.gradle deleted file mode 100644 index d7fbab3..0000000 --- a/build/android/build.gradle +++ /dev/null @@ -1,4 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -plugins { - id 'com.android.application' version '8.7.3' apply false -} diff --git a/build/android/gradle.properties b/build/android/gradle.properties deleted file mode 100644 index b9d4426..0000000 --- a/build/android/gradle.properties +++ /dev/null @@ -1,26 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. For more details, visit -# https://developer.android.com/build/optimize-your-build#parallel -# org.gradle.parallel=true - -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true - -# Enables namespacing of each library's R class so that its R class includes only the -# resources declared in the library itself and none from the library's dependencies, -# thereby reducing the size of the R class for that library -android.nonTransitiveRClass=true diff --git a/build/android/gradle/wrapper/gradle-wrapper.jar b/build/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f8e1ee3125fe0768e9a76ee977ac089eb657005e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45633 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�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 diff --git a/build/android/gradle/wrapper/gradle-wrapper.properties b/build/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 23449a2..0000000 --- a/build/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,7 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip -networkTimeout=10000 -validateDistributionUrl=true -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/build/android/gradlew b/build/android/gradlew deleted file mode 100644 index adff685..0000000 --- a/build/android/gradlew +++ /dev/null @@ -1,248 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/build/android/gradlew.bat b/build/android/gradlew.bat deleted file mode 100644 index c4bdd3a..0000000 --- a/build/android/gradlew.bat +++ /dev/null @@ -1,93 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/build/android/main_android.go b/build/android/main_android.go deleted file mode 100644 index 70a7164..0000000 --- a/build/android/main_android.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build android - -package main - -import "github.com/wailsapp/wails/v3/pkg/application" - -func init() { - // Register main function to be called when the Android app initializes - // This is necessary because in c-shared build mode, main() is not automatically called - application.RegisterAndroidMain(main) -} diff --git a/build/android/scripts/deps/install_deps.go b/build/android/scripts/deps/install_deps.go deleted file mode 100644 index d9dfedf..0000000 --- a/build/android/scripts/deps/install_deps.go +++ /dev/null @@ -1,151 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" -) - -func main() { - fmt.Println("Checking Android development dependencies...") - fmt.Println() - - errors := []string{} - - // Check Go - if !checkCommand("go", "version") { - errors = append(errors, "Go is not installed. Install from https://go.dev/dl/") - } else { - fmt.Println("✓ Go is installed") - } - - // Check ANDROID_HOME - androidHome := os.Getenv("ANDROID_HOME") - if androidHome == "" { - androidHome = os.Getenv("ANDROID_SDK_ROOT") - } - if androidHome == "" { - // Try common default locations - home, _ := os.UserHomeDir() - possiblePaths := []string{ - filepath.Join(home, "Android", "Sdk"), - filepath.Join(home, "Library", "Android", "sdk"), - "/usr/local/share/android-sdk", - } - for _, p := range possiblePaths { - if _, err := os.Stat(p); err == nil { - androidHome = p - break - } - } - } - - if androidHome == "" { - errors = append(errors, "ANDROID_HOME not set. Install Android Studio and set ANDROID_HOME environment variable") - } else { - fmt.Printf("✓ ANDROID_HOME: %s\n", androidHome) - } - - // Check adb - if !checkCommand("adb", "version") { - if androidHome != "" { - platformTools := filepath.Join(androidHome, "platform-tools") - errors = append(errors, fmt.Sprintf("adb not found. Add %s to PATH", platformTools)) - } else { - errors = append(errors, "adb not found. Install Android SDK Platform-Tools") - } - } else { - fmt.Println("✓ adb is installed") - } - - // Check emulator - if !checkCommand("emulator", "-list-avds") { - if androidHome != "" { - emulatorPath := filepath.Join(androidHome, "emulator") - errors = append(errors, fmt.Sprintf("emulator not found. Add %s to PATH", emulatorPath)) - } else { - errors = append(errors, "emulator not found. Install Android Emulator via SDK Manager") - } - } else { - fmt.Println("✓ Android Emulator is installed") - } - - // Check NDK - ndkHome := os.Getenv("ANDROID_NDK_HOME") - if ndkHome == "" && androidHome != "" { - // Look for NDK in default location - ndkDir := filepath.Join(androidHome, "ndk") - if entries, err := os.ReadDir(ndkDir); err == nil { - for _, entry := range entries { - if entry.IsDir() { - ndkHome = filepath.Join(ndkDir, entry.Name()) - break - } - } - } - } - - if ndkHome == "" { - errors = append(errors, "Android NDK not found. Install NDK via Android Studio > SDK Manager > SDK Tools > NDK (Side by side)") - } else { - fmt.Printf("✓ Android NDK: %s\n", ndkHome) - } - - // Check Java - if !checkCommand("java", "-version") { - errors = append(errors, "Java not found. Install JDK 11+ (OpenJDK recommended)") - } else { - fmt.Println("✓ Java is installed") - } - - // Check for AVD (Android Virtual Device) - if checkCommand("emulator", "-list-avds") { - cmd := exec.Command("emulator", "-list-avds") - output, err := cmd.Output() - if err == nil && len(strings.TrimSpace(string(output))) > 0 { - avds := strings.Split(strings.TrimSpace(string(output)), "\n") - fmt.Printf("✓ Found %d Android Virtual Device(s)\n", len(avds)) - } else { - fmt.Println("⚠ No Android Virtual Devices found. Create one via Android Studio > Tools > Device Manager") - } - } - - fmt.Println() - - if len(errors) > 0 { - fmt.Println("❌ Missing dependencies:") - for _, err := range errors { - fmt.Printf(" - %s\n", err) - } - fmt.Println() - fmt.Println("Setup instructions:") - fmt.Println("1. Install Android Studio: https://developer.android.com/studio") - fmt.Println("2. Open SDK Manager and install:") - fmt.Println(" - Android SDK Platform (API 34)") - fmt.Println(" - Android SDK Build-Tools") - fmt.Println(" - Android SDK Platform-Tools") - fmt.Println(" - Android Emulator") - fmt.Println(" - NDK (Side by side)") - fmt.Println("3. Set environment variables:") - if runtime.GOOS == "darwin" { - fmt.Println(" export ANDROID_HOME=$HOME/Library/Android/sdk") - } else { - fmt.Println(" export ANDROID_HOME=$HOME/Android/Sdk") - } - fmt.Println(" export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/emulator") - fmt.Println("4. Create an AVD via Android Studio > Tools > Device Manager") - os.Exit(1) - } - - fmt.Println("✓ All Android development dependencies are installed!") -} - -func checkCommand(name string, args ...string) bool { - cmd := exec.Command(name, args...) - cmd.Stdout = nil - cmd.Stderr = nil - return cmd.Run() == nil -} diff --git a/build/android/settings.gradle b/build/android/settings.gradle deleted file mode 100644 index a3f3ec3..0000000 --- a/build/android/settings.gradle +++ /dev/null @@ -1,18 +0,0 @@ -pluginManagement { - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) - repositories { - google() - mavenCentral() - } -} - -rootProject.name = "WailsApp" -include ':app' diff --git a/build/config.yml b/build/config.yml index 03cbfa9..9c6459e 100644 --- a/build/config.yml +++ b/build/config.yml @@ -1,7 +1,7 @@ # This file contains the configuration for this project. # When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets. # Note that this will overwrite any changes you have made to the assets. -version: '3' +version: "3" # This information is used to generate the build assets. info: @@ -12,23 +12,6 @@ info: copyright: "(c) 2025, My Company" # Copyright text comments: "Some Product Comments" # Comments version: "0.0.1" # The application version - # cfBundleIconName: "appicon" # The macOS icon name in Assets.car icon bundles (optional) - # # Should match the name of your .icon file without the extension - # # If not set and Assets.car exists, defaults to "appicon" - -# iOS build configuration (uncomment to customise iOS project generation) -# Note: Keys under `ios` OVERRIDE values under `info` when set. -# ios: -# # The iOS bundle identifier used in the generated Xcode project (CFBundleIdentifier) -# bundleID: "com.mycompany.myproduct" -# # The display name shown under the app icon (CFBundleDisplayName/CFBundleName) -# displayName: "My Product" -# # The app version to embed in Info.plist (CFBundleShortVersionString/CFBundleVersion) -# version: "0.0.1" -# # The company/organisation name for templates and project settings -# company: "My Company" -# # Additional comments to embed in Info.plist metadata -# comments: "Some Product Comments" # Dev mode configuration dev_mode: @@ -75,4 +58,4 @@ fileAssociations: # Other data other: - - name: My Other Data \ No newline at end of file + - name: My Other Data diff --git a/build/ios/Assets.xcassets b/build/ios/Assets.xcassets deleted file mode 100644 index 46fbb87..0000000 --- a/build/ios/Assets.xcassets +++ /dev/null @@ -1,116 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - }, - "images" : [ - { - "filename" : "icon-20@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "icon-20@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "filename" : "icon-29@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "icon-29@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "filename" : "icon-40@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "icon-40@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "filename" : "icon-60@2x.png", - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "filename" : "icon-60@3x.png", - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "filename" : "icon-20.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "filename" : "icon-20@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "filename" : "icon-29.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "filename" : "icon-29@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "filename" : "icon-40.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "filename" : "icon-40@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "icon-76.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "filename" : "icon-76@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "filename" : "icon-83.5@2x.png", - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "filename" : "icon-1024.png", - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ] -} \ No newline at end of file diff --git a/build/ios/Info.dev.plist b/build/ios/Info.dev.plist deleted file mode 100644 index 71789cb..0000000 --- a/build/ios/Info.dev.plist +++ /dev/null @@ -1,62 +0,0 @@ - - - - - CFBundleExecutable - mesh-drop - CFBundleIdentifier - com.example.meshdrop.dev - CFBundleName - My Product (Dev) - CFBundleDisplayName - My Product (Dev) - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1.0-dev - CFBundleVersion - 0.1.0 - LSRequiresIPhoneOS - - MinimumOSVersion - 15.0 - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsLocalNetworking - - - - WailsDevelopmentMode - - - NSHumanReadableCopyright - © 2026, My Company - - - CFBundleGetInfoString - This is a comment - - - \ No newline at end of file diff --git a/build/ios/Info.plist b/build/ios/Info.plist deleted file mode 100644 index 89fd385..0000000 --- a/build/ios/Info.plist +++ /dev/null @@ -1,59 +0,0 @@ - - - - - CFBundleExecutable - mesh-drop - CFBundleIdentifier - com.example.meshdrop - CFBundleName - My Product - CFBundleDisplayName - My Product - CFBundlePackageType - APPL - CFBundleShortVersionString - 0.1.0 - CFBundleVersion - 0.1.0 - LSRequiresIPhoneOS - - MinimumOSVersion - 15.0 - UILaunchStoryboardName - LaunchScreen - UIRequiredDeviceCapabilities - - armv7 - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSAppTransportSecurity - - NSAllowsArbitraryLoads - - NSAllowsLocalNetworking - - - - NSHumanReadableCopyright - © 2026, My Company - - - CFBundleGetInfoString - This is a comment - - - \ No newline at end of file diff --git a/build/ios/LaunchScreen.storyboard b/build/ios/LaunchScreen.storyboard deleted file mode 100644 index 176e2e4..0000000 --- a/build/ios/LaunchScreen.storyboard +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/ios/Taskfile.yml b/build/ios/Taskfile.yml deleted file mode 100644 index 8c27f08..0000000 --- a/build/ios/Taskfile.yml +++ /dev/null @@ -1,293 +0,0 @@ -version: '3' - -includes: - common: ../Taskfile.yml - -vars: - BUNDLE_ID: '{{.BUNDLE_ID | default "com.wails.app"}}' - # SDK_PATH is computed lazily at task-level to avoid errors on non-macOS systems - # Each task that needs it defines SDK_PATH in its own vars section - -tasks: - install:deps: - summary: Check and install iOS development dependencies - cmds: - - go run build/ios/scripts/deps/install_deps.go - env: - TASK_FORCE_YES: '{{if .YES}}true{{else}}false{{end}}' - prompt: This will check and install iOS development dependencies. Continue? - - # Note: Bindings generation may show CGO warnings for iOS C imports. - # These warnings are harmless and don't affect the generated bindings, - # as the generator only needs to parse Go types, not C implementations. - build: - summary: Creates a build of the application for iOS - deps: - - task: generate:ios:overlay - - task: generate:ios:xcode - - task: common:go:mod:tidy - - task: generate:ios:bindings - vars: - BUILD_FLAGS: - ref: .BUILD_FLAGS - - task: common:build:frontend - vars: - BUILD_FLAGS: - ref: .BUILD_FLAGS - PRODUCTION: - ref: .PRODUCTION - - task: common:generate:icons - cmds: - - echo "Building iOS app {{.APP_NAME}}..." - - go build -buildmode=c-archive -overlay build/ios/xcode/overlay.json {{.BUILD_FLAGS}} -o {{.OUTPUT}}.a - vars: - BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production,ios -trimpath -buildvcs=false -ldflags="-w -s"{{else}}-tags ios,debug -buildvcs=false -gcflags=all="-l"{{end}}' - DEFAULT_OUTPUT: '{{.BIN_DIR}}/{{.APP_NAME}}' - OUTPUT: '{{ .OUTPUT | default .DEFAULT_OUTPUT }}' - SDK_PATH: - sh: xcrun --sdk iphonesimulator --show-sdk-path - env: - GOOS: ios - CGO_ENABLED: 1 - GOARCH: '{{.ARCH | default "arm64"}}' - PRODUCTION: '{{.PRODUCTION | default "false"}}' - CGO_CFLAGS: '-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0' - CGO_LDFLAGS: '-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator' - - compile:objc: - summary: Compile Objective-C iOS wrapper - vars: - SDK_PATH: - sh: xcrun --sdk iphonesimulator --show-sdk-path - cmds: - - xcrun -sdk iphonesimulator clang -target arm64-apple-ios15.0-simulator -isysroot {{.SDK_PATH}} -framework Foundation -framework UIKit -framework WebKit -o {{.BIN_DIR}}/{{.APP_NAME}} build/ios/main.m - - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}" - - package: - summary: Packages a production build of the application into a `.app` bundle - deps: - - task: build - vars: - PRODUCTION: "true" - cmds: - - task: create:app:bundle - - create:app:bundle: - summary: Creates an iOS `.app` bundle - cmds: - - rm -rf "{{.BIN_DIR}}/{{.APP_NAME}}.app" - - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.app" - - cp "{{.BIN_DIR}}/{{.APP_NAME}}" "{{.BIN_DIR}}/{{.APP_NAME}}.app/" - - cp build/ios/Info.plist "{{.BIN_DIR}}/{{.APP_NAME}}.app/" - - | - # Compile asset catalog and embed icons in the app bundle - APP_BUNDLE="{{.BIN_DIR}}/{{.APP_NAME}}.app" - AC_IN="build/ios/xcode/main/Assets.xcassets" - if [ -d "$AC_IN" ]; then - TMP_AC=$(mktemp -d) - xcrun actool \ - --compile "$TMP_AC" \ - --app-icon AppIcon \ - --platform iphonesimulator \ - --minimum-deployment-target 15.0 \ - --product-type com.apple.product-type.application \ - --target-device iphone \ - --target-device ipad \ - --output-partial-info-plist "$APP_BUNDLE/assetcatalog_generated_info.plist" \ - "$AC_IN" - if [ -f "$TMP_AC/Assets.car" ]; then - cp -f "$TMP_AC/Assets.car" "$APP_BUNDLE/Assets.car" - fi - rm -rf "$TMP_AC" - if [ -f "$APP_BUNDLE/assetcatalog_generated_info.plist" ]; then - /usr/libexec/PlistBuddy -c "Merge $APP_BUNDLE/assetcatalog_generated_info.plist" "$APP_BUNDLE/Info.plist" || true - fi - fi - - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.app" - - deploy-simulator: - summary: Deploy to iOS Simulator - deps: [package] - cmds: - - xcrun simctl terminate booted {{.BUNDLE_ID}} 2>/dev/null || true - - xcrun simctl uninstall booted {{.BUNDLE_ID}} 2>/dev/null || true - - xcrun simctl install booted "{{.BIN_DIR}}/{{.APP_NAME}}.app" - - xcrun simctl launch booted {{.BUNDLE_ID}} - - compile:ios: - summary: Compile the iOS executable from Go archive and main.m - deps: - - task: build - vars: - SDK_PATH: - sh: xcrun --sdk iphonesimulator --show-sdk-path - cmds: - - | - MAIN_M=build/ios/xcode/main/main.m - if [ ! -f "$MAIN_M" ]; then - MAIN_M=build/ios/main.m - fi - xcrun -sdk iphonesimulator clang \ - -target arm64-apple-ios15.0-simulator \ - -isysroot {{.SDK_PATH}} \ - -framework Foundation -framework UIKit -framework WebKit \ - -framework Security -framework CoreFoundation \ - -lresolv \ - -o "{{.BIN_DIR}}/{{.APP_NAME | lower}}" \ - "$MAIN_M" "{{.BIN_DIR}}/{{.APP_NAME}}.a" - - generate:ios:bindings: - internal: true - summary: Generates bindings for iOS with proper CGO flags - sources: - - "**/*.go" - - go.mod - - go.sum - generates: - - frontend/bindings/**/* - vars: - SDK_PATH: - sh: xcrun --sdk iphonesimulator --show-sdk-path - cmds: - - wails3 generate bindings -f '{{.BUILD_FLAGS}}' -clean=true - env: - GOOS: ios - CGO_ENABLED: 1 - GOARCH: '{{.ARCH | default "arm64"}}' - CGO_CFLAGS: '-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0' - CGO_LDFLAGS: '-isysroot {{.SDK_PATH}} -target arm64-apple-ios15.0-simulator' - - ensure-simulator: - internal: true - summary: Ensure iOS Simulator is running and booted - silent: true - cmds: - - | - if ! xcrun simctl list devices booted | grep -q "Booted"; then - echo "Starting iOS Simulator..." - # Get first available iPhone device - DEVICE_ID=$(xcrun simctl list devices available | grep "iPhone" | head -1 | grep -o "[A-F0-9-]\{36\}" || true) - if [ -z "$DEVICE_ID" ]; then - echo "No iPhone simulator found. Creating one..." - RUNTIME=$(xcrun simctl list runtimes | grep iOS | tail -1 | awk '{print $NF}') - DEVICE_ID=$(xcrun simctl create "iPhone 15 Pro" "iPhone 15 Pro" "$RUNTIME") - fi - # Boot the device - echo "Booting device $DEVICE_ID..." - xcrun simctl boot "$DEVICE_ID" 2>/dev/null || true - # Open Simulator app - open -a Simulator - # Wait for boot (max 30 seconds) - for i in {1..30}; do - if xcrun simctl list devices booted | grep -q "Booted"; then - echo "Simulator booted successfully" - break - fi - sleep 1 - done - # Final check - if ! xcrun simctl list devices booted | grep -q "Booted"; then - echo "Failed to boot simulator after 30 seconds" - exit 1 - fi - fi - preconditions: - - sh: command -v xcrun - msg: "xcrun not found. Please run 'wails3 task ios:install:deps' to install iOS development dependencies" - - generate:ios:overlay: - internal: true - summary: Generate Go build overlay and iOS shim - sources: - - build/config.yml - generates: - - build/ios/xcode/overlay.json - - build/ios/xcode/gen/main_ios.gen.go - cmds: - - wails3 ios overlay:gen -out build/ios/xcode/overlay.json -config build/config.yml - - generate:ios:xcode: - internal: true - summary: Generate iOS Xcode project structure and assets - sources: - - build/config.yml - - build/appicon.png - generates: - - build/ios/xcode/main/main.m - - build/ios/xcode/main/Assets.xcassets/**/* - - build/ios/xcode/project.pbxproj - cmds: - - wails3 ios xcode:gen -outdir build/ios/xcode -config build/config.yml - - run: - summary: Run the application in iOS Simulator - deps: - - task: ensure-simulator - - task: compile:ios - cmds: - - rm -rf "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app" - - mkdir -p "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app" - - cp "{{.BIN_DIR}}/{{.APP_NAME | lower}}" "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/{{.APP_NAME | lower}}" - - cp build/ios/Info.dev.plist "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app/Info.plist" - - | - # Compile asset catalog and embed icons for dev bundle - APP_BUNDLE="{{.BIN_DIR}}/{{.APP_NAME}}.dev.app" - AC_IN="build/ios/xcode/main/Assets.xcassets" - if [ -d "$AC_IN" ]; then - TMP_AC=$(mktemp -d) - xcrun actool \ - --compile "$TMP_AC" \ - --app-icon AppIcon \ - --platform iphonesimulator \ - --minimum-deployment-target 15.0 \ - --product-type com.apple.product-type.application \ - --target-device iphone \ - --target-device ipad \ - --output-partial-info-plist "$APP_BUNDLE/assetcatalog_generated_info.plist" \ - "$AC_IN" - if [ -f "$TMP_AC/Assets.car" ]; then - cp -f "$TMP_AC/Assets.car" "$APP_BUNDLE/Assets.car" - fi - rm -rf "$TMP_AC" - if [ -f "$APP_BUNDLE/assetcatalog_generated_info.plist" ]; then - /usr/libexec/PlistBuddy -c "Merge $APP_BUNDLE/assetcatalog_generated_info.plist" "$APP_BUNDLE/Info.plist" || true - fi - fi - - codesign --force --sign - "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app" - - xcrun simctl terminate booted "com.wails.{{.APP_NAME | lower}}.dev" 2>/dev/null || true - - xcrun simctl uninstall booted "com.wails.{{.APP_NAME | lower}}.dev" 2>/dev/null || true - - xcrun simctl install booted "{{.BIN_DIR}}/{{.APP_NAME}}.dev.app" - - xcrun simctl launch booted "com.wails.{{.APP_NAME | lower}}.dev" - - xcode: - summary: Open the generated Xcode project for this app - cmds: - - task: generate:ios:xcode - - open build/ios/xcode/main.xcodeproj - - logs: - summary: Stream iOS Simulator logs filtered to this app - cmds: - - | - xcrun simctl spawn booted log stream \ - --level debug \ - --style compact \ - --predicate 'senderImagePath CONTAINS[c] "{{.APP_NAME | lower}}.app/" OR composedMessage CONTAINS[c] "{{.APP_NAME | lower}}" OR eventMessage CONTAINS[c] "{{.APP_NAME | lower}}" OR process == "{{.APP_NAME | lower}}" OR category CONTAINS[c] "{{.APP_NAME | lower}}"' - - logs:dev: - summary: Stream logs for the dev bundle (used by `task ios:run`) - cmds: - - | - xcrun simctl spawn booted log stream \ - --level debug \ - --style compact \ - --predicate 'senderImagePath CONTAINS[c] ".dev.app/" OR subsystem == "com.wails.{{.APP_NAME | lower}}.dev" OR process == "{{.APP_NAME | lower}}"' - - logs:wide: - summary: Wide log stream to help discover the exact process/bundle identifiers - cmds: - - | - xcrun simctl spawn booted log stream \ - --level debug \ - --style compact \ - --predicate 'senderImagePath CONTAINS[c] ".app/"' \ No newline at end of file diff --git a/build/ios/app_options_default.go b/build/ios/app_options_default.go deleted file mode 100644 index 04e4f1b..0000000 --- a/build/ios/app_options_default.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !ios - -package main - -import "github.com/wailsapp/wails/v3/pkg/application" - -// modifyOptionsForIOS is a no-op on non-iOS platforms -func modifyOptionsForIOS(opts *application.Options) { - // No modifications needed for non-iOS platforms -} \ No newline at end of file diff --git a/build/ios/app_options_ios.go b/build/ios/app_options_ios.go deleted file mode 100644 index 8f6ac31..0000000 --- a/build/ios/app_options_ios.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build ios - -package main - -import "github.com/wailsapp/wails/v3/pkg/application" - -// modifyOptionsForIOS adjusts the application options for iOS -func modifyOptionsForIOS(opts *application.Options) { - // Disable signal handlers on iOS to prevent crashes - opts.DisableDefaultSignalHandler = true -} \ No newline at end of file diff --git a/build/ios/build.sh b/build/ios/build.sh deleted file mode 100644 index 522a7bd..0000000 --- a/build/ios/build.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -set -e - -# Build configuration -APP_NAME="mesh-drop" -BUNDLE_ID="com.example.meshdrop" -VERSION="0.1.0" -BUILD_NUMBER="0.1.0" -BUILD_DIR="build/ios" -TARGET="simulator" - -echo "Building iOS app: $APP_NAME" -echo "Bundle ID: $BUNDLE_ID" -echo "Version: $VERSION ($BUILD_NUMBER)" -echo "Target: $TARGET" - -# Ensure build directory exists -mkdir -p "$BUILD_DIR" - -# Determine SDK and target architecture -if [ "$TARGET" = "simulator" ]; then - SDK="iphonesimulator" - ARCH="arm64-apple-ios15.0-simulator" -elif [ "$TARGET" = "device" ]; then - SDK="iphoneos" - ARCH="arm64-apple-ios15.0" -else - echo "Unknown target: $TARGET" - exit 1 -fi - -# Get SDK path -SDK_PATH=$(xcrun --sdk $SDK --show-sdk-path) - -# Compile the application -echo "Compiling with SDK: $SDK" -xcrun -sdk $SDK clang \ - -target $ARCH \ - -isysroot "$SDK_PATH" \ - -framework Foundation \ - -framework UIKit \ - -framework WebKit \ - -framework CoreGraphics \ - -o "$BUILD_DIR/$APP_NAME" \ - "$BUILD_DIR/main.m" - -# Create app bundle -echo "Creating app bundle..." -APP_BUNDLE="$BUILD_DIR/$APP_NAME.app" -rm -rf "$APP_BUNDLE" -mkdir -p "$APP_BUNDLE" - -# Move executable -mv "$BUILD_DIR/$APP_NAME" "$APP_BUNDLE/" - -# Copy Info.plist -cp "$BUILD_DIR/Info.plist" "$APP_BUNDLE/" - -# Sign the app -echo "Signing app..." -codesign --force --sign - "$APP_BUNDLE" - -echo "Build complete: $APP_BUNDLE" - -# Deploy to simulator if requested -if [ "$TARGET" = "simulator" ]; then - echo "Deploying to simulator..." - xcrun simctl terminate booted "$BUNDLE_ID" 2>/dev/null || true - xcrun simctl install booted "$APP_BUNDLE" - xcrun simctl launch booted "$BUNDLE_ID" - echo "App launched on simulator" -fi \ No newline at end of file diff --git a/build/ios/entitlements.plist b/build/ios/entitlements.plist deleted file mode 100644 index cc5d958..0000000 --- a/build/ios/entitlements.plist +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - get-task-allow - - - - com.apple.security.app-sandbox - - - - com.apple.security.network.client - - - - com.apple.security.files.user-selected.read-only - - - \ No newline at end of file diff --git a/build/ios/icon.png b/build/ios/icon.png deleted file mode 100644 index be7d591..0000000 --- a/build/ios/icon.png +++ /dev/null @@ -1,3 +0,0 @@ -# iOS Icon Placeholder -# This file should be replaced with the actual app icon (1024x1024 PNG) -# The build process will generate all required icon sizes from this base icon \ No newline at end of file diff --git a/build/ios/main.m b/build/ios/main.m deleted file mode 100644 index 366767a..0000000 --- a/build/ios/main.m +++ /dev/null @@ -1,23 +0,0 @@ -//go:build ios -// Minimal bootstrap: delegate comes from Go archive (WailsAppDelegate) -#import -#include - -// External Go initialization function from the c-archive (declare before use) -extern void WailsIOSMain(); - -int main(int argc, char * argv[]) { - @autoreleasepool { - // Disable buffering so stdout/stderr from Go log.Printf flush immediately - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); - - // Start Go runtime on a background queue to avoid blocking main thread/UI - dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{ - WailsIOSMain(); - }); - - // Run UIApplicationMain using WailsAppDelegate provided by the Go archive - return UIApplicationMain(argc, argv, nil, @"WailsAppDelegate"); - } -} \ No newline at end of file diff --git a/build/ios/main_ios.go b/build/ios/main_ios.go deleted file mode 100644 index b75a403..0000000 --- a/build/ios/main_ios.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build ios - -package main - -import ( - "C" -) - -// For iOS builds, we need to export a function that can be called from Objective-C -// This wrapper allows us to keep the original main.go unmodified - -//export WailsIOSMain -func WailsIOSMain() { - // DO NOT lock the goroutine to the current OS thread on iOS! - // This causes signal handling issues: - // "signal 16 received on thread with no signal stack" - // "fatal error: non-Go code disabled sigaltstack" - // iOS apps run in a sandboxed environment where the Go runtime's - // signal handling doesn't work the same way as desktop platforms. - - // Call the actual main function from main.go - // This ensures all the user's code is executed - main() -} \ No newline at end of file diff --git a/build/ios/project.pbxproj b/build/ios/project.pbxproj deleted file mode 100644 index d2bf1c2..0000000 --- a/build/ios/project.pbxproj +++ /dev/null @@ -1,222 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = {}; - objectVersion = 56; - objects = { - -/* Begin PBXBuildFile section */ - C0DEBEEF0000000000000001 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000002 /* main.m */; }; - C0DEBEEF00000000000000F1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000101 /* UIKit.framework */; }; - C0DEBEEF00000000000000F2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000102 /* Foundation.framework */; }; - C0DEBEEF00000000000000F3 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000103 /* WebKit.framework */; }; - C0DEBEEF00000000000000F4 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000104 /* Security.framework */; }; - C0DEBEEF00000000000000F5 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000105 /* CoreFoundation.framework */; }; - C0DEBEEF00000000000000F6 /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000106 /* libresolv.tbd */; }; - C0DEBEEF00000000000000F7 /* My Product.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0DEBEEF0000000000000107 /* My Product.a */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - C0DEBEEF0000000000000002 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - C0DEBEEF0000000000000003 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C0DEBEEF0000000000000004 /* My Product.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "My Product.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - C0DEBEEF0000000000000101 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000102 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000103 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000104 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000105 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000106 /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.text-based-dylib-definition; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; }; - C0DEBEEF0000000000000107 /* My Product.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "My Product.a"; path = ../../../bin/My Product.a; sourceTree = SOURCE_ROOT; }; -/* End PBXFileReference section */ - -/* Begin PBXGroup section */ - C0DEBEEF0000000000000010 = { - isa = PBXGroup; - children = ( - C0DEBEEF0000000000000020 /* Products */, - C0DEBEEF0000000000000045 /* Frameworks */, - C0DEBEEF0000000000000030 /* main */, - ); - sourceTree = ""; - }; - C0DEBEEF0000000000000020 /* Products */ = { - isa = PBXGroup; - children = ( - C0DEBEEF0000000000000004 /* My Product.app */, - ); - name = Products; - sourceTree = ""; - }; - C0DEBEEF0000000000000030 /* main */ = { - isa = PBXGroup; - children = ( - C0DEBEEF0000000000000002 /* main.m */, - C0DEBEEF0000000000000003 /* Info.plist */, - ); - path = main; - sourceTree = SOURCE_ROOT; - }; - C0DEBEEF0000000000000045 /* Frameworks */ = { - isa = PBXGroup; - children = ( - C0DEBEEF0000000000000101 /* UIKit.framework */, - C0DEBEEF0000000000000102 /* Foundation.framework */, - C0DEBEEF0000000000000103 /* WebKit.framework */, - C0DEBEEF0000000000000104 /* Security.framework */, - C0DEBEEF0000000000000105 /* CoreFoundation.framework */, - C0DEBEEF0000000000000106 /* libresolv.tbd */, - C0DEBEEF0000000000000107 /* My Product.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - C0DEBEEF0000000000000040 /* My Product */ = { - isa = PBXNativeTarget; - buildConfigurationList = C0DEBEEF0000000000000070 /* Build configuration list for PBXNativeTarget "My Product" */; - buildPhases = ( - C0DEBEEF0000000000000055 /* Prebuild: Wails Go Archive */, - C0DEBEEF0000000000000050 /* Sources */, - C0DEBEEF0000000000000056 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "My Product"; - productName = "My Product"; - productReference = C0DEBEEF0000000000000004 /* My Product.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - C0DEBEEF0000000000000060 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1500; - ORGANIZATIONNAME = "My Company"; - TargetAttributes = { - C0DEBEEF0000000000000040 = { - CreatedOnToolsVersion = 15.0; - }; - }; - }; - buildConfigurationList = C0DEBEEF0000000000000080 /* Build configuration list for PBXProject "main" */; - compatibilityVersion = "Xcode 15.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = C0DEBEEF0000000000000010; - productRefGroup = C0DEBEEF0000000000000020 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - C0DEBEEF0000000000000040 /* My Product */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXFrameworksBuildPhase section */ - C0DEBEEF0000000000000056 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C0DEBEEF00000000000000F7 /* My Product.a in Frameworks */, - C0DEBEEF00000000000000F1 /* UIKit.framework in Frameworks */, - C0DEBEEF00000000000000F2 /* Foundation.framework in Frameworks */, - C0DEBEEF00000000000000F3 /* WebKit.framework in Frameworks */, - C0DEBEEF00000000000000F4 /* Security.framework in Frameworks */, - C0DEBEEF00000000000000F5 /* CoreFoundation.framework in Frameworks */, - C0DEBEEF00000000000000F6 /* libresolv.tbd in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C0DEBEEF0000000000000055 /* Prebuild: Wails Go Archive */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Prebuild: Wails Go Archive"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -e\nAPP_ROOT=\"${PROJECT_DIR}/../../..\"\nSDK_PATH=$(xcrun --sdk iphonesimulator --show-sdk-path)\nexport GOOS=ios\nexport GOARCH=arm64\nexport CGO_ENABLED=1\nexport CGO_CFLAGS=\"-isysroot ${SDK_PATH} -target arm64-apple-ios15.0-simulator -mios-simulator-version-min=15.0\"\nexport CGO_LDFLAGS=\"-isysroot ${SDK_PATH} -target arm64-apple-ios15.0-simulator\"\ncd \"${APP_ROOT}\"\n# Ensure overlay exists\nif [ ! -f build/ios/xcode/overlay.json ]; then\n wails3 ios overlay:gen -out build/ios/xcode/overlay.json -config build/config.yml || true\nfi\n# Build Go c-archive if missing or older than sources\nif [ ! -f bin/My Product.a ]; then\n echo \"Building Go c-archive...\"\n go build -buildmode=c-archive -overlay build/ios/xcode/overlay.json -o bin/My Product.a\nfi\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - C0DEBEEF0000000000000050 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C0DEBEEF0000000000000001 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - C0DEBEEF0000000000000090 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - INFOPLIST_FILE = main/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - PRODUCT_BUNDLE_IDENTIFIER = "com.example.meshdrop"; - PRODUCT_NAME = "My Product"; - CODE_SIGNING_ALLOWED = NO; - SDKROOT = iphonesimulator; - }; - name = Debug; - }; - C0DEBEEF00000000000000A0 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - INFOPLIST_FILE = main/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; - PRODUCT_BUNDLE_IDENTIFIER = "com.example.meshdrop"; - PRODUCT_NAME = "My Product"; - CODE_SIGNING_ALLOWED = NO; - SDKROOT = iphonesimulator; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C0DEBEEF0000000000000070 /* Build configuration list for PBXNativeTarget "My Product" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C0DEBEEF0000000000000090 /* Debug */, - C0DEBEEF00000000000000A0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - C0DEBEEF0000000000000080 /* Build configuration list for PBXProject "main" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C0DEBEEF0000000000000090 /* Debug */, - C0DEBEEF00000000000000A0 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; -/* End XCConfigurationList section */ - }; - rootObject = C0DEBEEF0000000000000060 /* Project object */; -} diff --git a/build/ios/scripts/deps/install_deps.go b/build/ios/scripts/deps/install_deps.go deleted file mode 100644 index 88ed47a..0000000 --- a/build/ios/scripts/deps/install_deps.go +++ /dev/null @@ -1,319 +0,0 @@ -// install_deps.go - iOS development dependency checker -// This script checks for required iOS development tools. -// It's designed to be portable across different shells by using Go instead of shell scripts. -// -// Usage: -// go run install_deps.go # Interactive mode -// TASK_FORCE_YES=true go run install_deps.go # Auto-accept prompts -// CI=true go run install_deps.go # CI mode (auto-accept) - -package main - -import ( - "bufio" - "fmt" - "os" - "os/exec" - "strings" -) - -type Dependency struct { - Name string - CheckFunc func() (bool, string) // Returns (success, details) - Required bool - InstallCmd []string - InstallMsg string - SuccessMsg string - FailureMsg string -} - -func main() { - fmt.Println("Checking iOS development dependencies...") - fmt.Println("=" + strings.Repeat("=", 50)) - fmt.Println() - - hasErrors := false - dependencies := []Dependency{ - { - Name: "Xcode", - CheckFunc: func() (bool, string) { - // Check if xcodebuild exists - if !checkCommand([]string{"xcodebuild", "-version"}) { - return false, "" - } - // Get version info - out, err := exec.Command("xcodebuild", "-version").Output() - if err != nil { - return false, "" - } - lines := strings.Split(string(out), "\n") - if len(lines) > 0 { - return true, strings.TrimSpace(lines[0]) - } - return true, "" - }, - Required: true, - InstallMsg: "Please install Xcode from the Mac App Store:\n https://apps.apple.com/app/xcode/id497799835\n Xcode is REQUIRED for iOS development (includes iOS SDKs, simulators, and frameworks)", - SuccessMsg: "✅ Xcode found", - FailureMsg: "❌ Xcode not found (REQUIRED)", - }, - { - Name: "Xcode Developer Path", - CheckFunc: func() (bool, string) { - // Check if xcode-select points to a valid Xcode path - out, err := exec.Command("xcode-select", "-p").Output() - if err != nil { - return false, "xcode-select not configured" - } - path := strings.TrimSpace(string(out)) - - // Check if path exists and is in Xcode.app - if _, err := os.Stat(path); err != nil { - return false, "Invalid Xcode path" - } - - // Verify it's pointing to Xcode.app (not just Command Line Tools) - if !strings.Contains(path, "Xcode.app") { - return false, fmt.Sprintf("Points to %s (should be Xcode.app)", path) - } - - return true, path - }, - Required: true, - InstallCmd: []string{"sudo", "xcode-select", "-s", "/Applications/Xcode.app/Contents/Developer"}, - InstallMsg: "Xcode developer path needs to be configured", - SuccessMsg: "✅ Xcode developer path configured", - FailureMsg: "❌ Xcode developer path not configured correctly", - }, - { - Name: "iOS SDK", - CheckFunc: func() (bool, string) { - // Get the iOS Simulator SDK path - cmd := exec.Command("xcrun", "--sdk", "iphonesimulator", "--show-sdk-path") - output, err := cmd.Output() - if err != nil { - return false, "Cannot find iOS SDK" - } - sdkPath := strings.TrimSpace(string(output)) - - // Check if the SDK path exists - if _, err := os.Stat(sdkPath); err != nil { - return false, "iOS SDK path not found" - } - - // Check for UIKit framework (essential for iOS development) - uikitPath := fmt.Sprintf("%s/System/Library/Frameworks/UIKit.framework", sdkPath) - if _, err := os.Stat(uikitPath); err != nil { - return false, "UIKit.framework not found" - } - - // Get SDK version - versionCmd := exec.Command("xcrun", "--sdk", "iphonesimulator", "--show-sdk-version") - versionOut, _ := versionCmd.Output() - version := strings.TrimSpace(string(versionOut)) - - return true, fmt.Sprintf("iOS %s SDK", version) - }, - Required: true, - InstallMsg: "iOS SDK comes with Xcode. Please ensure Xcode is properly installed.", - SuccessMsg: "✅ iOS SDK found with UIKit framework", - FailureMsg: "❌ iOS SDK not found or incomplete", - }, - { - Name: "iOS Simulator Runtime", - CheckFunc: func() (bool, string) { - if !checkCommand([]string{"xcrun", "simctl", "help"}) { - return false, "" - } - // Check if we can list runtimes - out, err := exec.Command("xcrun", "simctl", "list", "runtimes").Output() - if err != nil { - return false, "Cannot access simulator" - } - // Count iOS runtimes - lines := strings.Split(string(out), "\n") - count := 0 - var versions []string - for _, line := range lines { - if strings.Contains(line, "iOS") && !strings.Contains(line, "unavailable") { - count++ - // Extract version number - if parts := strings.Fields(line); len(parts) > 2 { - for _, part := range parts { - if strings.HasPrefix(part, "(") && strings.HasSuffix(part, ")") { - versions = append(versions, strings.Trim(part, "()")) - break - } - } - } - } - } - if count > 0 { - return true, fmt.Sprintf("%d runtime(s): %s", count, strings.Join(versions, ", ")) - } - return false, "No iOS runtimes installed" - }, - Required: true, - InstallMsg: "iOS Simulator runtimes come with Xcode. You may need to download them:\n Xcode → Settings → Platforms → iOS", - SuccessMsg: "✅ iOS Simulator runtime available", - FailureMsg: "❌ iOS Simulator runtime not available", - }, - } - - // Check each dependency - for _, dep := range dependencies { - success, details := dep.CheckFunc() - if success { - msg := dep.SuccessMsg - if details != "" { - msg = fmt.Sprintf("%s (%s)", dep.SuccessMsg, details) - } - fmt.Println(msg) - } else { - fmt.Println(dep.FailureMsg) - if details != "" { - fmt.Printf(" Details: %s\n", details) - } - if dep.Required { - hasErrors = true - if len(dep.InstallCmd) > 0 { - fmt.Println() - fmt.Println(" " + dep.InstallMsg) - fmt.Printf(" Fix command: %s\n", strings.Join(dep.InstallCmd, " ")) - if promptUser("Do you want to run this command?") { - fmt.Println("Running command...") - cmd := exec.Command(dep.InstallCmd[0], dep.InstallCmd[1:]...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - if err := cmd.Run(); err != nil { - fmt.Printf("Command failed: %v\n", err) - os.Exit(1) - } - fmt.Println("✅ Command completed. Please run this check again.") - } else { - fmt.Printf(" Please run manually: %s\n", strings.Join(dep.InstallCmd, " ")) - } - } else { - fmt.Println(" " + dep.InstallMsg) - } - } - } - } - - // Check for iPhone simulators - fmt.Println() - fmt.Println("Checking for iPhone simulator devices...") - if !checkCommand([]string{"xcrun", "simctl", "list", "devices"}) { - fmt.Println("❌ Cannot check for iPhone simulators") - hasErrors = true - } else { - out, err := exec.Command("xcrun", "simctl", "list", "devices").Output() - if err != nil { - fmt.Println("❌ Failed to list simulator devices") - hasErrors = true - } else if !strings.Contains(string(out), "iPhone") { - fmt.Println("⚠️ No iPhone simulator devices found") - fmt.Println() - - // Get the latest iOS runtime - runtimeOut, err := exec.Command("xcrun", "simctl", "list", "runtimes").Output() - if err != nil { - fmt.Println(" Failed to get iOS runtimes:", err) - } else { - lines := strings.Split(string(runtimeOut), "\n") - var latestRuntime string - for _, line := range lines { - if strings.Contains(line, "iOS") && !strings.Contains(line, "unavailable") { - // Extract runtime identifier - parts := strings.Fields(line) - if len(parts) > 0 { - latestRuntime = parts[len(parts)-1] - } - } - } - - if latestRuntime == "" { - fmt.Println(" No iOS runtime found. Please install iOS simulators in Xcode:") - fmt.Println(" Xcode → Settings → Platforms → iOS") - } else { - fmt.Println(" Would you like to create an iPhone 15 Pro simulator?") - createCmd := []string{"xcrun", "simctl", "create", "iPhone 15 Pro", "iPhone 15 Pro", latestRuntime} - fmt.Printf(" Command: %s\n", strings.Join(createCmd, " ")) - if promptUser("Create simulator?") { - cmd := exec.Command(createCmd[0], createCmd[1:]...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - fmt.Printf(" Failed to create simulator: %v\n", err) - } else { - fmt.Println(" ✅ iPhone 15 Pro simulator created") - } - } else { - fmt.Println(" Skipping simulator creation") - fmt.Printf(" Create manually: %s\n", strings.Join(createCmd, " ")) - } - } - } - } else { - // Count iPhone devices - count := 0 - lines := strings.Split(string(out), "\n") - for _, line := range lines { - if strings.Contains(line, "iPhone") && !strings.Contains(line, "unavailable") { - count++ - } - } - fmt.Printf("✅ %d iPhone simulator device(s) available\n", count) - } - } - - // Final summary - fmt.Println() - fmt.Println("=" + strings.Repeat("=", 50)) - if hasErrors { - fmt.Println("❌ Some required dependencies are missing or misconfigured.") - fmt.Println() - fmt.Println("Quick setup guide:") - fmt.Println("1. Install Xcode from Mac App Store (if not installed)") - fmt.Println("2. Open Xcode once and agree to the license") - fmt.Println("3. Install additional components when prompted") - fmt.Println("4. Run: sudo xcode-select -s /Applications/Xcode.app/Contents/Developer") - fmt.Println("5. Download iOS simulators: Xcode → Settings → Platforms → iOS") - fmt.Println("6. Run this check again") - os.Exit(1) - } else { - fmt.Println("✅ All required dependencies are installed!") - fmt.Println(" You're ready for iOS development with Wails!") - } -} - -func checkCommand(args []string) bool { - if len(args) == 0 { - return false - } - cmd := exec.Command(args[0], args[1:]...) - cmd.Stdout = nil - cmd.Stderr = nil - err := cmd.Run() - return err == nil -} - -func promptUser(question string) bool { - // Check if we're in a non-interactive environment - if os.Getenv("CI") != "" || os.Getenv("TASK_FORCE_YES") == "true" { - fmt.Printf("%s [y/N]: y (auto-accepted)\n", question) - return true - } - - reader := bufio.NewReader(os.Stdin) - fmt.Printf("%s [y/N]: ", question) - - response, err := reader.ReadString('\n') - if err != nil { - return false - } - - response = strings.ToLower(strings.TrimSpace(response)) - return response == "y" || response == "yes" -} \ No newline at end of file diff --git a/build/windows/Taskfile.yml b/build/windows/Taskfile.yml index a973981..53dd37b 100644 --- a/build/windows/Taskfile.yml +++ b/build/windows/Taskfile.yml @@ -25,7 +25,7 @@ tasks: DEV: "{{.DEV}}" vars: # Default to CGO_ENABLED=0 if not explicitly set - CGO_ENABLED: '{{.CGO_ENABLED | default "0"}}'--lzma + CGO_ENABLED: '{{.CGO_ENABLED | default "0"}}' build:native: summary: Builds the application using native Go cross-compilation diff --git a/frontend/bindings/mesh-drop/internal/discovery/service.ts b/frontend/bindings/mesh-drop/internal/discovery/service.ts index 7df7db1..0854693 100644 --- a/frontend/bindings/mesh-drop/internal/discovery/service.ts +++ b/frontend/bindings/mesh-drop/internal/discovery/service.ts @@ -13,15 +13,26 @@ export function GetID(): $CancellablePromise { return $Call.ByID(1539451205); } +export function GetLocalIPInSameSubnet(receiverIP: string): $CancellablePromise<[string, boolean]> { + return $Call.ByID(3089425954, receiverIP); +} + +export function GetLocalIPs(): $CancellablePromise<[string[], boolean]> { + return $Call.ByID(2403939179).then(($result: any) => { + $result[0] = $$createType0($result[0]); + return $result; + }); +} + export function GetPeerByIP(ip: string): $CancellablePromise<$models.Peer | null> { return $Call.ByID(1626825408, ip).then(($result: any) => { - return $$createType1($result); + return $$createType2($result); }); } export function GetPeers(): $CancellablePromise<$models.Peer[]> { return $Call.ByID(3041084029).then(($result: any) => { - return $$createType2($result); + return $$createType3($result); }); } @@ -30,6 +41,7 @@ export function Start(): $CancellablePromise { } // Private type creation functions -const $$createType0 = $models.Peer.createFrom; -const $$createType1 = $Create.Nullable($$createType0); -const $$createType2 = $Create.Array($$createType0); +const $$createType0 = $Create.Array($Create.Any); +const $$createType1 = $models.Peer.createFrom; +const $$createType2 = $Create.Nullable($$createType1); +const $$createType3 = $Create.Array($$createType1); diff --git a/frontend/bindings/mesh-drop/internal/transfer/models.ts b/frontend/bindings/mesh-drop/internal/transfer/models.ts index be4c325..856fb6c 100644 --- a/frontend/bindings/mesh-drop/internal/transfer/models.ts +++ b/frontend/bindings/mesh-drop/internal/transfer/models.ts @@ -70,6 +70,11 @@ export class Sender { */ "name": string; + /** + * 发送者 IP + */ + "ip": string; + /** Creates a new Sender instance. */ constructor($$source: Partial = {}) { if (!("id" in $$source)) { @@ -78,6 +83,9 @@ export class Sender { if (!("name" in $$source)) { this["name"] = ""; } + if (!("ip" in $$source)) { + this["ip"] = ""; + } Object.assign(this, $$source); }