diff --git a/.forgejo/workflows/deploy-dev.yml b/.forgejo/workflows/deploy-dev.yml index ab7edf1..26053ff 100644 --- a/.forgejo/workflows/deploy-dev.yml +++ b/.forgejo/workflows/deploy-dev.yml @@ -4,31 +4,20 @@ on: - dev jobs: - build-web: + deploy: runs-on: docker + steps: - name: Check out repo uses: https://data.forgejo.org/actions/checkout@v4 - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Nix - uses: https://github.com/cachix/install-nix-action@v30 - - - name: Install Bun + - name: Setup Bun uses: oven-sh/setup-bun@v2 - name: Install dependencies run: bun install --frozen-lockfile - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - - name: Build web + - name: Build run: bun run build:web - name: Install rsync @@ -36,204 +25,3 @@ jobs: - name: Deploy run: rsync -a --delete apps/web/dist/ /var/lib/www/tensamin-web-dev/ - - build-mobile: - runs-on: docker - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Nix - uses: https://github.com/cachix/install-nix-action@v30 - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - - name: Setup Android Keystore - env: - KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} - KEYSTORE_PROPERTIES: ${{ secrets.ANDROID_KEYSTORE_PROPERTIES }} - run: | - bun -e "require('fs').writeFileSync('keystore.jks', Buffer.from(process.env.KEYSTORE_BASE64.replace(/\s+/g, ''), 'base64'))" - bun -e "const content = process.env.KEYSTORE_PROPERTIES.replace(/\\n/g, '\n').replace(/\r/g, '').split('\n').map(l => l.trim()).filter(l => l).join('\n'); require('fs').writeFileSync('keystore.properties', content)" - - - name: Build mobile - run: bun run build:mobile - - - name: Upload mobile artifact - uses: https://data.forgejo.org/actions/upload-artifact@v3 - with: - name: mobile-apk - path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk - - build-desktop: - runs-on: docker - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Nix - uses: https://github.com/cachix/install-nix-action@v30 - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - - name: Build desktop - run: bun run build:desktop - - - name: Upload desktop artifacts - uses: https://data.forgejo.org/actions/upload-artifact@v3 - with: - name: desktop-bundles - path: apps/tauri/src-tauri/target/release/bundle/ - - release: - runs-on: docker - needs: [build-web, build-mobile, build-desktop] - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Download mobile artifact - uses: https://data.forgejo.org/actions/download-artifact@v3 - with: - name: mobile-apk - path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/ - - - name: Download desktop artifacts - uses: https://data.forgejo.org/actions/download-artifact@v3 - with: - name: desktop-bundles - path: apps/tauri/src-tauri/target/release/bundle/ - - - name: Copy releases - run: bun --bun run copy-releases - - - name: Read version and hash - id: version - run: | - VERSION="$(node -p "require('./package.json').version")" - SHORT_SHA="$(git rev-parse --short HEAD)" - echo "version=$VERSION" >> "$FORGEJO_OUTPUT" - echo "short_sha=$SHORT_SHA" >> "$FORGEJO_OUTPUT" - echo "tag=${VERSION}-dev-${SHORT_SHA}" >> "$FORGEJO_OUTPUT" - echo "title=${VERSION}-dev-${SHORT_SHA}" >> "$FORGEJO_OUTPUT" - - - name: Create pre-release and upload files - env: - TOKEN: ${{ forgejo.token }} - API: ${{ forgejo.api_url }} - REPO: ${{ forgejo.repository }} - SHA: ${{ forgejo.sha }} - TAG: ${{ steps.version.outputs.tag }} - TITLE: ${{ steps.version.outputs.title }} - run: | - set -eu - - test -d releases - find releases -type f | grep -q . - - LATEST_PROD_TAG="$(git tag --list '*-prod' --sort=-v:refname | head -n 1 || true)" - - if [ -n "$LATEST_PROD_TAG" ]; then - RAW_LOG="$(git log "$LATEST_PROD_TAG"..HEAD --pretty=format:'- %s')" - else - RAW_LOG="$(git log --pretty=format:'- %s')" - fi - - export RAW_LOG LATEST_PROD_TAG API REPO TAG - BODY="$(node -e ' - const raw = process.env.RAW_LOG; - const lines = raw.split("\n"); - const commits = []; - for (const line of lines) { - const msg = line.replace(/^- /, ""); - const parts = msg.split(/(?=\([^)]+\):)/).filter(Boolean).map(s => s.trim()).filter(s => s); - for (const part of parts) { - commits.push(part); - } - } - const priority = { "(feat):": 1, "(fix):": 2, "(qol):": 3 }; - commits.sort((a, b) => { - const tagA = a.match(/^(\([^)]+\):)/)?.[1] || ""; - const tagB = b.match(/^(\([^)]+\):)/)?.[1] || ""; - return (priority[tagA] || 99) - (priority[tagB] || 99); - }); - const log = commits.map(c => "- " + c).join("\n"); - const latestTag = process.env.LATEST_PROD_TAG; - if (latestTag) { - const serverUrl = process.env.API.replace(/\/api\/v1.*/, ""); - const compareUrl = serverUrl + "/" + process.env.REPO + "/compare/" + latestTag + "..." + process.env.TAG; - console.log(log + "\n\n[View changes](" + compareUrl + ")"); - } else { - console.log(log); - } - ')" - - HTTP_STATUS=$(curl -s -w "%{http_code}" -o release_out.json -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/tags/$TAG") - - if [ "$HTTP_STATUS" = "200" ]; then - echo "Release $TAG already exists." - RELEASE_ID="$(jq -r .id release_out.json)" - else - echo "Creating new pre-release for $TAG" - RELEASE_JSON="$(curl -f -sS -X POST "$API/repos/$REPO/releases" \ - -H "Authorization: token $TOKEN" \ - -H "Content-Type: application/json" \ - -d "$(jq -n \ - --arg tag "$TAG" \ - --arg name "$TITLE" \ - --arg body "$BODY" \ - --arg target "$SHA" \ - '{ - tag_name: $tag, - name: $name, - body: $body, - target_commitish: $target, - draft: false, - prerelease: true - }')")" - RELEASE_ID="$(echo "$RELEASE_JSON" | jq -r .id)" - fi - - find releases -type f -print0 | while IFS= read -r -d '' file; do - name="$(basename "$file")" - curl -fsS -X POST "$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$name" \ - -H "Authorization: token $TOKEN" \ - -F "attachment=@$file" - done diff --git a/.forgejo/workflows/deploy-prod.yml b/.forgejo/workflows/deploy-prod.yml index 7cd9016..1df5b60 100644 --- a/.forgejo/workflows/deploy-prod.yml +++ b/.forgejo/workflows/deploy-prod.yml @@ -4,8 +4,9 @@ on: - main jobs: - build-web: + deploy: runs-on: docker + steps: - name: Check out repo uses: https://data.forgejo.org/actions/checkout@v4 @@ -22,132 +23,29 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - - name: Build web - run: bun run build:web - - - name: Install rsync - run: apt-get update && apt-get install -y rsync - - - name: Deploy - run: rsync -a --delete apps/web/dist/ /var/lib/www/tensamin-web-prod/ - - build-mobile: - runs-on: docker - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Nix - uses: https://github.com/cachix/install-nix-action@v30 - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - name: Setup Android Keystore env: KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} KEYSTORE_PROPERTIES: ${{ secrets.ANDROID_KEYSTORE_PROPERTIES }} run: | bun -e "require('fs').writeFileSync('keystore.jks', Buffer.from(process.env.KEYSTORE_BASE64.replace(/\s+/g, ''), 'base64'))" - bun -e "const content = process.env.KEYSTORE_PROPERTIES.replace(/\\n/g, '\n').replace(/\r/g, '').split('\n').map(l => l.trim()).filter(l => l).join('\n'); require('fs').writeFileSync('keystore.properties', content)" + bun -e "const content = process.env.KEYSTORE_PROPERTIES.replace(/\\\\n/g, '\n').replace(/\\r/g, '').split('\n').map(l => l.trim()).filter(l => l).join('\n'); require('fs').writeFileSync('keystore.properties', content)" - - name: Build mobile - run: bun run build:mobile + - name: Build + run: bun run build:apps - - name: Upload mobile artifact - uses: https://data.forgejo.org/actions/upload-artifact@v3 - with: - name: mobile-apk - path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release.apk + - name: Install rsync + run: apt-get update && apt-get install -y rsync - build-desktop: - runs-on: docker - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Nix - uses: https://github.com/cachix/install-nix-action@v30 - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Copy licenses - run: bun run copy-licenses - - - name: Build packages - run: bun run build:packages - - - name: Build desktop - run: bun run build:desktop - - - name: Upload desktop artifacts - uses: https://data.forgejo.org/actions/upload-artifact@v3 - with: - name: desktop-bundles - path: apps/tauri/src-tauri/target/release/bundle/ - - release: - runs-on: docker - needs: [build-web, build-mobile, build-desktop] - steps: - - name: Check out repo - uses: https://data.forgejo.org/actions/checkout@v4 - - - name: Install Packages - run: apt-get update && apt-get install -y sudo curl jq - - - name: Install Bun - uses: oven-sh/setup-bun@v2 - - - name: Install dependencies - run: bun install --frozen-lockfile - - - name: Download mobile artifact - uses: https://data.forgejo.org/actions/download-artifact@v3 - with: - name: mobile-apk - path: apps/tauri/src-tauri/gen/android/app/build/outputs/apk/universal/release/ - - - name: Download desktop artifacts - uses: https://data.forgejo.org/actions/download-artifact@v3 - with: - name: desktop-bundles - path: apps/tauri/src-tauri/target/release/bundle/ - - - name: Copy releases - run: bun --bun run copy-releases + - name: Deploy + run: rsync -a --delete apps/web/dist/ /var/lib/www/tensamin-web-prod/ - name: Read version id: version run: | VERSION="$(node -p "require('./package.json').version")" echo "version=$VERSION" >> "$FORGEJO_OUTPUT" - echo "tag=${VERSION}-prod" >> "$FORGEJO_OUTPUT" + echo "tag=v$VERSION" >> "$FORGEJO_OUTPUT" - name: Create release and upload files env: @@ -156,40 +54,39 @@ jobs: REPO: ${{ forgejo.repository }} SHA: ${{ forgejo.sha }} TAG: ${{ steps.version.outputs.tag }} + VERSION: ${{ steps.version.outputs.version }} run: | set -eu test -d releases find releases -type f | grep -q . - COMMIT_MSG="$(git log -1 --pretty=%B | sed 's/$/ /')" - HTTP_STATUS=$(curl -s -w "%{http_code}" -o release_out.json -H "Authorization: token $TOKEN" "$API/repos/$REPO/releases/tags/$TAG") if [ "$HTTP_STATUS" = "200" ]; then echo "Release $TAG already exists." - exit 0 + RELEASE_ID="$(jq -r .id release_out.json)" + else + echo "Creating new release for $TAG" + RELEASE_JSON="$(curl -f -sS -X POST "$API/repos/$REPO/releases" \ + -H "Authorization: token $TOKEN" \ + -H "Content-Type: application/json" \ + -d "$(jq -n \ + --arg tag "$TAG" \ + --arg name "$TAG" \ + --arg body "Release $VERSION" \ + --arg target "$SHA" \ + '{ + tag_name: $tag, + name: $name, + body: $body, + target_commitish: $target, + draft: false, + prerelease: false + }')")" + RELEASE_ID="$(echo "$RELEASE_JSON" | jq -r .id)" fi - echo "Creating new release for $TAG" - RELEASE_JSON="$(curl -f -sS -X POST "$API/repos/$REPO/releases" \ - -H "Authorization: token $TOKEN" \ - -H "Content-Type: application/json" \ - -d "$(jq -n \ - --arg tag "$TAG" \ - --arg name "$TAG" \ - --arg body "$COMMIT_MSG" \ - --arg target "$SHA" \ - '{ - tag_name: $tag, - name: $name, - body: $body, - target_commitish: $target, - draft: false, - prerelease: false - }')")" - RELEASE_ID="$(echo "$RELEASE_JSON" | jq -r .id)" - find releases -type f -print0 | while IFS= read -r -d '' file; do name="$(basename "$file")" curl -fsS -X POST "$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$name" \ diff --git a/apps/web/src/components/sidebar.tsx b/apps/web/src/components/sidebar.tsx index 6b4b6cd..ce9bb6b 100644 --- a/apps/web/src/components/sidebar.tsx +++ b/apps/web/src/components/sidebar.tsx @@ -6,7 +6,6 @@ import { Sidebar as SidebarRoot, SidebarContent, SidebarFooter, - useSidebar, } from "@tensamin/ui"; import { isTauri } from "@tauri-apps/api/core"; import { useIsMobile } from "@tensamin/ui"; @@ -14,21 +13,17 @@ import { MobileNavbar } from "./navbar"; import SidebarBox from "@tensamin/call/sidebarBox"; import { useShowMobileNavbar } from "@/routes/app/layout"; + /** * Renders the conversation sidebar with account summary and conversation list. - * On mobile the sidebar is always kept in the DOM and hidden via CSS - * (opacity + translateX) instead of being unmounted. This keeps the DOM and - * React state alive while the drawer is closed, allowing the sidebar to open - * instantly on subsequent toggles. * @returns Sidebar JSX. */ export default function Sidebar() { const isMobile = useIsMobile(); const showMobileNavbar = useShowMobileNavbar(); - const { openMobile, setOpenMobile } = useSidebar(); - const content = ( - <> + return ( + )} - + ); - - if (isMobile) { - return ( - <> - {openMobile && ( -
setOpenMobile(false)} - /> - )} -
-
{content}
-
- - ); - } - - return {content}; }