diff --git a/.github/assets/ann.png b/.github/assets/ann.png new file mode 100644 index 0000000..7d76c18 Binary files /dev/null and b/.github/assets/ann.png differ diff --git a/.github/assets/screenshot.png b/.github/assets/screenshot.png index 85ff1c5..fd02dec 100644 Binary files a/.github/assets/screenshot.png and b/.github/assets/screenshot.png differ diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3f0d8b5..d1e714c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,4 +1,4 @@ -name: Release Nuts +name: Release Orbit on: workflow_dispatch: inputs: @@ -52,9 +52,9 @@ jobs: with: name: ${{ matrix.platform }} path: | - ./src-tauri/target/release/NutsClient + ./src-tauri/target/release/Orbit ./src-tauri/target/release/bundle/dmg/*.dmg - ./src-tauri/target/release/NutsClient.exe + ./src-tauri/target/release/Orbit.exe release: permissions: @@ -71,19 +71,18 @@ jobs: - name: Package macOS binary for release run: | cd ./macos-latest/bundle/dmg/ - tar -czvf Nuts_${{ github.event.inputs.version }}_macOS_Release.tar.gz ./*.dmg + tar -czvf Orbit_${{ github.event.inputs.version }}_macOS_Release.tar.gz ./*.dmg - name: Package linux binary for release run: | cd ./ubuntu-latest/ - chmod u+x NutsClient - tar -czvf Nuts_${{ github.event.inputs.version }}_Linux_Release.tar.gz "NutsClient" + chmod u+x Orbit + tar -czvf Orbit_${{ github.event.inputs.version }}_Linux_Release.tar.gz "Orbit" - - name: Package Windows binary for release run: | cd ./windows-latest/ - zip Nuts_${{ github.event.inputs.version }}_Windows_Release.zip "NutsClient.exe" + zip Orbit_${{ github.event.inputs.version }}_Windows_Release.zip "Orbit.exe" - name: Create GitHub release uses: softprops/action-gh-release@v2 @@ -105,6 +104,6 @@ jobs: **Why do you need to run this?** macOS sometimes marks downloaded files as coming from an untrusted source, and this can prevent the app from launching properly. Running the `xattr` command clears those flags and allows the app to function normally. files: | - ubuntu-latest/Nuts_${{ github.event.inputs.version }}_Linux_Release.tar.gz - macos-latest/bundle/dmg/Nuts_${{ github.event.inputs.version }}_macOS_Release.tar.gz - windows-latest/Nuts_${{ github.event.inputs.version }}_Windows_Release.zip + ubuntu-latest/Orbit_${{ github.event.inputs.version }}_Linux_Release.tar.gz + macos-latest/bundle/dmg/Orbit_${{ github.event.inputs.version }}_macOS_Release.tar.gz + windows-latest/Orbit_${{ github.event.inputs.version }}_Windows_Release.zip diff --git a/Icon.png b/Icon.png new file mode 100644 index 0000000..78bea29 Binary files /dev/null and b/Icon.png differ diff --git a/NATS.png b/NATS.png deleted file mode 100644 index 1ca771d..0000000 Binary files a/NATS.png and /dev/null differ diff --git a/README.md b/README.md index 8bdd2e6..42153d3 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,33 @@ -# NUTS-Client +
+ +
+ +# 🚀 Announcement: **NUTS-Client** is now **Orbit** + +**TL;DR:** We’ve renamed **NUTS-Client** to **Orbit**. Same project, same mission—clearer name, sharper UI, and a few polish touches. No breaking changes to your data; a simple rename in your tooling and you're good to go. + +--- + +## Why the rename? + +- **Clarity:** “Orbit” better reflects the idea of observing, navigating, and interacting with your services and messages from a single, stable vantage point. +- **Room to grow:** We’re expanding beyond the original scope, and the new name fits the broader roadmap. + +--- + +## What is Orbit? + +Orbit is a **file-based GUI client for NATS** that streamlines microservice development. Use it to browse subjects, publish/subscribe, inspect payloads, and iterate quickly—without leaving your flow. -NUTS-Client is a file-based NATS GUI designed to streamline the development of microservices. It provides a user-friendly interface to interact with NATS, a powerful messaging system commonly used in distributed systems.
---- ## Development ### Setting Up a NATS Server - To develop and test your NATS client, you will need a running NATS Server. We provide a Python-based service that listens to topics like `time`, `TP_TEST1`, and `TP_TEST2`. The recommended way to run a NATS Broker is via Docker. You can do so with the following commands: @@ -41,27 +57,3 @@ npm run tauri dev ``` This will start the client in a development environment. - ---- - -### Building the Client in Debug Mode - -If you want to build the client for debugging purposes, run: - -```sh -npm run tauri build -- --debug -``` - -This will generate a debug build of the client. - ---- - -### Building the Client for Release - -To create a release build of the client, use the following command: - -```sh -npm run tauri build -``` - -This will generate a production-ready build of the NUTS-Client. diff --git a/components.json b/components.json index d710b49..f826c54 100644 --- a/components.json +++ b/components.json @@ -1,6 +1,6 @@ { "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", + "style": "new-york", "rsc": true, "tsx": true, "tailwind": { @@ -10,6 +10,7 @@ "cssVariables": true, "prefix": "" }, + "iconLibrary": "lucide", "aliases": { "components": "@/components", "utils": "@/lib/utils", @@ -17,5 +18,5 @@ "lib": "@/lib", "hooks": "@/hooks" }, - "iconLibrary": "lucide" -} \ No newline at end of file + "registries": {} +} diff --git a/package-lock.json b/package-lock.json index f7b4eed..9248ab2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,25 @@ { "name": "nuts-client", - "version": "0.2.1", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "nuts-client", - "version": "0.2.1", + "version": "1.0.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-context-menu": "^2.2.4", - "@radix-ui/react-dialog": "^1.1.14", - "@radix-ui/react-label": "^2.1.1", - "@radix-ui/react-menubar": "^1.1.15", + "@radix-ui/react-context-menu": "^2.2.16", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-menubar": "^1.1.16", "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.1.2", - "@radix-ui/react-tabs": "^1.1.12", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.7", "@reduxjs/toolkit": "^2.5.0", "@sentry/nextjs": "^8.55.0", @@ -30,11 +31,14 @@ "@vitejs/plugin-react": "^4.3.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "lucide-react": "^0.471.0", + "lucide-react": "^0.471.2", "monaco-editor": "^0.52.2", + "motion": "^12.23.22", "next": "^15.3.4", + "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-json-pretty": "^2.2.0", "react-redux": "^9.2.0", "react-resizable-panels": "^2.1.7", "redux-persist": "^6.0.0", @@ -2785,7 +2789,6 @@ "version": "2.2.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", - "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", "@radix-ui/primitive": "1.1.3", @@ -2824,6 +2827,29 @@ } } }, + "node_modules/@radix-ui/react-separator": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.7.tgz", + "integrity": "sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-slot": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", @@ -6698,6 +6724,33 @@ "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==" }, + "node_modules/framer-motion": { + "version": "12.23.22", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.22.tgz", + "integrity": "sha512-ZgGvdxXCw55ZYvhoZChTlG6pUuehecgvEAJz0BHoC5pQKW1EC5xf1Mul1ej5+ai+pVY0pylyFfdl45qnM1/GsA==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.23.21", + "motion-utils": "^12.23.6", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7766,7 +7819,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -7905,6 +7957,47 @@ "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==", "license": "MIT" }, + "node_modules/motion": { + "version": "12.23.22", + "resolved": "https://registry.npmjs.org/motion/-/motion-12.23.22.tgz", + "integrity": "sha512-iSq6X9vLHbeYwmHvhK//+U74ROaPnZmBuy60XZzqNl0QtZkWfoZyMDHYnpKuWFv0sNMqHgED8aCXk94LCoQPGg==", + "license": "MIT", + "dependencies": { + "framer-motion": "^12.23.22", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/motion-dom": { + "version": "12.23.21", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.21.tgz", + "integrity": "sha512-5xDXx/AbhrfgsQmSE7YESMn4Dpo6x5/DTZ4Iyy4xqDvVHWvFVoV+V2Ri2S/ksx+D40wrZ7gPYiMWshkdoqNgNQ==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.23.6" + } + }, + "node_modules/motion-utils": { + "version": "12.23.6", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", + "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8015,6 +8108,15 @@ } } }, + "node_modules/next-themes": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", + "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", + "peerDependencies": { + "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -8551,7 +8653,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -8624,6 +8725,18 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-json-pretty": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-json-pretty/-/react-json-pretty-2.2.0.tgz", + "integrity": "sha512-3UMzlAXkJ4R8S4vmkRKtvJHTewG4/rn1Q18n0zqdu/ipZbUPLVZD+QwC7uVcD/IAY3s8iNVHlgR2dMzIUS0n1A==", + "dependencies": { + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=15.0", + "react-dom": ">=15.0" + } + }, "node_modules/react-redux": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", diff --git a/package.json b/package.json index eb045eb..ce385d9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nuts-client", "author": "jnsaph", - "version": "0.2.1.1", + "version": "1.0.0", "repository": { "type": "git", "url": "https://github.com/JNSAPH/NUTS-CLIENT" @@ -18,14 +18,15 @@ "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@monaco-editor/react": "^4.7.0", - "@radix-ui/react-context-menu": "^2.2.4", - "@radix-ui/react-dialog": "^1.1.14", - "@radix-ui/react-label": "^2.1.1", - "@radix-ui/react-menubar": "^1.1.15", + "@radix-ui/react-context-menu": "^2.2.16", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-label": "^2.1.7", + "@radix-ui/react-menubar": "^1.1.16", "@radix-ui/react-select": "^2.2.6", + "@radix-ui/react-separator": "^1.1.7", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-switch": "^1.1.2", - "@radix-ui/react-tabs": "^1.1.12", + "@radix-ui/react-switch": "^1.2.6", + "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.7", "@reduxjs/toolkit": "^2.5.0", "@sentry/nextjs": "^8.55.0", @@ -37,11 +38,14 @@ "@vitejs/plugin-react": "^4.3.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "lucide-react": "^0.471.0", + "lucide-react": "^0.471.2", "monaco-editor": "^0.52.2", + "motion": "^12.23.22", "next": "^15.3.4", + "next-themes": "^0.4.6", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-json-pretty": "^2.2.0", "react-redux": "^9.2.0", "react-resizable-panels": "^2.1.7", "redux-persist": "^6.0.0", diff --git a/public/logo_color.svg b/public/logo_color.svg new file mode 100644 index 0000000..e7ada6f --- /dev/null +++ b/public/logo_color.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8c1fc2c..01b57f3 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3,8 +3,8 @@ version = 4 [[package]] -name = "NutsClient" -version = "0.2.0" +name = "Orbit" +version = "1.0.0-2" dependencies = [ "async-nats", "bytes", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 896f54d..d659d87 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "NutsClient" -version = "0.2.0" +name = "Orbit" +version = "1.0.0-2" description = "A Tauri App" authors = ["you"] edition = "2021" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 3ac1961..1969180 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -130,6 +130,7 @@ "dialog:default", "shell:default", "opener:default", - "opener:allow-open-path" + "opener:allow-open-path", + "core:webview:allow-create-webview-window" ] } \ No newline at end of file diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png index d04a2ff..ed8b081 100644 Binary files a/src-tauri/icons/128x128.png and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png index e394364..a03ab20 100644 Binary files a/src-tauri/icons/128x128@2x.png and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png index 6690b6c..53bec32 100644 Binary files a/src-tauri/icons/32x32.png and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/64x64.png b/src-tauri/icons/64x64.png index e3e1d5c..6123eba 100644 Binary files a/src-tauri/icons/64x64.png and b/src-tauri/icons/64x64.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png index 6e29fb3..eb4f18d 100644 Binary files a/src-tauri/icons/Square107x107Logo.png and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png index 271c6b5..15b61d8 100644 Binary files a/src-tauri/icons/Square142x142Logo.png and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png index 8abbefb..e3c68a4 100644 Binary files a/src-tauri/icons/Square150x150Logo.png and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png index 9d0f491..cb2a712 100644 Binary files a/src-tauri/icons/Square284x284Logo.png and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png index adc46d4..897698c 100644 Binary files a/src-tauri/icons/Square30x30Logo.png and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png index 01208af..64e5f1b 100644 Binary files a/src-tauri/icons/Square310x310Logo.png and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png index b7e40eb..2b71c10 100644 Binary files a/src-tauri/icons/Square44x44Logo.png and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png index 216cd51..cc43bd6 100644 Binary files a/src-tauri/icons/Square71x71Logo.png and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png index 8474353..29bafe1 100644 Binary files a/src-tauri/icons/Square89x89Logo.png and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png index 0e6a365..0f8d605 100644 Binary files a/src-tauri/icons/StoreLogo.png and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png index 2cae514..90a153f 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png index 7312ec8..44f1702 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png index 2cae514..90a153f 100644 Binary files a/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png index 58e08d4..40aa7cd 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png index 2183cfe..1f3ea73 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png index 58e08d4..40aa7cd 100644 Binary files a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png index 3147927..52582d8 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png index c6f37db..5f8ec9e 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png index 3147927..52582d8 100644 Binary files a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png index e9c2576..69187ea 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png index 65cb44c..9549ffa 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png index e9c2576..69187ea 100644 Binary files a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png index 7fe0685..e604df3 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png index 40f12f9..22d7d4e 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png index 7fe0685..e604df3 100644 Binary files a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png and b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index a9a2fbf..d49b451 100644 Binary files a/src-tauri/icons/icon.icns and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index 8a455b3..fe83f47 100644 Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png index 4dc8c6c..f3fff5e 100644 Binary files a/src-tauri/icons/icon.png and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@1x.png b/src-tauri/icons/ios/AppIcon-20x20@1x.png index efd9ac1..893ff56 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@1x.png and b/src-tauri/icons/ios/AppIcon-20x20@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png index 67cdac3..1ebe5f4 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@2x-1.png and b/src-tauri/icons/ios/AppIcon-20x20@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@2x.png b/src-tauri/icons/ios/AppIcon-20x20@2x.png index 67cdac3..1ebe5f4 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@2x.png and b/src-tauri/icons/ios/AppIcon-20x20@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-20x20@3x.png b/src-tauri/icons/ios/AppIcon-20x20@3x.png index 0ca9c3b..68ac58f 100644 Binary files a/src-tauri/icons/ios/AppIcon-20x20@3x.png and b/src-tauri/icons/ios/AppIcon-20x20@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@1x.png b/src-tauri/icons/ios/AppIcon-29x29@1x.png index 7d8f0ac..b4645cb 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@1x.png and b/src-tauri/icons/ios/AppIcon-29x29@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png index 600b675..6a94518 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png and b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x.png b/src-tauri/icons/ios/AppIcon-29x29@2x.png index 600b675..6a94518 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@2x.png and b/src-tauri/icons/ios/AppIcon-29x29@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-29x29@3x.png b/src-tauri/icons/ios/AppIcon-29x29@3x.png index 942cde9..43c5f01 100644 Binary files a/src-tauri/icons/ios/AppIcon-29x29@3x.png and b/src-tauri/icons/ios/AppIcon-29x29@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@1x.png b/src-tauri/icons/ios/AppIcon-40x40@1x.png index 67cdac3..1ebe5f4 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@1x.png and b/src-tauri/icons/ios/AppIcon-40x40@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png index e38d0c0..ce5a671 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@2x-1.png and b/src-tauri/icons/ios/AppIcon-40x40@2x-1.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x.png b/src-tauri/icons/ios/AppIcon-40x40@2x.png index e38d0c0..ce5a671 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@2x.png and b/src-tauri/icons/ios/AppIcon-40x40@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-40x40@3x.png b/src-tauri/icons/ios/AppIcon-40x40@3x.png index 85fd514..ddfc261 100644 Binary files a/src-tauri/icons/ios/AppIcon-40x40@3x.png and b/src-tauri/icons/ios/AppIcon-40x40@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-512@2x.png b/src-tauri/icons/ios/AppIcon-512@2x.png index 096bb94..7992f85 100644 Binary files a/src-tauri/icons/ios/AppIcon-512@2x.png and b/src-tauri/icons/ios/AppIcon-512@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@2x.png b/src-tauri/icons/ios/AppIcon-60x60@2x.png index 85fd514..ddfc261 100644 Binary files a/src-tauri/icons/ios/AppIcon-60x60@2x.png and b/src-tauri/icons/ios/AppIcon-60x60@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-60x60@3x.png b/src-tauri/icons/ios/AppIcon-60x60@3x.png index 5aa35aa..40eb7d8 100644 Binary files a/src-tauri/icons/ios/AppIcon-60x60@3x.png and b/src-tauri/icons/ios/AppIcon-60x60@3x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@1x.png b/src-tauri/icons/ios/AppIcon-76x76@1x.png index 7372896..75494b3 100644 Binary files a/src-tauri/icons/ios/AppIcon-76x76@1x.png and b/src-tauri/icons/ios/AppIcon-76x76@1x.png differ diff --git a/src-tauri/icons/ios/AppIcon-76x76@2x.png b/src-tauri/icons/ios/AppIcon-76x76@2x.png index 2a5fec9..88d0191 100644 Binary files a/src-tauri/icons/ios/AppIcon-76x76@2x.png and b/src-tauri/icons/ios/AppIcon-76x76@2x.png differ diff --git a/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png index f7efc0b..3664419 100644 Binary files a/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png and b/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png differ diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4830194..e37f75e 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", - "productName": "Nuts Client", - "version": "0.2.0", + "productName": "Orbit", + "version": "1.0.0-2", "identifier": "com.jnsaph.nuts-client", "build": { "beforeDevCommand": "npm run dev", @@ -12,7 +12,7 @@ "app": { "windows": [ { - "title": "Nuts Client", + "title": "Orbit", "width": 1000, "height": 600, "minHeight": 400, diff --git a/src/app/changelog/changelog.json b/src/app/changelog/changelog.json new file mode 100644 index 0000000..1205785 --- /dev/null +++ b/src/app/changelog/changelog.json @@ -0,0 +1,17 @@ +[ + { + "version": "1.0.0", + "date": "2025-01-15", + "changes": [ + "NUTS-Client is now Orbit. We've joined oOVOLabs to expand into more DevTools.", + "Improved overall UI/UX across the app.", + "Resolved numerous bugs and UX issues.", + "Added a Changelog page to track updates.", + "Added keyboard shortcuts for common actions.", + "Added a Welcome page to help new users get started.", + "Added a Settings page for customization.", + "Added a Light and Dark mode toggle.", + "Removed code clutter." + ] + } +] diff --git a/src/app/changelog/layout.tsx b/src/app/changelog/layout.tsx new file mode 100644 index 0000000..7245cac --- /dev/null +++ b/src/app/changelog/layout.tsx @@ -0,0 +1,9 @@ +import React from "react"; + +export default function ChangelogLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return
{children}
; +} \ No newline at end of file diff --git a/src/app/changelog/page.tsx b/src/app/changelog/page.tsx new file mode 100644 index 0000000..d8f3854 --- /dev/null +++ b/src/app/changelog/page.tsx @@ -0,0 +1,214 @@ +"use client"; + +import React from "react"; +import Image from "next/image"; +import { motion } from "framer-motion"; +import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Separator } from "@/components/ui/separator"; +import { Input } from "@/components/ui/input"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { + Bug, + Sparkles, + Wrench, + Plus, + ArrowUpRight, + CheckCircle2, + CalendarDays, + Link as LinkIcon, + Search, +} from "lucide-react"; + +// --- Helpers --------------------------------------------------------------- +const typeMap = { + added: { label: "Added", Icon: Plus }, + improved: { label: "Improved", Icon: Wrench }, + fixed: { label: "Fixed", Icon: Bug }, + introduced: { label: "Introduced", Icon: Sparkles }, + updated: { label: "Updated", Icon: ArrowUpRight }, + resolved: { label: "Resolved", Icon: CheckCircle2 }, +} as const; + +type ChangeType = keyof typeof typeMap; + +function detectType(text: string): ChangeType | null { + const t = text.toLowerCase(); + if (t.startsWith("added")) return "added"; + if (t.startsWith("improved")) return "improved"; + if (t.startsWith("fixed")) return "fixed"; + if (t.startsWith("introduced")) return "introduced"; + if (t.startsWith("updated")) return "updated"; + if (t.startsWith("resolved")) return "resolved"; + return null; +} + +function formatDate(iso: string) { + const d = new Date(iso + "T00:00:00"); + return d.toLocaleDateString(undefined, { + year: "numeric", + month: "short", + day: "2-digit", + }); +} + +export default function ChangelogPage() { + const changelog = require("./changelog.json") as { + version: string; + date: string; + changes: string[]; + }[]; + + const [query, setQuery] = React.useState(""); + const [filter, setFilter] = React.useState<"all" | ChangeType>("all"); + + const filtered = changelog.map((entry) => ({ + ...entry, + changes: entry.changes.filter((c) => { + const matchesQuery = c.toLowerCase().includes(query.toLowerCase()); + const t = detectType(c); + const matchesType = filter === "all" ? true : t === filter; + return matchesQuery && matchesType; + }), + })); + + const anyResults = filtered.some((e) => e.changes.length > 0); + + return ( +
+ {/* Header */} +
+
+
+ App Logo +
+

Changelog

+

What’s new and improved

+
+
+
+
+ + {/* Toolbar */} +
+
+
+
+ + setQuery(e.target.value)} + /> +
+
+ setFilter(v as any)} + className="w-full sm:w-auto" + > + + All + Added + Improved + Fixed + + +
+
+ + {/* Timeline */} +
+ {!anyResults ? ( + + ) : ( +
    + {filtered.map((entry, idx) => ( + + {/* Timeline dot */} +
    + + + +
    +
    + + v{entry.version} + + + {formatDate(entry.date)} + + {idx === 0 && ( + + Latest + + )} +
    +
    +
    + + + + +
      + {entry.changes.map((change, i) => { + const t = detectType(change); + const meta = t && typeMap[t]; + const Icon = meta?.Icon ?? Sparkles; + return ( +
    • + + + +
      +

      {change}

      +
      +
    • + ); + })} +
    +
    +
    + + ))} +
+ )} +
+
+ ); +} + +function EmptyState() { + return ( +
+
+ +

No matches

+

+ Try a different search or filter to find a specific change. +

+
+
+ ); +} diff --git a/src/app/client/explorer/layout.tsx b/src/app/client/explorer/layout.tsx index 443fa17..d037085 100644 --- a/src/app/client/explorer/layout.tsx +++ b/src/app/client/explorer/layout.tsx @@ -42,7 +42,7 @@ const Layout = ({ children }: LayoutProps) => { - +
{children} diff --git a/src/app/client/explorer/page.tsx b/src/app/client/explorer/page.tsx index 9817214..5996b3b 100644 --- a/src/app/client/explorer/page.tsx +++ b/src/app/client/explorer/page.tsx @@ -1,96 +1,139 @@ "use client"; -import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable"; +import { + ResizableHandle, + ResizablePanel, + ResizablePanelGroup, +} from "@/components/ui/resizable"; import { RootState } from "@/redux/store"; -import { useMemo, useCallback, useRef, useEffect, useState } from "react"; +import React, { + useMemo, + useCallback, + useRef, + useEffect, + useState, +} from "react"; import { useDispatch, useSelector } from "react-redux"; -import { setAuthenticationType, setFileContent, setLastResponse, setNatsServerURL, setNATSToken, setUsernamePassword } from "@/redux/slices/projectFile"; -import { setClientSettings } from "@/redux/slices/windowProperties"; -import { NatsAuth, sendNatsMessage } from "@/services/natsWrapper"; -import Logger from "@/services/logging"; +import JSONPretty from 'react-json-pretty'; +import { + setFileContent, + setLastResponse, + setNatsServerURL, +} from "@/redux/slices/projectFile"; import { setTitle } from "@/redux/slices/windowProperties"; -import { IcoPlusBorder } from "@/components/Icons"; +import { Badge } from "@/components/ui/badge"; +import { AuthTypes } from "@/types/Auth"; +import Editor from "@monaco-editor/react"; +import { Button } from "@/components/ui/button"; +import { + handleNewProject, + handleOpenProject, +} from "@/components/titlebar/utils"; +import { Input } from "@/components/ui/input"; +import { Textarea } from "@/components/ui/textarea"; import AuthDialog from "@/components/AuthDialog"; import * as utils from "@/services/utils"; -import { Badge } from "@/components/ui/badge" -import { AuthTypes } from "@/types/Auth"; -import Editor, { useMonaco } from "@monaco-editor/react"; +import { NatsAuth, sendNatsMessage } from "@/services/natsWrapper"; +import Logger from "@/services/logging"; export default function Page() { const content = useSelector((state: RootState) => state.projectFile); - const selectedRequest = useSelector((state: RootState) => state.projectFile.fileContent?.requests[state.projectFile.selectedRequestIndex]); - const settings = useSelector((state: RootState) => state.windowProperties.clientSettings); + const selectedRequest = useSelector( + (state: RootState) => + state.projectFile.fileContent?.requests[ + state.projectFile.selectedRequestIndex + ] + ); + const settings = useSelector( + (state: RootState) => state.windowProperties.clientSettings + ); const dispatch = useDispatch(); - const [natsUrl, setNatsUrl] = useState(content.fileContent?.requests[content.selectedRequestIndex]?.url || ""); + + const [natsUrl, setNatsUrl] = useState( + content.fileContent?.requests[content.selectedRequestIndex]?.url || "" + ); const [disableAuthPoupup, setDisableAuthPopup] = useState(false); const textareaRef = useRef(null); + const saveId = "explorercontent"; const ExplorerContent = useMemo( () => ({ getItem(name: string): string | null { - return localStorage.getItem(name); + return typeof window !== "undefined" + ? localStorage.getItem(name) + : null; }, setItem(name: string, value: string) { - localStorage.setItem(name, value); + if (typeof window !== "undefined") localStorage.setItem(name, value); }, }), [] ); + // Keep the window title in sync useEffect(() => { - dispatch(setTitle("NUTS - " + content.fileContent?.name)); - }, [content.selectedRequestIndex]); - + dispatch(setTitle("Orbit - " + (content.fileContent?.name ?? "Untitled"))); + }, [dispatch, content.fileContent?.name, content.selectedRequestIndex]); - // Function to format JSON - const formatJson = (jsonString: string) => { + // Format JSON nicely if possible + const formatJson = useCallback((jsonString: string) => { try { - if (jsonString === "") return ""; // Return empty string if null - return JSON.stringify(JSON.parse(jsonString), null, 2); // Format with indentation - } catch (e) { - return jsonString; // Return raw string if it's not valid JSON + if (jsonString === "") return ""; + return JSON.stringify(JSON.parse(jsonString), null, 2); + } catch { + return jsonString; } - }; + }, []); - // Memoized onChange handler + // Unified onChange handler for inputs/textarea/editor const handleChange = useCallback( - (e: React.ChangeEvent, key: string) => { - if (selectedRequest && content.fileContent) { - const lastResponse = selectedRequest.lastResponse; - dispatch( - setFileContent({ - ...content.fileContent, - requests: content.fileContent.requests.map((request: any, index: any) => { - if (index === content.selectedRequestIndex) { - return { - ...selectedRequest, - [key]: e.target.value || "", - }; - } - return request; - }), - }) - ); - - dispatch(setLastResponse(lastResponse || "")); // More of a hack, but it works and i don't care enough to fix it - it's 2:43am - } + ( + e: React.ChangeEvent, + key: string + ) => { + if (!selectedRequest || !content.fileContent) return; + + const lastResponse = selectedRequest.lastResponse; + dispatch( + setFileContent({ + ...content.fileContent, + requests: content.fileContent.requests.map( + (request: any, index: number) => + index === content.selectedRequestIndex + ? { + ...selectedRequest, + [key]: e.target.value || "", + } + : request + ), + }) + ); + + // preserve existing lastResponse + dispatch(setLastResponse(lastResponse || "")); }, - [dispatch, content.fileContent, selectedRequest, content.selectedRequestIndex] + [ + dispatch, + content.fileContent, + selectedRequest, + content.selectedRequestIndex, + ] ); - const handleAutoResize = () => { + // Auto-resize plain