diff --git a/.github/workflows/mobile-build.yml b/.github/workflows/mobile-build.yml new file mode 100644 index 00000000..cd6d6e67 --- /dev/null +++ b/.github/workflows/mobile-build.yml @@ -0,0 +1,84 @@ +name: Mobile App CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build-ios: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.2.2 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: aarch64-apple-ios + + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: "frontend/src-tauri -> target" + cache-on-failure: true + + - name: Install dependencies (macOS) + run: | + brew install openssl@3 + + - name: Install frontend dependencies + working-directory: ./frontend + run: bun install + + - name: Setup Xcode + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: latest-stable + + - name: Install Tauri CLI + run: cargo install tauri-cli + + - name: Set up API Key + run: | + mkdir -p ~/.private_keys + echo "${{ secrets.APPLE_API_PRIVATE_KEY }}" | base64 --decode > ~/.private_keys/AuthKey_${{ secrets.APPLE_API_KEY }}.p8 + chmod 600 ~/.private_keys/AuthKey_${{ secrets.APPLE_API_KEY }}.p8 + echo "APPLE_API_KEY_PATH=~/.private_keys/AuthKey_${{ secrets.APPLE_API_KEY }}.p8" >> $GITHUB_ENV + + - name: Build Tauri iOS App + working-directory: ./frontend + run: | + bun tauri ios build --export-method app-store-connect + env: + APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} + APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} + APPLE_API_KEY_PATH: ${{ env.APPLE_API_KEY_PATH }} + APPLE_DEVELOPMENT_TEAM: ${{ secrets.APPLE_TEAM_ID }} + VITE_OPEN_SECRET_API_URL: https://enclave.trymaple.ai + VITE_MAPLE_BILLING_API_URL: https://billing.opensecret.cloud + VITE_CLIENT_ID: ba5a14b5-d915-47b1-b7b1-afda52bc5fc6 + + - name: Upload iOS App + uses: actions/upload-artifact@v4 + with: + name: maple-ios + path: | + frontend/src-tauri/gen/apple/build/arm64/*.ipa + retention-days: 5 + + - name: Submit to TestFlight + run: | + # Find the actual path of the IPA file + IPA_PATH=$(find frontend/src-tauri/gen/apple/build -name "*.ipa" | head -n 1) + echo "Found IPA at: $IPA_PATH" + + xcrun altool --upload-app --type ios \ + --file "$IPA_PATH" \ + --apiKey ${{ secrets.APPLE_API_KEY }} \ + --apiIssuer ${{ secrets.APPLE_API_ISSUER }} \ No newline at end of file diff --git a/frontend/bun.lock b/frontend/bun.lock index 263b675b..c193cedb 100644 --- a/frontend/bun.lock +++ b/frontend/bun.lock @@ -17,9 +17,10 @@ "@radix-ui/react-tooltip": "^1.1.2", "@tanstack/react-query": "^5.56.2", "@tanstack/react-router": "^1.50.1", - "@tauri-apps/api": "^2.0.0", + "@tauri-apps/api": "^2.4.1", "@tauri-apps/plugin-deep-link": "^2.0.0", "@tauri-apps/plugin-opener": "^2.2.6", + "@tauri-apps/plugin-os": "^2.2.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.436.0", @@ -419,6 +420,8 @@ "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.2.6", "", { "dependencies": { "@tauri-apps/api": "^2.0.0" } }, "sha512-bSdkuP71ZQRepPOn8BOEdBKYJQvl6+jb160QtJX/i2H9BF6ZySY/kYljh76N2Ne5fJMQRge7rlKoStYQY5Jq1w=="], + "@tauri-apps/plugin-os": ["@tauri-apps/plugin-os@2.2.1", "", { "dependencies": { "@tauri-apps/api": "^2.0.0" } }, "sha512-cNYpNri2CCc6BaNeB6G/mOtLvg8dFyFQyCUdf2y0K8PIAKGEWdEcu8DECkydU2B+oj4OJihDPD2de5K6cbVl9A=="], + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], "@types/babel__generator": ["@types/babel__generator@7.6.8", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw=="], diff --git a/frontend/package.json b/frontend/package.json index 8020bb90..f8863800 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,9 +29,10 @@ "@radix-ui/react-tooltip": "^1.1.2", "@tanstack/react-query": "^5.56.2", "@tanstack/react-router": "^1.50.1", - "@tauri-apps/api": "^2.0.0", + "@tauri-apps/api": "^2.4.1", "@tauri-apps/plugin-deep-link": "^2.0.0", "@tauri-apps/plugin-opener": "^2.2.6", + "@tauri-apps/plugin-os": "^2.2.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "lucide-react": "^0.436.0", diff --git a/frontend/public/.well-known/apple-app-site-association b/frontend/public/.well-known/apple-app-site-association new file mode 100644 index 00000000..199b35df --- /dev/null +++ b/frontend/public/.well-known/apple-app-site-association @@ -0,0 +1,19 @@ +{ + "applinks": { + "details": [ + { + "appIDs": ["X773Y823TN.cloud.opensecret.maple"], + "components": [ + { + "/": "/auth/*", + "comment": "Matches any URL whose path starts with /auth/" + }, + { + "/": "/desktop-auth/*", + "comment": "Matches any URL whose path starts with /desktop-auth/" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/frontend/src-tauri/Cargo.lock b/frontend/src-tauri/Cargo.lock index f215f6f3..97e0b2ca 100644 --- a/frontend/src-tauri/Cargo.lock +++ b/frontend/src-tauri/Cargo.lock @@ -1426,6 +1426,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7131e57abbde63513e0e6636f76668a1ca9798dcae2df4e283cae9ee83859e" +dependencies = [ + "rustix 1.0.3", + "windows-targets 0.52.6", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2233,6 +2243,7 @@ dependencies = [ "tauri-plugin-dialog", "tauri-plugin-log", "tauri-plugin-opener", + "tauri-plugin-os", "tauri-plugin-updater", "tokio", ] @@ -2703,6 +2714,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_info" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + [[package]] name = "osakit" version = "0.3.1" @@ -4038,6 +4060,15 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -4359,6 +4390,24 @@ dependencies = [ "zbus", ] +[[package]] +name = "tauri-plugin-os" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "424f19432397850c2ddd42aa58078630c15287bbce3866eb1d90e7dbee680637" +dependencies = [ + "gethostname", + "log", + "os_info", + "serde", + "serde_json", + "serialize-to-javascript", + "sys-locale", + "tauri", + "tauri-plugin", + "thiserror 2.0.11", +] + [[package]] name = "tauri-plugin-updater" version = "2.7.0" diff --git a/frontend/src-tauri/Cargo.toml b/frontend/src-tauri/Cargo.toml index 6ed9e624..e324a367 100644 --- a/frontend/src-tauri/Cargo.toml +++ b/frontend/src-tauri/Cargo.toml @@ -28,5 +28,6 @@ tauri-plugin-dialog = "2.2.1" tauri-plugin = "2.1.1" tauri-plugin-deep-link = "2" tauri-plugin-opener = "2" +tauri-plugin-os = "2" tokio = { version = "1.0", features = ["time"] } once_cell = "1.18.0" diff --git a/frontend/src-tauri/gen/apple/.gitignore b/frontend/src-tauri/gen/apple/.gitignore new file mode 100644 index 00000000..6726e2f8 --- /dev/null +++ b/frontend/src-tauri/gen/apple/.gitignore @@ -0,0 +1,3 @@ +xcuserdata/ +build/ +Externals/ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png new file mode 100644 index 00000000..0e763000 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png new file mode 100644 index 00000000..3984e1c6 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png new file mode 100644 index 00000000..3984e1c6 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png new file mode 100644 index 00000000..205c7bea Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png new file mode 100644 index 00000000..85650c3d Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png new file mode 100644 index 00000000..4bd3df7a Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png new file mode 100644 index 00000000..4bd3df7a Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png new file mode 100644 index 00000000..43f5a955 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png new file mode 100644 index 00000000..3984e1c6 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png new file mode 100644 index 00000000..1ff87f5f Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png new file mode 100644 index 00000000..1ff87f5f Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png new file mode 100644 index 00000000..526da678 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png new file mode 100644 index 00000000..a37bc4a2 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png new file mode 100644 index 00000000..526da678 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png new file mode 100644 index 00000000..ba66c2be Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png new file mode 100644 index 00000000..2aa8edbb Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png new file mode 100644 index 00000000..e333cbeb Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png new file mode 100644 index 00000000..eccc2844 Binary files /dev/null and b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png differ diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..90eea7ec --- /dev/null +++ b/frontend/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "AppIcon-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "AppIcon-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "AppIcon-29x29@2x-1.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "AppIcon-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "AppIcon-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "AppIcon-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "AppIcon-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "AppIcon-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "AppIcon-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "AppIcon-20x20@2x-1.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "AppIcon-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "AppIcon-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "AppIcon-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "AppIcon-40x40@2x-1.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "AppIcon-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "AppIcon-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "AppIcon-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "AppIcon-512@2x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/src-tauri/gen/apple/Assets.xcassets/Contents.json b/frontend/src-tauri/gen/apple/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/frontend/src-tauri/gen/apple/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/frontend/src-tauri/gen/apple/ExportOptions.plist b/frontend/src-tauri/gen/apple/ExportOptions.plist new file mode 100644 index 00000000..0428a171 --- /dev/null +++ b/frontend/src-tauri/gen/apple/ExportOptions.plist @@ -0,0 +1,8 @@ + + + + + method + debugging + + diff --git a/frontend/src-tauri/gen/apple/LaunchScreen.storyboard b/frontend/src-tauri/gen/apple/LaunchScreen.storyboard new file mode 100644 index 00000000..dd79351e --- /dev/null +++ b/frontend/src-tauri/gen/apple/LaunchScreen.storyboard @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src-tauri/gen/apple/Podfile b/frontend/src-tauri/gen/apple/Podfile new file mode 100644 index 00000000..98ee0f28 --- /dev/null +++ b/frontend/src-tauri/gen/apple/Podfile @@ -0,0 +1,21 @@ +# Uncomment the next line to define a global platform for your project + +target 'maple_iOS' do +platform :ios, '13.0' + # Pods for maple_iOS +end + +target 'maple_macOS' do +platform :osx, '11.0' + # Pods for maple_macOS +end + +# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET' + config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET' + end + end +end diff --git a/frontend/src-tauri/gen/apple/Sources/maple/bindings/bindings.h b/frontend/src-tauri/gen/apple/Sources/maple/bindings/bindings.h new file mode 100644 index 00000000..51522007 --- /dev/null +++ b/frontend/src-tauri/gen/apple/Sources/maple/bindings/bindings.h @@ -0,0 +1,8 @@ +#pragma once + +namespace ffi { + extern "C" { + void start_app(); + } +} + diff --git a/frontend/src-tauri/gen/apple/Sources/maple/main.mm b/frontend/src-tauri/gen/apple/Sources/maple/main.mm new file mode 100644 index 00000000..7793a9d5 --- /dev/null +++ b/frontend/src-tauri/gen/apple/Sources/maple/main.mm @@ -0,0 +1,6 @@ +#include "bindings/bindings.h" + +int main(int argc, char * argv[]) { + ffi::start_app(); + return 0; +} diff --git a/frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj new file mode 100644 index 00000000..435919c9 --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj @@ -0,0 +1,626 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 0F4AA8C5111094B8D7B033A4 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E996CAD20B045EF299247BEF /* WebKit.framework */; }; + 23D760C25DBAAA96DF52F98C /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAFD3E024B29F57EA0D88AB5 /* MetalKit.framework */; }; + 27222ACBBD95CA356BDB87AB /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BAF092EB33F2B4FDF867E2ED /* QuartzCore.framework */; }; + 46728F6CD07C626A781543FF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 938F41BA03AF7FAB80585A60 /* Security.framework */; }; + 4E14944735CA89389849E430 /* libapp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F27A6FC4AB3E06D481B1E137 /* libapp.a */; }; + 621A96F6B965E600E714FB6C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B0EAFEFF59AA7CFEF57FA63C /* LaunchScreen.storyboard */; }; + 8F9EDB5679AB5E12D6F1E071 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DACD0B6B9FB86AFF47366EB2 /* UIKit.framework */; }; + 90DEA2E2EC5F95784C9D8B00 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 898D6E7ABC92C3B9A7970DAE /* CoreGraphics.framework */; }; + 9F3ED7EA97AFC22E0B4A6EAF /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE20E8A9C4CF149CA9CA485A /* main.mm */; }; + A120CF155DE2B343CEFFB77C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6BF4C7EB12DBD2E253B2741E /* Assets.xcassets */; }; + B79EC8A2A1A869B9F38906ED /* assets in Resources */ = {isa = PBXBuildFile; fileRef = AF5DA3546C7B12BA141E9508 /* assets */; }; + FB98D58EAB479A32F7CA66CA /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C072EB8E1CCC1094712EA7F7 /* Metal.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1094B8CB671809878F533CEC /* lib.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = lib.rs; sourceTree = ""; }; + 19C98BDFCAE8C0B2FE05F13B /* maple_iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = maple_iOS.entitlements; sourceTree = ""; }; + 1DB07799A17353B2E32B65D3 /* Maple.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Maple.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6BF4C7EB12DBD2E253B2741E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7BBAB8D5C4E3D05A4F48B6EA /* bindings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bindings.h; sourceTree = ""; }; + 898D6E7ABC92C3B9A7970DAE /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 938F41BA03AF7FAB80585A60 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + AAFD3E024B29F57EA0D88AB5 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; + AF5DA3546C7B12BA141E9508 /* assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = assets; sourceTree = SOURCE_ROOT; }; + B0EAFEFF59AA7CFEF57FA63C /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + BAF092EB33F2B4FDF867E2ED /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + C072EB8E1CCC1094712EA7F7 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + C0A332F21EB65CD4B83229DF /* main.rs */ = {isa = PBXFileReference; lastKnownFileType = text; path = main.rs; sourceTree = ""; }; + CE20E8A9C4CF149CA9CA485A /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; + D6F6085362AF0C062EDB5810 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + DACD0B6B9FB86AFF47366EB2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + E996CAD20B045EF299247BEF /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; + F27A6FC4AB3E06D481B1E137 /* libapp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libapp.a; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 04F3BEBB04BD927FDC86B255 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4E14944735CA89389849E430 /* libapp.a in Frameworks */, + 90DEA2E2EC5F95784C9D8B00 /* CoreGraphics.framework in Frameworks */, + FB98D58EAB479A32F7CA66CA /* Metal.framework in Frameworks */, + 23D760C25DBAAA96DF52F98C /* MetalKit.framework in Frameworks */, + 27222ACBBD95CA356BDB87AB /* QuartzCore.framework in Frameworks */, + 46728F6CD07C626A781543FF /* Security.framework in Frameworks */, + 8F9EDB5679AB5E12D6F1E071 /* UIKit.framework in Frameworks */, + 0F4AA8C5111094B8D7B033A4 /* WebKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 31943D18956B6AFD5A82AB02 /* maple_iOS */ = { + isa = PBXGroup; + children = ( + D6F6085362AF0C062EDB5810 /* Info.plist */, + 19C98BDFCAE8C0B2FE05F13B /* maple_iOS.entitlements */, + ); + path = maple_iOS; + sourceTree = ""; + }; + 6AE8986BFC081ADF4EF98889 /* Externals */ = { + isa = PBXGroup; + children = ( + ); + path = Externals; + sourceTree = ""; + }; + A278899D6905367F60E00F01 /* Sources */ = { + isa = PBXGroup; + children = ( + E5992A2C52DE443515252068 /* maple */, + ); + path = Sources; + sourceTree = ""; + }; + B58B2AB62FA5D8F41C3A031C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 898D6E7ABC92C3B9A7970DAE /* CoreGraphics.framework */, + F27A6FC4AB3E06D481B1E137 /* libapp.a */, + C072EB8E1CCC1094712EA7F7 /* Metal.framework */, + AAFD3E024B29F57EA0D88AB5 /* MetalKit.framework */, + BAF092EB33F2B4FDF867E2ED /* QuartzCore.framework */, + 938F41BA03AF7FAB80585A60 /* Security.framework */, + DACD0B6B9FB86AFF47366EB2 /* UIKit.framework */, + E996CAD20B045EF299247BEF /* WebKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + C312B5C9A1506139452E194B /* Products */ = { + isa = PBXGroup; + children = ( + 1DB07799A17353B2E32B65D3 /* Maple.app */, + ); + name = Products; + sourceTree = ""; + }; + D3140E092D76240F6A157CCE = { + isa = PBXGroup; + children = ( + AF5DA3546C7B12BA141E9508 /* assets */, + 6BF4C7EB12DBD2E253B2741E /* Assets.xcassets */, + B0EAFEFF59AA7CFEF57FA63C /* LaunchScreen.storyboard */, + 6AE8986BFC081ADF4EF98889 /* Externals */, + 31943D18956B6AFD5A82AB02 /* maple_iOS */, + A278899D6905367F60E00F01 /* Sources */, + FF31B258F4FE6CC5B57B4FB8 /* src */, + B58B2AB62FA5D8F41C3A031C /* Frameworks */, + C312B5C9A1506139452E194B /* Products */, + ); + sourceTree = ""; + }; + E5992A2C52DE443515252068 /* maple */ = { + isa = PBXGroup; + children = ( + CE20E8A9C4CF149CA9CA485A /* main.mm */, + F9E1B0C7AF484C8F6312F2C8 /* bindings */, + ); + path = maple; + sourceTree = ""; + }; + F9E1B0C7AF484C8F6312F2C8 /* bindings */ = { + isa = PBXGroup; + children = ( + 7BBAB8D5C4E3D05A4F48B6EA /* bindings.h */, + ); + path = bindings; + sourceTree = ""; + }; + FF31B258F4FE6CC5B57B4FB8 /* src */ = { + isa = PBXGroup; + children = ( + 1094B8CB671809878F533CEC /* lib.rs */, + C0A332F21EB65CD4B83229DF /* main.rs */, + ); + name = src; + path = ../../src; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 745812EBA5246F9E4CEE1574 /* maple_iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 27939507295816FC37580B40 /* Build configuration list for PBXNativeTarget "maple_iOS" */; + buildPhases = ( + 88FF8D973FB9516A2A98CD39 /* Build Rust Code */, + 6D9F08407F22BE108C77276C /* Sources */, + 25104604B2C2A81B04543E68 /* Resources */, + 04F3BEBB04BD927FDC86B255 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = maple_iOS; + productName = maple_iOS; + productReference = 1DB07799A17353B2E32B65D3 /* Maple.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + EAA0B11A781B9CD753D1399F /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1430; + }; + buildConfigurationList = 2FA6FD4DEFE659C96AAB5E5D /* Build configuration list for PBXProject "maple" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = D3140E092D76240F6A157CCE; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 745812EBA5246F9E4CEE1574 /* maple_iOS */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 25104604B2C2A81B04543E68 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A120CF155DE2B343CEFFB77C /* Assets.xcassets in Resources */, + 621A96F6B965E600E714FB6C /* LaunchScreen.storyboard in Resources */, + B79EC8A2A1A869B9F38906ED /* assets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 88FF8D973FB9516A2A98CD39 /* Build Rust Code */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Build Rust Code"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a", + "$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a", + "$(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "bun tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths \"${FRAMEWORK_SEARCH_PATHS:?}\" --header-search-paths \"${HEADER_SEARCH_PATHS:?}\" --gcc-preprocessor-definitions \"${GCC_PREPROCESSOR_DEFINITIONS:-}\" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?}"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6D9F08407F22BE108C77276C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9F3ED7EA97AFC22E0B4A6EAF /* main.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DE1BEC252AAEF735A07CA8B /* debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = ( + arm64, + "arm64-sim", + ); + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = maple_iOS/maple_iOS.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = X773Y823TN; + ENABLE_BITCODE = NO; + "EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64"; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\".\"", + ); + INFOPLIST_FILE = maple_iOS/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=x86_64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + PRODUCT_BUNDLE_IDENTIFIER = cloud.opensecret.maple; + PRODUCT_NAME = Maple; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 arm64-sim"; + }; + name = debug; + }; + 1E8FE8E2E3063C3FDCD3B5D1 /* debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = debug; + }; + 94ECC2E044AA76E166E0866E /* release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = release; + }; + B90C9BEF4885680BFA986CD2 /* release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = ( + arm64, + "arm64-sim", + ); + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = maple_iOS/maple_iOS.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = X773Y823TN; + ENABLE_BITCODE = NO; + "EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64"; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\".\"", + ); + INFOPLIST_FILE = maple_iOS/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=x86_64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + PRODUCT_BUNDLE_IDENTIFIER = cloud.opensecret.maple; + PRODUCT_NAME = Maple; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 arm64-sim"; + }; + name = release; + }; + EA2669D02DADAA11005A7F4B /* local */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "DEBUG=1", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = local; + }; + EA2669D12DADAA11005A7F4B /* local */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ARCHS = ( + arm64, + "arm64-sim", + ); + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_ENTITLEMENTS = maple_iOS/maple_iOS.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = X773Y823TN; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = X773Y823TN; + ENABLE_BITCODE = NO; + "EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64"; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\".\"", + ); + INFOPLIST_FILE = maple_iOS/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=arm64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + "LIBRARY_SEARCH_PATHS[arch=x86_64]" = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION)", + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", + ); + PRODUCT_BUNDLE_IDENTIFIER = cloud.opensecret.maple; + PRODUCT_NAME = Maple; + PROVISIONING_PROFILE_SPECIFIER = "86059ea7-ae8e-44af-8a58-b2ab7c78d299"; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "86059ea7-ae8e-44af-8a58-b2ab7c78d299"; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALID_ARCHS = "arm64 arm64-sim"; + }; + name = local; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 27939507295816FC37580B40 /* Build configuration list for PBXNativeTarget "maple_iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DE1BEC252AAEF735A07CA8B /* debug */, + EA2669D12DADAA11005A7F4B /* local */, + B90C9BEF4885680BFA986CD2 /* release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = debug; + }; + 2FA6FD4DEFE659C96AAB5E5D /* Build configuration list for PBXProject "maple" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1E8FE8E2E3063C3FDCD3B5D1 /* debug */, + EA2669D02DADAA11005A7F4B /* local */, + 94ECC2E044AA76E166E0866E /* release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = debug; + }; +/* End XCConfigurationList section */ + }; + rootObject = EAA0B11A781B9CD753D1399F /* Project object */; +} diff --git a/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..ac90d5ac --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,10 @@ + + + + + BuildSystemType + Original + DisableBuildSystemDeprecationDiagnostic + + + diff --git a/frontend/src-tauri/gen/apple/maple.xcodeproj/xcshareddata/xcschemes/maple_iOS.xcscheme b/frontend/src-tauri/gen/apple/maple.xcodeproj/xcshareddata/xcschemes/maple_iOS.xcscheme new file mode 100644 index 00000000..273d1b79 --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple.xcodeproj/xcshareddata/xcschemes/maple_iOS.xcscheme @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src-tauri/gen/apple/maple_iOS/Info.plist b/frontend/src-tauri/gen/apple/maple_iOS/Info.plist new file mode 100644 index 00000000..2e8e1484 --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple_iOS/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0.4 + CFBundleVersion + 1.0.4 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + arm64 + metal + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CFBundleURLTypes + + + CFBundleURLName + cloud.opensecret.maple + CFBundleURLSchemes + + cloud.opensecret.maple + + + + LSApplicationQueriesSchemes + + https + http + + ITSAppUsesNonExemptEncryption + + + \ No newline at end of file diff --git a/frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlements b/frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlements new file mode 100644 index 00000000..b026fc17 --- /dev/null +++ b/frontend/src-tauri/gen/apple/maple_iOS/maple_iOS.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.associated-domains + + applinks:trymaple.ai + + + \ No newline at end of file diff --git a/frontend/src-tauri/gen/apple/project.yml b/frontend/src-tauri/gen/apple/project.yml new file mode 100644 index 00000000..30f0f1ad --- /dev/null +++ b/frontend/src-tauri/gen/apple/project.yml @@ -0,0 +1,91 @@ +name: maple +options: + bundleIdPrefix: cloud.opensecret.maple + deploymentTarget: + iOS: 13.0 +fileGroups: [../../src] +configs: + debug: debug + release: release +settingGroups: + app: + base: + PRODUCT_NAME: Maple + PRODUCT_BUNDLE_IDENTIFIER: cloud.opensecret.maple +targetTemplates: + app: + type: application + sources: + - path: Sources + scheme: + environmentVariables: + RUST_BACKTRACE: full + RUST_LOG: info + settings: + groups: [app] +targets: + maple_iOS: + type: application + platform: iOS + sources: + - path: Sources + - path: Assets.xcassets + - path: Externals + - path: maple_iOS + - path: assets + buildPhase: resources + type: folder + - path: LaunchScreen.storyboard + info: + path: maple_iOS/Info.plist + properties: + LSRequiresIPhoneOS: true + UILaunchStoryboardName: LaunchScreen + UIRequiredDeviceCapabilities: [arm64, metal] + UISupportedInterfaceOrientations: + - UIInterfaceOrientationPortrait + - UIInterfaceOrientationLandscapeLeft + - UIInterfaceOrientationLandscapeRight + UISupportedInterfaceOrientations~ipad: + - UIInterfaceOrientationPortrait + - UIInterfaceOrientationPortraitUpsideDown + - UIInterfaceOrientationLandscapeLeft + - UIInterfaceOrientationLandscapeRight + CFBundleShortVersionString: 1.0.2 + CFBundleVersion: 1.0.2 + entitlements: + path: maple_iOS/maple_iOS.entitlements + scheme: + environmentVariables: + RUST_BACKTRACE: full + RUST_LOG: info + settings: + base: + ENABLE_BITCODE: false + ARCHS: [arm64, arm64-sim] + VALID_ARCHS: arm64 arm64-sim + LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) + LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) + LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true + EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64 + EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64 + groups: [app] + dependencies: + - framework: libapp.a + embed: false + - sdk: CoreGraphics.framework + - sdk: Metal.framework + - sdk: MetalKit.framework + - sdk: QuartzCore.framework + - sdk: Security.framework + - sdk: UIKit.framework + - sdk: WebKit.framework + preBuildScripts: + - script: bun tauri ios xcode-script -v --platform ${PLATFORM_DISPLAY_NAME:?} --sdk-root ${SDKROOT:?} --framework-search-paths "${FRAMEWORK_SEARCH_PATHS:?}" --header-search-paths "${HEADER_SEARCH_PATHS:?}" --gcc-preprocessor-definitions "${GCC_PREPROCESSOR_DEFINITIONS:-}" --configuration ${CONFIGURATION:?} ${FORCE_COLOR} ${ARCHS:?} + name: Build Rust Code + basedOnDependencyAnalysis: false + outputFiles: + - $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a + - $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a + - $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a \ No newline at end of file diff --git a/frontend/src-tauri/icons/128x128.png b/frontend/src-tauri/icons/128x128.png index b73b9c4b..39d98729 100644 Binary files a/frontend/src-tauri/icons/128x128.png and b/frontend/src-tauri/icons/128x128.png differ diff --git a/frontend/src-tauri/icons/128x128@2x.png b/frontend/src-tauri/icons/128x128@2x.png index 6cb5b871..0a7cc4e7 100644 Binary files a/frontend/src-tauri/icons/128x128@2x.png and b/frontend/src-tauri/icons/128x128@2x.png differ diff --git a/frontend/src-tauri/icons/32x32.png b/frontend/src-tauri/icons/32x32.png index 149c5266..108544ee 100644 Binary files a/frontend/src-tauri/icons/32x32.png and b/frontend/src-tauri/icons/32x32.png differ diff --git a/frontend/src-tauri/icons/64x64.png b/frontend/src-tauri/icons/64x64.png index 8b0964bd..61719efe 100644 Binary files a/frontend/src-tauri/icons/64x64.png and b/frontend/src-tauri/icons/64x64.png differ diff --git a/frontend/src-tauri/icons/Square107x107Logo.png b/frontend/src-tauri/icons/Square107x107Logo.png index f38a1d50..aeca38a6 100644 Binary files a/frontend/src-tauri/icons/Square107x107Logo.png and b/frontend/src-tauri/icons/Square107x107Logo.png differ diff --git a/frontend/src-tauri/icons/Square142x142Logo.png b/frontend/src-tauri/icons/Square142x142Logo.png index b5045ebe..459b40f5 100644 Binary files a/frontend/src-tauri/icons/Square142x142Logo.png and b/frontend/src-tauri/icons/Square142x142Logo.png differ diff --git a/frontend/src-tauri/icons/Square150x150Logo.png b/frontend/src-tauri/icons/Square150x150Logo.png index cb1749c8..f33808b9 100644 Binary files a/frontend/src-tauri/icons/Square150x150Logo.png and b/frontend/src-tauri/icons/Square150x150Logo.png differ diff --git a/frontend/src-tauri/icons/Square284x284Logo.png b/frontend/src-tauri/icons/Square284x284Logo.png index 83801e15..c4cf6463 100644 Binary files a/frontend/src-tauri/icons/Square284x284Logo.png and b/frontend/src-tauri/icons/Square284x284Logo.png differ diff --git a/frontend/src-tauri/icons/Square30x30Logo.png b/frontend/src-tauri/icons/Square30x30Logo.png index 5e9a800e..5368a452 100644 Binary files a/frontend/src-tauri/icons/Square30x30Logo.png and b/frontend/src-tauri/icons/Square30x30Logo.png differ diff --git a/frontend/src-tauri/icons/Square310x310Logo.png b/frontend/src-tauri/icons/Square310x310Logo.png index ad33b26a..b6c42329 100644 Binary files a/frontend/src-tauri/icons/Square310x310Logo.png and b/frontend/src-tauri/icons/Square310x310Logo.png differ diff --git a/frontend/src-tauri/icons/Square44x44Logo.png b/frontend/src-tauri/icons/Square44x44Logo.png index 75b07520..39bf7036 100644 Binary files a/frontend/src-tauri/icons/Square44x44Logo.png and b/frontend/src-tauri/icons/Square44x44Logo.png differ diff --git a/frontend/src-tauri/icons/Square71x71Logo.png b/frontend/src-tauri/icons/Square71x71Logo.png index d854da89..1328ddc2 100644 Binary files a/frontend/src-tauri/icons/Square71x71Logo.png and b/frontend/src-tauri/icons/Square71x71Logo.png differ diff --git a/frontend/src-tauri/icons/Square89x89Logo.png b/frontend/src-tauri/icons/Square89x89Logo.png index 46ffdc72..da6e587c 100644 Binary files a/frontend/src-tauri/icons/Square89x89Logo.png and b/frontend/src-tauri/icons/Square89x89Logo.png differ diff --git a/frontend/src-tauri/icons/StoreLogo.png b/frontend/src-tauri/icons/StoreLogo.png index 61b4c97d..93c27bd7 100644 Binary files a/frontend/src-tauri/icons/StoreLogo.png and b/frontend/src-tauri/icons/StoreLogo.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png index 27b0fb48..f4c4197f 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png index dca3fa25..61fac805 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png index 27b0fb48..f4c4197f 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and b/frontend/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png index 81540274..8e8cc9f1 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png index f19efc08..5fb05cd3 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png index 81540274..8e8cc9f1 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and b/frontend/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png index f1f8f4de..d3ee1189 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png index 84234dfe..d4afed74 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png index f1f8f4de..d3ee1189 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and b/frontend/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png index 83e0992d..12b1a2e7 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png index f63d626d..3cc58913 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png index 83e0992d..12b1a2e7 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and b/frontend/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png index 86e59e61..354d53e4 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png index 778a014b..ecbbdedf 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png index 86e59e61..354d53e4 100644 Binary files a/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and b/frontend/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/frontend/src-tauri/icons/icon.ico b/frontend/src-tauri/icons/icon.ico index 3e383755..ccc997dd 100644 Binary files a/frontend/src-tauri/icons/icon.ico and b/frontend/src-tauri/icons/icon.ico differ diff --git a/frontend/src-tauri/icons/icon.png b/frontend/src-tauri/icons/icon.png index b3983cf0..3a601788 100644 Binary files a/frontend/src-tauri/icons/icon.png and b/frontend/src-tauri/icons/icon.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png b/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png index 0e763000..76eaa0d6 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png and b/frontend/src-tauri/icons/ios/AppIcon-20x20@1x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png index 3984e1c6..5e328c1c 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and b/frontend/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png b/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png index 3984e1c6..5e328c1c 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-20x20@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png b/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png index 205c7bea..755d875d 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png and b/frontend/src-tauri/icons/ios/AppIcon-20x20@3x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png b/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png index 85650c3d..72326ad5 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png and b/frontend/src-tauri/icons/ios/AppIcon-29x29@1x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png index 4bd3df7a..8b74e09b 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and b/frontend/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png b/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png index 4bd3df7a..8b74e09b 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-29x29@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png b/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png index 43f5a955..faa81215 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png and b/frontend/src-tauri/icons/ios/AppIcon-29x29@3x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png b/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png index 3984e1c6..5e328c1c 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png and b/frontend/src-tauri/icons/ios/AppIcon-40x40@1x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png index 1ff87f5f..add5207c 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and b/frontend/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png b/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png index 1ff87f5f..add5207c 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-40x40@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png b/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png index 526da678..f8e167b2 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png and b/frontend/src-tauri/icons/ios/AppIcon-40x40@3x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-512@2x.png b/frontend/src-tauri/icons/ios/AppIcon-512@2x.png index a37bc4a2..0c0838ce 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-512@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-512@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png b/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png index 526da678..f8e167b2 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-60x60@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png b/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png index ba66c2be..8f85ca18 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png and b/frontend/src-tauri/icons/ios/AppIcon-60x60@3x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png b/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png index 2aa8edbb..be1fb475 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png and b/frontend/src-tauri/icons/ios/AppIcon-76x76@1x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png b/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png index e333cbeb..017ee8fa 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-76x76@2x.png differ diff --git a/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png index eccc2844..7ef1862a 100644 Binary files a/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and b/frontend/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index bc43ab08..3655ec4a 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -20,6 +20,7 @@ pub fn run() { .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_deep_link::init()) .plugin(tauri_plugin_opener::init()) + .plugin(tauri_plugin_os::init()) .setup(|app| { // Set up the deep link handler // Use a cloned handle with 'static lifetime @@ -189,6 +190,23 @@ pub fn run() { .level(log::LevelFilter::Info) .build(), ) + .plugin(tauri_plugin_deep_link::init()) + .plugin(tauri_plugin_opener::init()) + .plugin(tauri_plugin_os::init()) + .setup(|app| { + // Set up the deep link handler for mobile + let app_handle = app.handle().clone(); + + // Register deep link handler - note that iOS does not support runtime registration + // but the handler for incoming URLs still works + app.deep_link().on_open_url(move |event| { + if let Some(url) = event.urls().first() { + handle_deep_link_event(&url.to_string(), &app_handle); + } + }); + + Ok(()) + }) .plugin(tauri_plugin_updater::Builder::new().build()); app.run(tauri::generate_context!()) diff --git a/frontend/src-tauri/tauri.conf.json b/frontend/src-tauri/tauri.conf.json index f888400f..80245193 100644 --- a/frontend/src-tauri/tauri.conf.json +++ b/frontend/src-tauri/tauri.conf.json @@ -21,7 +21,12 @@ "deep-link": { "desktop": { "schemes": ["cloud.opensecret.maple"] - } + }, + "mobile": [ + { + "host": "trymaple.ai" + } + ] } }, "app": { @@ -60,7 +65,7 @@ "entitlements": null }, "iOS": { - "developmentTeam": null + "developmentTeam": "X773Y823TN" }, "windows": { "certificateThumbprint": null, diff --git a/frontend/src/components/DeepLinkHandler.tsx b/frontend/src/components/DeepLinkHandler.tsx index 05ba3e8f..b25a1633 100644 --- a/frontend/src/components/DeepLinkHandler.tsx +++ b/frontend/src/components/DeepLinkHandler.tsx @@ -13,6 +13,8 @@ export function DeepLinkHandler() { const setupDeepLinkHandling = async () => { try { if (await isTauri()) { + console.log("[Deep Link] Setting up handler for Tauri app"); + // Listen for the custom event we emit from Rust unlisten = await listen("deep-link-received", (event) => { const url = event.payload; diff --git a/frontend/src/components/Marketing.tsx b/frontend/src/components/Marketing.tsx index d3e74ab6..c060db58 100644 --- a/frontend/src/components/Marketing.tsx +++ b/frontend/src/components/Marketing.tsx @@ -4,6 +4,10 @@ import { ArrowRight, Check, Lock, MessageSquareMore, Shield, Sparkles, Laptop } import { Footer } from "./Footer"; import { useQuery } from "@tanstack/react-query"; import { getBillingService } from "@/billing/billingService"; +import { useState, useEffect } from "react"; +// eslint-disable-next-line +// @ts-ignore +import { type } from "@tauri-apps/plugin-os"; function CTAButton({ children, @@ -83,7 +87,8 @@ function PricingTier({ features, ctaText, popular = false, - productId = "" // Add productId parameter + productId = "", // Add productId parameter + isIOS = false // Add iOS detection parameter }: { name: string; price: string; @@ -92,8 +97,10 @@ function PricingTier({ ctaText: string; popular?: boolean; productId?: string; // Add type for productId + isIOS?: boolean; // Add type for iOS detection }) { const isTeamPlan = name.toLowerCase().includes("team"); + const isFreeplan = name.toLowerCase().includes("free"); return ( ))} - {isTeamPlan ? ( + {/* For iOS devices, disable paid plans with "Coming Soon" text */} + {isIOS && !isFreeplan ? ( + + Coming Soon + + ) : isTeamPlan ? ( // For team plans, add "Contact Us" button that opens email { @@ -174,6 +194,23 @@ function PricingTier({ } export function Marketing() { + const [isIOS, setIsIOS] = useState(false); + + // Check if the app is running on iOS + useEffect(() => { + const checkPlatform = async () => { + try { + const platform = await type(); + setIsIOS(platform === "ios"); + } catch (error) { + console.error("Error checking platform:", error); + setIsIOS(false); + } + }; + + checkPlatform(); + }, []); + // Fetch products to get product IDs for pricing tiers const { data: products @@ -613,6 +650,7 @@ export function Marketing() { ]} ctaText="Start Chatting" productId={getProductId("Starter")} + isIOS={isIOS} /> diff --git a/frontend/src/routes/auth.$provider.callback.tsx b/frontend/src/routes/auth.$provider.callback.tsx index 2a875000..ef043ccb 100644 --- a/frontend/src/routes/auth.$provider.callback.tsx +++ b/frontend/src/routes/auth.$provider.callback.tsx @@ -48,14 +48,14 @@ function OAuthCallback() { ? handleGitHubCallback(code, state, "") : handleGoogleCallback(code, state, "")); - // Check if this is a desktop auth flow - const isDesktopAuth = localStorage.getItem("redirect-to-native") === "true"; + // Check if this is a Tauri app auth flow (desktop or mobile) + const isTauriAuth = localStorage.getItem("redirect-to-native") === "true"; // Clear the flag localStorage.removeItem("redirect-to-native"); - if (isDesktopAuth) { - // This is a desktop auth flow - redirect to the desktop app with tokens + if (isTauriAuth) { + // This is a Tauri app auth flow - redirect back to the app with tokens // Get tokens from localStorage where they're stored after auth const accessToken = localStorage.getItem("access_token") || ""; const refreshToken = localStorage.getItem("refresh_token"); @@ -111,7 +111,7 @@ function OAuthCallback() { processCallback(); }, [handleGitHubCallback, handleGoogleCallback, navigate, provider]); - // If this is a desktop auth flow, show a different UI + // If this is a Tauri app auth flow (desktop or mobile), show a different UI if (localStorage.getItem("redirect-to-native") === "true") { return ( @@ -119,9 +119,7 @@ function OAuthCallback() { {formattedProvider} Authentication Successful - - Authentication successful! Redirecting you back to the desktop app... - + Authentication successful! Redirecting you back to the app... diff --git a/frontend/src/routes/desktop-auth.tsx b/frontend/src/routes/desktop-auth.tsx index c08c5839..bbc11395 100644 --- a/frontend/src/routes/desktop-auth.tsx +++ b/frontend/src/routes/desktop-auth.tsx @@ -10,6 +10,7 @@ interface DesktopAuthSearchParams { selected_plan?: string; } +// This route handles OAuth flow for both desktop and mobile Tauri apps export const Route = createFileRoute("/desktop-auth")({ component: DesktopAuth, validateSearch: (search: Record): DesktopAuthSearchParams => { @@ -35,7 +36,7 @@ function DesktopAuth() { useEffect(() => { const initiateAuth = async () => { try { - // Store the flag to indicate this is a desktop auth flow + // Store the flag to indicate this is a Tauri app auth flow (desktop or mobile) localStorage.setItem("redirect-to-native", "true"); // Store selected plan if present diff --git a/frontend/src/routes/login.tsx b/frontend/src/routes/login.tsx index 8fe7ed5f..ffab5962 100644 --- a/frontend/src/routes/login.tsx +++ b/frontend/src/routes/login.tsx @@ -83,10 +83,10 @@ function LoginPage() { const handleGitHubLogin = async () => { try { const isTauriEnv = await isTauri(); - console.log("[OAuth] Using", isTauriEnv ? "desktop" : "web", "flow"); + console.log("[OAuth] Using", isTauriEnv ? "Tauri" : "web", "flow"); if (isTauriEnv) { - // For desktop, redirect to the web app's desktop-auth route + // For Tauri (desktop or mobile), redirect to the web app's desktop-auth route let desktopAuthUrl = "https://trymaple.ai/desktop-auth?provider=github"; // If there's a selected plan, add it to the URL @@ -95,6 +95,8 @@ function LoginPage() { } // Use the opener plugin by directly invoking the command + // This works for both desktop and mobile (iOS/Android) + console.log("[OAuth] Opening URL in external browser:", desktopAuthUrl); invoke("plugin:opener|open_url", { url: desktopAuthUrl }).catch((error: Error) => { console.error("[OAuth] Failed to open external browser:", error); setError("Failed to open authentication page in browser"); @@ -116,10 +118,10 @@ function LoginPage() { const handleGoogleLogin = async () => { try { const isTauriEnv = await isTauri(); - console.log("[OAuth] Using", isTauriEnv ? "desktop" : "web", "flow"); + console.log("[OAuth] Using", isTauriEnv ? "Tauri" : "web", "flow"); if (isTauriEnv) { - // For desktop, redirect to the web app's desktop-auth route + // For Tauri (desktop or mobile), redirect to the web app's desktop-auth route let desktopAuthUrl = "https://trymaple.ai/desktop-auth?provider=google"; // If there's a selected plan, add it to the URL @@ -128,6 +130,8 @@ function LoginPage() { } // Use the opener plugin by directly invoking the command + // This works for both desktop and mobile (iOS/Android) + console.log("[OAuth] Opening URL in external browser:", desktopAuthUrl); invoke("plugin:opener|open_url", { url: desktopAuthUrl }).catch((error: Error) => { console.error("[OAuth] Failed to open external browser:", error); setError("Failed to open authentication page in browser"); diff --git a/frontend/src/routes/pricing.tsx b/frontend/src/routes/pricing.tsx index b9e7178e..88142c8b 100644 --- a/frontend/src/routes/pricing.tsx +++ b/frontend/src/routes/pricing.tsx @@ -11,6 +11,7 @@ import { Badge } from "@/components/ui/badge"; import { useLocalState } from "@/state/useLocalState"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; +import { type } from "@tauri-apps/plugin-os"; type PricingSearchParams = { selected_plan?: string; @@ -140,12 +141,28 @@ function PricingPage() { const [checkoutError, setCheckoutError] = useState(""); const [loadingProductId, setLoadingProductId] = useState(null); const [useBitcoin, setUseBitcoin] = useState(false); + const [isIOS, setIsIOS] = useState(false); const navigate = useNavigate(); const os = useOpenSecret(); const { setBillingStatus } = useLocalState(); const isLoggedIn = !!os.auth.user; const { selected_plan } = Route.useSearch(); + // Check if the app is running on iOS + useEffect(() => { + const checkPlatform = async () => { + try { + const platform = await type(); + setIsIOS(platform === "ios"); + } catch (error) { + console.error("Error checking platform:", error); + setIsIOS(false); + } + }; + + checkPlatform(); + }, []); + // Fetch billing status if user is logged in const { data: freshBillingStatus, isLoading: isBillingStatusLoading } = useQuery({ queryKey: ["billingStatus"], @@ -158,12 +175,12 @@ function PricingPage() { enabled: isLoggedIn }); - // Auto-enable Bitcoin toggle for Zaprite users + // Auto-enable Bitcoin toggle for Zaprite users (except on iOS) useEffect(() => { - if (freshBillingStatus?.payment_provider === "zaprite") { + if (freshBillingStatus?.payment_provider === "zaprite" && !isIOS) { setUseBitcoin(true); } - }, [freshBillingStatus?.payment_provider]); + }, [freshBillingStatus?.payment_provider, isIOS]); // Always try to fetch portal URL if logged in const { data: portalUrl } = useQuery({ @@ -215,6 +232,11 @@ function PricingPage() { }); const getButtonText = (product: Product) => { + // For iOS, show "Coming Soon" for paid plans + if (isIOS && !product.name.toLowerCase().includes("free")) { + return "Coming Soon"; + } + if (loadingProductId === product.id) { return ( <> @@ -342,6 +364,11 @@ function PricingPage() { const handleButtonClick = useCallback( (product: Product) => { + // For iOS, disable payment buttons except for free plan + if (isIOS && !product.name.toLowerCase().includes("free")) { + return; // Do nothing for paid plans on iOS + } + if (!isLoggedIn) { const targetPlanName = product.name.toLowerCase(); const isTeamPlan = targetPlanName.includes("team"); @@ -413,17 +440,30 @@ function PricingPage() { // create checkout session newHandleSubscribe(product.id); }, - [isLoggedIn, isTeamPlanAvailable, freshBillingStatus, navigate, portalUrl, newHandleSubscribe] + [ + isLoggedIn, + isTeamPlanAvailable, + freshBillingStatus, + navigate, + portalUrl, + newHandleSubscribe, + isIOS + ] ); useEffect(() => { let isSubscribed = true; - // If user is logged in and there's a selected plan, trigger checkout + // If user is logged in and there's a selected plan, trigger checkout (except on iOS for paid plans) if (isLoggedIn && selected_plan && !isBillingStatusLoading) { if (loadingProductId) return; // Prevent multiple triggers const product = products?.find((p) => p.id === selected_plan); if (product) { + // Skip automatic checkout for paid plans on iOS + if (isIOS && !product.name.toLowerCase().includes("free")) { + return; + } + if (isSubscribed) { handleButtonClick(product); } @@ -439,7 +479,8 @@ function PricingPage() { isBillingStatusLoading, products, loadingProductId, - handleButtonClick + handleButtonClick, + isIOS ]); // Show loading state if we're fetching initial data @@ -536,20 +577,22 @@ function PricingPage() { } /> - - - - - Pay with Bitcoin + {!isIOS && ( + + + + + Pay with Bitcoin + + - - + )} {products && @@ -666,7 +709,9 @@ function PricingPage() { handleButtonClick(product)} disabled={ - loadingProductId === product.id || (useBitcoin && product.name === "Team") + loadingProductId === product.id || + (useBitcoin && product.name === "Team") || + (isIOS && !product.name.toLowerCase().includes("free")) } className={`w-full dark:bg-white/90 dark:text-black dark:hover:bg-[hsl(var(--purple))]/80 dark:hover:text-[hsl(var(--foreground))] dark:active:bg-white/80 @@ -677,7 +722,7 @@ function PricingPage() { hover:shadow-[0_0_25px_rgba(var(--purple-rgb),0.3)] disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 group-hover:bg-[hsl(var(--purple))] group-hover:text-[hsl(var(--foreground))] dark:group-hover:text-[hsl(var(--foreground))] dark:group-hover:bg-[hsl(var(--purple))]/80 ${ - isTeamPlan && !isTeamPlanAvailable + isTeamPlan && !isTeamPlanAvailable && !isIOS ? "!opacity-100 !cursor-pointer hover:!bg-[hsl(var(--purple))]" : "" }`} diff --git a/frontend/src/routes/signup.tsx b/frontend/src/routes/signup.tsx index 8ca14a74..5c11c514 100644 --- a/frontend/src/routes/signup.tsx +++ b/frontend/src/routes/signup.tsx @@ -8,6 +8,7 @@ import { AlertDestructive } from "@/components/AlertDestructive"; import { Loader2, Github, Mail } from "lucide-react"; import { Google } from "@/components/icons/Google"; import { AuthMain } from "@/components/AuthMain"; +import { isTauri, invoke } from "@tauri-apps/api/core"; type SignupSearchParams = { next?: string; @@ -81,11 +82,33 @@ function SignupPage() { const handleGitHubSignup = async () => { try { - const { auth_url } = await os.initiateGitHubAuth(""); - if (selected_plan) { - sessionStorage.setItem("selected_plan", selected_plan); + const isTauriEnv = await isTauri(); + console.log("[OAuth] Using", isTauriEnv ? "Tauri" : "web", "flow"); + + if (isTauriEnv) { + // For Tauri (desktop or mobile), redirect to the web app's desktop-auth route + let desktopAuthUrl = "https://trymaple.ai/desktop-auth?provider=github"; + + // If there's a selected plan, add it to the URL + if (selected_plan) { + desktopAuthUrl += `&selected_plan=${encodeURIComponent(selected_plan)}`; + } + + // Use the opener plugin by directly invoking the command + // This works for both desktop and mobile (iOS/Android) + console.log("[OAuth] Opening URL in external browser:", desktopAuthUrl); + invoke("plugin:opener|open_url", { url: desktopAuthUrl }).catch((error: Error) => { + console.error("[OAuth] Failed to open external browser:", error); + setError("Failed to open authentication page in browser"); + }); + } else { + // Web flow remains unchanged + const { auth_url } = await os.initiateGitHubAuth(""); + if (selected_plan) { + sessionStorage.setItem("selected_plan", selected_plan); + } + window.location.href = auth_url; } - window.location.href = auth_url; } catch (error) { console.error("Failed to initiate GitHub signup:", error); setError("Failed to initiate GitHub signup. Please try again."); @@ -94,11 +117,33 @@ function SignupPage() { const handleGoogleSignup = async () => { try { - const { auth_url } = await os.initiateGoogleAuth(""); - if (selected_plan) { - sessionStorage.setItem("selected_plan", selected_plan); + const isTauriEnv = await isTauri(); + console.log("[OAuth] Using", isTauriEnv ? "Tauri" : "web", "flow"); + + if (isTauriEnv) { + // For Tauri (desktop or mobile), redirect to the web app's desktop-auth route + let desktopAuthUrl = "https://trymaple.ai/desktop-auth?provider=google"; + + // If there's a selected plan, add it to the URL + if (selected_plan) { + desktopAuthUrl += `&selected_plan=${encodeURIComponent(selected_plan)}`; + } + + // Use the opener plugin by directly invoking the command + // This works for both desktop and mobile (iOS/Android) + console.log("[OAuth] Opening URL in external browser:", desktopAuthUrl); + invoke("plugin:opener|open_url", { url: desktopAuthUrl }).catch((error: Error) => { + console.error("[OAuth] Failed to open external browser:", error); + setError("Failed to open authentication page in browser"); + }); + } else { + // Web flow remains unchanged + const { auth_url } = await os.initiateGoogleAuth(""); + if (selected_plan) { + sessionStorage.setItem("selected_plan", selected_plan); + } + window.location.href = auth_url; } - window.location.href = auth_url; } catch (error) { console.error("Failed to initiate Google signup:", error); setError("Failed to initiate Google signup. Please try again.");
- Authentication successful! Redirecting you back to the desktop app... -
Authentication successful! Redirecting you back to the app...