diff --git a/.gitignore b/.gitignore index 76af755426..bf21e1a2cd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ devAssets .DS_Store .idea - +*.code-workspace .env .wrangler @@ -24,6 +24,31 @@ build.sh # the following line was added with the "git ignore" tool by itsrye.dev, version 0.1.0 .lh +# Tauri +/build +/target/ +/gen/schemas +dist-js + +# Gradle / Android build artifacts +**/android/build/ +**/android/.tauri/ +**/android/.gradle/ +**/.gradle/ + +# Rust build artifacts +src-tauri/target/ +# Tauri Android build outputs +src-tauri/gen/android/app/build/ +# Tauri Android release keystore +*.jks + +# Tauri-typegen cache +.typecache + +# Worktrees +.worktrees + # the following line was added with nvim by Shea because its annoying to clear every so often .vscode/bookmarks.json diff --git a/.vscode/settings.json b/.vscode/settings.json index d8071aa979..78a3d23b9a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,9 @@ "[json]": { "editor.defaultFormatter": "oxc.oxc-vscode" }, + "[rust]": { + "editor.defaultFormatter": "rust-lang.rust-analyzer" + }, "nixEnvSelector.nixFile": "${workspaceFolder}/flake.nix", "nixEnvSelector.useFlakes": true, "explorer.fileNesting.enabled": true, diff --git a/config.json b/config.json index 0002880c9b..9abd8fd830 100644 --- a/config.json +++ b/config.json @@ -10,7 +10,9 @@ "pushNotificationDetails": { "pushNotifyUrl": "https://sygnal.sable.moe/_matrix/push/v1/notify", "vapidPublicKey": "BCnS4SbHjeOaqVFW4wjt5xDt_pYIL62qMzKePfYF9fl9PQU14RieIaObh7nLR_9dQf4sykZa-CTrcjkgMIE1mcg", - "webPushAppID": "moe.sable.app.sygnal" + "webPushAppID": "moe.sable.app.sygnal", + "nativePushAppID": "moe.sable.client.android", + "unifiedPushAppID": "moe.sable.up" }, "themeCatalogBaseUrl": "https://raw.githubusercontent.com/SableClient/themes/main/", diff --git a/flake.lock b/flake.lock index 536adabd72..b8fb186ec0 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,26 @@ { "nodes": { + "fenix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "rust-analyzer-src": "rust-analyzer-src" + }, + "locked": { + "lastModified": 1784276287, + "narHash": "sha256-xXONk0mfpVtFSaZZp21bjw1eRud0dFJ2jpVQ/TQX7ZY=", + "owner": "nix-community", + "repo": "fenix", + "rev": "3181005f932fbae4626c6a6dca5b728742656d9e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "fenix", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -110,12 +131,30 @@ }, "root": { "inputs": { + "fenix": "fenix", "flake-parts": "flake-parts", "git-hooks": "git-hooks", "nixpkgs": "nixpkgs", "treefmt-nix": "treefmt-nix" } }, + "rust-analyzer-src": { + "flake": false, + "locked": { + "lastModified": 1784247776, + "narHash": "sha256-GiZgiGRmDl773Y8wEnS1Vs/KJICXwYYspYSuKS0dhLc=", + "owner": "rust-lang", + "repo": "rust-analyzer", + "rev": "7d5fff4b1a86097dda2b8bb899eaf5cf6b6827d5", + "type": "github" + }, + "original": { + "owner": "rust-lang", + "ref": "nightly", + "repo": "rust-analyzer", + "type": "github" + } + }, "treefmt-nix": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 4b719d4b77..e95a163082 100644 --- a/flake.nix +++ b/flake.nix @@ -7,11 +7,14 @@ git-hooks.inputs.nixpkgs.follows = "nixpkgs"; treefmt-nix.url = "github:numtide/treefmt-nix"; treefmt-nix.inputs.nixpkgs.follows = "nixpkgs"; + fenix = { + url = "github:nix-community/fenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = - inputs@{ flake-parts, ... }: - flake-parts.lib.mkFlake { inherit inputs; } { + outputs = inputs @ {flake-parts, ...}: + flake-parts.lib.mkFlake {inherit inputs;} { imports = [ inputs.git-hooks.flakeModule inputs.treefmt-nix.flakeModule @@ -24,108 +27,102 @@ "aarch64-darwin" ]; - perSystem = - { - config, - pkgs, - lib, - ... - }: - let - self = inputs.self; + perSystem = { + inputs', + config, + system, + lib, + ... + }: let + pkgs = import inputs.nixpkgs { + inherit system; - packageJson = builtins.fromJSON (builtins.readFile ./package.json); + config = { + allowUnfree = true; + android_sdk.accept_license = true; + }; + }; - nodejs = pkgs.nodejs_24; - pnpm = pkgs.pnpm_10; - pnpmConfigHook = pkgs.pnpmConfigHook.override { inherit pnpm; }; + rust = ( + with inputs'.fenix.packages; + combine [ + stable.toolchain + targets.aarch64-linux-android.stable.rust-std + targets.x86_64-linux-android.stable.rust-std + targets.armv7-linux-androideabi.stable.rust-std + targets.i686-linux-android.stable.rust-std + ] + ); - pnpmNativeBuildInputs = [ - nodejs - pnpm - pnpmConfigHook - ]; + platformVersion = "36"; + systemImageType = "default"; + currentPath = builtins.getEnv "PWD"; + androidEnv = pkgs.androidenv.override {licenseAccepted = true;}; + androidComp = ( + androidEnv.composeAndroidPackages { + cmdLineToolsVersion = "8.0"; + includeNDK = true; + buildToolsVersions = ["35.0.0"]; - mkPnpmDeps = - { - src, - version, - pnpmInstallFlags, - }: - pkgs.fetchPnpmDeps { - inherit - pnpm - src - version - pnpmInstallFlags - ; - pname = "sable"; - fetcherVersion = 3; - hash = "sha256-iBvtMeYUHWhsz1DnKjTzydAt3cGPaisUhaagoaZRg1M="; - }; - - mkPnpmCheck = - name: script: - pkgs.stdenv.mkDerivation (finalAttrs: { - pname = "sable-${name}"; - inherit (packageJson) version; - src = lib.cleanSource ./.; - - pnpmInstallFlags = [ "--ignore-scripts" ]; - - pnpmDeps = mkPnpmDeps { - inherit (finalAttrs) src version pnpmInstallFlags; - }; - - nativeBuildInputs = pnpmNativeBuildInputs; - - buildPhase = '' - runHook preBuild - pnpm run ${script} - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - touch $out - runHook postInstall - ''; - - doCheck = false; - }); - in - { - treefmt = { - projectRootFile = "flake.nix"; - programs = { - nixfmt.enable = true; - oxfmt.enable = true; - }; - settings.global.excludes = [ - "dist" - "node_modules" - "pnpm-lock.yaml" - "pnpm-workspace.yaml" - "package.json" - "LICENSE" - "CHANGELOG.md" - "./changeset" + platformVersions = [ + "30" + platformVersion ]; - }; - pre-commit.settings.hooks = { - treefmt = { - enable = true; - package = config.treefmt.build.wrapper; - }; - }; + includeEmulator = true; + includeSystemImages = true; + systemImageTypes = [ + systemImageType + ]; + abiVersions = [ + "x86" + "x86_64" + "armeabi-v7a" + "arm64-v8a" + ]; + cmakeVersions = ["3.10.2"]; + } + ); + android-sdk = pkgs.android-studio.withSdk androidComp.androidsdk; + + self = inputs.self; + + packageJson = builtins.fromJSON (builtins.readFile ./package.json); + + nodejs = pkgs.nodejs_24; + pnpm = pkgs.pnpm_10; + pnpmConfigHook = pkgs.pnpmConfigHook.override {inherit pnpm;}; - packages.sable = pkgs.stdenv.mkDerivation (finalAttrs: { + pnpmNativeBuildInputs = [ + pkgs.pkg-config + nodejs + pnpm + pnpmConfigHook + ]; + + mkPnpmDeps = { + src, + version, + pnpmInstallFlags, + }: + pkgs.fetchPnpmDeps { + inherit + pnpm + src + version + pnpmInstallFlags + ; pname = "sable"; + fetcherVersion = 3; + hash = "sha256-9lHy7/+hVET5c9Mt3F9DvrkW97DMxTISJsrklK/Ls2c="; + }; + + mkPnpmCheck = name: script: + pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "sable-${name}"; inherit (packageJson) version; src = lib.cleanSource ./.; - # ignoring knope for building - pnpmInstallFlags = [ "--ignore-scripts" ]; + pnpmInstallFlags = ["--ignore-scripts"]; pnpmDeps = mkPnpmDeps { inherit (finalAttrs) src version pnpmInstallFlags; @@ -133,49 +130,178 @@ nativeBuildInputs = pnpmNativeBuildInputs; - env.VITE_BUILD_HASH = self.shortRev or self.dirtyShortRev or ""; - env.VITE_IS_RELEASE_TAG = "false"; - buildPhase = '' runHook preBuild - pnpm run build + pnpm run ${script} runHook postBuild ''; installPhase = '' runHook preInstall - cp -r dist $out + touch $out runHook postInstall ''; + + doCheck = false; }); - packages.default = config.packages.sable; + nativeBuildInputs = with pkgs; [ + pkg-config + gobject-introspection + cargo + cargo-tauri + nodejs + xdg-utils + desktop-file-utils + wrapGAppsHook3 + ]; - checks = { - build = config.packages.sable; - lint = mkPnpmCheck "lint" "lint"; - fmt = mkPnpmCheck "fmt" "fmt:check"; - test = mkPnpmCheck "test" "test:run"; - typecheck = mkPnpmCheck "typecheck" "typecheck"; - knip = mkPnpmCheck "knip" "knip"; + buildInputs = with pkgs; [ + at-spi2-atk + atkmm + cairo + gdk-pixbuf + glib + glib-networking + gtk3 + gsettings-desktop-schemas + harfbuzz + librsvg + libsoup_3 + pango + webkitgtk_4_1 + openssl + dbus + dbus.dev + libayatana-appindicator + gst_all_1.gstreamer + gst_all_1.gst-plugins-base + gst_all_1.gst-plugins-good + gst_all_1.gst-plugins-bad + gst_all_1.gst-plugins-ugly + gst_all_1.gst-libav + android-sdk + ]; + + defaultPackages = [ + nodejs + pnpm + rust + pkgs.cargo + pkgs.cargo-tauri + pkgs.corepack + pkgs.vitejs + pkgs.oxlint + pkgs.oxfmt + pkgs.knope + pkgs.typescript + pkgs.typescript-language-server + pkgs.nil + pkgs.nixd + pkgs.jdk + ]; + in { + treefmt = { + projectRootFile = "flake.nix"; + programs = { + nixfmt.enable = true; + oxfmt.enable = true; }; + settings.global.excludes = [ + "dist" + "node_modules" + "pnpm-lock.yaml" + "pnpm-workspace.yaml" + "package.json" + "LICENSE" + "CHANGELOG.md" + "./changeset" + ]; + }; + pre-commit.settings.hooks = { + treefmt = { + enable = true; + package = config.treefmt.build.wrapper; + }; + }; - devShells.default = pkgs.mkShell { - packages = [ - nodejs - pnpm - pkgs.corepack - pkgs.vitejs - pkgs.oxlint - pkgs.oxfmt - pkgs.knope - pkgs.typescript - pkgs.typescript-language-server - pkgs.nil - pkgs.nixd + packages.sable = pkgs.stdenv.mkDerivation (finalAttrs: { + pname = "sable"; + inherit (packageJson) version; + src = lib.cleanSource ./.; + + # ignoring knope for building + pnpmInstallFlags = ["--ignore-scripts"]; + + pnpmDeps = mkPnpmDeps { + inherit (finalAttrs) src version pnpmInstallFlags; + }; + + nativeBuildInputs = pnpmNativeBuildInputs; + + env.VITE_BUILD_HASH = self.shortRev or self.dirtyShortRev or ""; + env.VITE_IS_RELEASE_TAG = "false"; + + buildPhase = '' + runHook preBuild + pnpm run build + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + cp -r dist $out + runHook postInstall + ''; + }); + + packages.android-emulator = androidEnv.emulateApp { + name = "emulate-sable"; + platformVersion = platformVersion; + abiVersion = "x86_64"; # arm64-v8a + systemImageType = systemImageType; + }; + + packages.default = config.packages.sable; + + checks = { + build = config.packages.sable; + lint = mkPnpmCheck "lint" "lint"; + fmt = mkPnpmCheck "fmt" "fmt:check"; + test = mkPnpmCheck "test" "test:run"; + typecheck = mkPnpmCheck "typecheck" "typecheck"; + knip = mkPnpmCheck "knip" "knip"; + }; + + devShells = { + default = pkgs.mkShell { + inherit buildInputs nativeBuildInputs; + + packages = defaultPackages; + + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (nativeBuildInputs ++ buildInputs); + + GIO_EXTRA_MODULES = "${pkgs.glib-networking}/lib/gio/modules"; + GST_PLUGIN_SYSTEM_PATH = "${pkgs.gst_all_1.gst-plugins-base}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-good}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-bad}/lib/gstreamer-1.0"; + }; + + android = pkgs.mkShell { + inherit buildInputs nativeBuildInputs; + + packages = defaultPackages ++ [ + android-sdk ]; - shellHook = config.pre-commit.installationScript; + + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (nativeBuildInputs ++ buildInputs); + + ANDROID_HOME = "${androidComp.androidsdk}/libexec/android-sdk"; + ANDROID_SDK_ROOT = "${androidComp.androidsdk}/libexec/android-sdk"; + ANDROID_NDK_ROOT = "${androidComp.androidsdk}/libexec/android-sdk/ndk-bundle"; + + GIO_EXTRA_MODULES = "${pkgs.glib-networking}/lib/gio/modules"; + GST_PLUGIN_SYSTEM_PATH = "${pkgs.gst_all_1.gst-plugins-base}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-good}/lib/gstreamer-1.0:${pkgs.gst_all_1.gst-plugins-bad}/lib/gstreamer-1.0"; }; }; + }; }; } diff --git a/index.html b/index.html index 4e73dec7cd..3a9c594781 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,10 @@
- +