From 62b4c1e232354eea4ae5a6a7890037fe4399c346 Mon Sep 17 00:00:00 2001 From: psyattack <82573437+psyattack@users.noreply.github.com> Date: Sat, 25 Jul 2026 15:26:53 +0300 Subject: [PATCH 1/5] fix(settings): Prevent select dropdown from closing parent dialog Update Select component to manage open state and handle pointer events properly so that selecting options or clicking outside select dropdowns does not trigger outside-click handlers on parent dialogs. --- src/components/common/Select.tsx | 34 ++++++++++++++----- .../settings/GeneralSettingsTab.tsx | 2 ++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/components/common/Select.tsx b/src/components/common/Select.tsx index 0e94667..c86a51b 100644 --- a/src/components/common/Select.tsx +++ b/src/components/common/Select.tsx @@ -1,6 +1,6 @@ import * as RadixSelect from "@radix-ui/react-select"; import { Check, ChevronDown } from "lucide-react"; -import { ReactNode } from "react"; +import { ReactNode, useState } from "react"; import { cn } from "@/lib/utils"; @@ -17,6 +17,7 @@ interface Props { placeholder?: string; className?: string; icon?: ReactNode; + closeOnSelectionOnly?: boolean; } const EMPTY_SENTINEL = "__empty__"; @@ -29,19 +30,25 @@ export default function Select({ placeholder, className, icon, + closeOnSelectionOnly = false, }: Props) { const normalized = value === "" ? EMPTY_SENTINEL : value; + const [open, setOpen] = useState(false); return ( onValueChange(v === EMPTY_SENTINEL ? "" : v)} - onOpenChange={(open) => { - if (!open) { - setTimeout(() => { - if (document.activeElement instanceof HTMLElement) { - document.activeElement.blur(); - } - }, 0); + open={open} + onValueChange={(v) => { + onValueChange(v === EMPTY_SENTINEL ? "" : v); + setOpen(false); + }} + onOpenChange={(newOpen) => { + if (closeOnSelectionOnly) { + if (newOpen) { + setOpen(true); + } + } else { + setOpen(newOpen); } }} > @@ -61,12 +68,21 @@ export default function Select({ position="popper" sideOffset={6} className="z-50 min-w-40 overflow-hidden rounded-md border border-border bg-surface shadow-card-hover" + onPointerDownOutside={(e) => { + if (closeOnSelectionOnly) e.preventDefault(); + }} > {options.map((opt) => ( setOpen(false)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + setOpen(false); + } + }} className="flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-highlighted:bg-surface-raised" > diff --git a/src/components/settings/GeneralSettingsTab.tsx b/src/components/settings/GeneralSettingsTab.tsx index f3a78cf..ca174e1 100644 --- a/src/components/settings/GeneralSettingsTab.tsx +++ b/src/components/settings/GeneralSettingsTab.tsx @@ -93,6 +93,7 @@ export default function GeneralSettingsTab() { onValueChange={(v) => { void changeLanguageTo(v); }} + closeOnSelectionOnly /> )} {renderRow( @@ -106,6 +107,7 @@ export default function GeneralSettingsTab() { state.setTheme(v as ThemeCode); void persistTheme(v as ThemeCode); }} + closeOnSelectionOnly /> )} {renderRow( From c4bde98997f718ed4364c90cfa65b6525303fb24 Mon Sep 17 00:00:00 2001 From: psyattack <82573437+psyattack@users.noreply.github.com> Date: Sat, 25 Jul 2026 14:53:07 +0300 Subject: [PATCH 2/5] build(ci): Integrate semantic-release and refactor bump script Configure semantic-release in GitHub release workflow and move the version bump script to .github/scripts/bump.mjs. Update package.json scripts and apply minor UI component class formatting. --- .github/.releaserc.json | 58 ++++++++++++++ version.mjs => .github/scripts/bump.mjs | 6 +- .github/workflows/ci.yml | 4 +- .github/workflows/release.yml | 76 ++----------------- CHANGELOG.md | 40 +++++----- README.md | 11 +-- README.ru.md | 11 +-- package-lock.json | 14 ++-- package.json | 2 +- src/components/common/Dialog.tsx | 2 +- src/components/common/Select.tsx | 2 +- .../common/details/PresetSettings.tsx | 2 +- src/components/dialogs/LegalDialog.tsx | 2 +- src/components/dialogs/UpdateDialog.tsx | 2 +- 14 files changed, 105 insertions(+), 127 deletions(-) create mode 100644 .github/.releaserc.json rename version.mjs => .github/scripts/bump.mjs (92%) diff --git a/.github/.releaserc.json b/.github/.releaserc.json new file mode 100644 index 0000000..0f84a81 --- /dev/null +++ b/.github/.releaserc.json @@ -0,0 +1,58 @@ +{ + "branches": ["main"], + "tagFormat": "v${version}", + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits" + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "writerOpts": { + "mainTemplate": "{{#if noteGroups}}\n{{#each noteGroups}}\n### {{title}}\n\n{{#each notes}}\n* {{text}}\n{{/each}}\n\n{{/each}}\n{{/if}}\n\n{{#if commitGroups}}\n
Detailed Changelog\n\n{{#each commitGroups}}\n### {{title}}\n\n{{#each commits}}\n* {{#if scope}}**{{scope}}:** {{/if}}{{subject}}{{#if href}} ([{{shortHash}}]({{href}})){{/if}}\n{{/each}}\n\n{{/each}}\n
\n{{/if}}" + } + } + ], + [ + "@semantic-release/changelog", + { + "changelogFile": "CHANGELOG.md" + } + ], + [ + "@semantic-release/exec", + { + "prepareCmd": "node .github/scripts/bump.mjs ${nextRelease.version}" + } + ], + [ + "@semantic-release/git", + { + "assets": [ + "CHANGELOG.md", + "package.json", + "package-lock.json", + "src-tauri/Cargo.toml", + "src-tauri/Cargo.lock", + "src-tauri/tauri.conf.json", + "src-tauri/src/core/constants.rs" + ], + "message": "chore(release): bump version to ${nextRelease.version} [skip ci]" + } + ], + [ + "@semantic-release/github", + { + "assets": [ + { "path": "dist_artifacts/*.exe" }, + { "path": "dist_artifacts/*.msi" }, + { "path": "dist_artifacts/*.zip" } + ] + } + ] + ] +} diff --git a/version.mjs b/.github/scripts/bump.mjs similarity index 92% rename from version.mjs rename to .github/scripts/bump.mjs index 2bc11c7..75cd9ae 100644 --- a/version.mjs +++ b/.github/scripts/bump.mjs @@ -2,13 +2,13 @@ /** * Usage: - * node version.mjs 4.5.0 + * node .github/scripts/bump.mjs 4.5.0 * * Updates the version string in all four locations: * 1. package.json * 2. src-tauri/Cargo.toml * 3. src-tauri/tauri.conf.json - * 4. src-tauri/src/constants.rs + * 4. src-tauri/src/core/constants.rs * * Then runs: * - `npm install --package-lock-only` to sync package-lock.json @@ -22,7 +22,7 @@ const newVersion = process.argv[2]; if (!newVersion || !/^\d+\.\d+\.\d+/.test(newVersion)) { console.error( - "Usage: node version.mjs (e.g. node version.mjs 4.5.0)", + "Usage: node .github/scripts/bump.mjs (e.g. node .github/scripts/bump.mjs 4.5.0)", ); process.exit(1); } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 627c712..bd6db1a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: CI on: push: - branches: [ main, master, dev ] + branches: [ main ] pull_request: - branches: [ main, master ] + branches: [ main ] jobs: frontend: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed00ef4..9a3cfc0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,24 +2,9 @@ name: Release on: push: - tags: - - 'v*' + branches: + - main workflow_dispatch: - inputs: - release_title: - description: 'Custom Release Title (leave empty for default: "WEave vX.Y.Z")' - required: false - type: string - is_draft: - description: 'Publish as Draft' - required: false - type: boolean - default: false - is_prerelease: - description: 'Publish as Pre-release' - required: false - type: boolean - default: false permissions: contents: write @@ -27,7 +12,7 @@ permissions: attestations: write jobs: - publish-tauri: + release: name: Build & Publish Release runs-on: windows-latest steps: @@ -53,19 +38,6 @@ jobs: - name: Install frontend dependencies run: npm ci - - name: Determine Version & Title - id: version_info - shell: powershell - run: | - $ver = (Get-Content package.json | ConvertFrom-Json).version - echo "VERSION=$ver" >> $env:GITHUB_OUTPUT - - $customTitle = "${{ github.event.inputs.release_title }}" - if ([string]::IsNullOrWhiteSpace($customTitle)) { - $customTitle = "WEave v$ver" - } - echo "TITLE=$customTitle" >> $env:GITHUB_OUTPUT - - name: Build Tauri App run: npm run tauri build @@ -73,7 +45,7 @@ jobs: id: prepare_artifacts shell: powershell run: | - $ver = "${{ steps.version_info.outputs.VERSION }}" + $ver = (Get-Content package.json | ConvertFrom-Json).version $distDir = "dist_artifacts" New-Item -ItemType Directory -Force -Path $distDir @@ -101,48 +73,12 @@ jobs: Write-Host "Created $zipTarget" } - - name: Extract Release Notes from CHANGELOG.md - id: changelog - shell: powershell - run: | - $latestTagNotes = "" - if (Test-Path "CHANGELOG.md") { - $lines = Get-Content "CHANGELOG.md" - $extracted = @() - $started = $false - foreach ($line in $lines) { - if ($line -match '^##\s+\[?v?\d+') { - if ($started) { break } - $started = $true - continue - } - if ($started) { - $extracted += $line - } - } - $latestTagNotes = ($extracted -join "`n").Trim() - } - - if (-not $latestTagNotes) { - $latestTagNotes = "Release v${{ steps.version_info.outputs.VERSION }}" - } - - [System.IO.File]::WriteAllText("CHANGELOG_GENERATED.md", $latestTagNotes, [System.Text.Encoding]::UTF8) - - name: Attest Build Artifacts uses: actions/attest-build-provenance@v2 with: subject-path: 'dist_artifacts/*' - - name: Create GitHub Release - uses: softprops/action-gh-release@v2 - with: - tag_name: v${{ steps.version_info.outputs.VERSION }} - name: "${{ steps.version_info.outputs.TITLE }}" - body_path: CHANGELOG_GENERATED.md - draft: ${{ github.event.inputs.is_draft || false }} - prerelease: ${{ github.event.inputs.is_prerelease || false }} - files: | - dist_artifacts/* + - name: Run Semantic Release + run: npx --yes -p semantic-release -p @semantic-release/commit-analyzer -p @semantic-release/release-notes-generator -p @semantic-release/changelog -p @semantic-release/exec -p @semantic-release/git -p @semantic-release/github -p conventional-changelog-conventionalcommits semantic-release --extends ./.github/.releaserc.json env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 84f45f5..a787579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,32 +3,30 @@ ## [4.11.0] - 2026-07-24 ### Added -- Combined "Download & Release Notes" action button in the update dialog. -- Header icons for UpdateDialog and ParserDebugDialog. +- Direct button to download updates and view release notes on GitHub from the update dialog. ### Fixed -- Fixed automatic update modal popup on startup when a new release is available. -- Prevented blank window flash on application launch by holding window visibility until React UI is ready. -- Fixed unexpected focus rings on dialog opening and closing. +- Prevented a brief blank window flash when launching the application. +- Fixed update detection on startup to reliably display the update dialog whenever a new version is available. -### Changed -- Streamlined UpdateDialog by removing release notes details and custom Markdown dependencies. -- Added NOTICE.md for third-party license compliance. +### Improved +- Polished UI elements including cleaner dropdown outlines, improved pagination spacing, and simplified hotkey tooltips. +- Updated Legal and Info dialogs to include comprehensive third-party software licensing details.
Detailed Changelog ### Added -- feat(updater): Improve update dialog, auto-check flow and focus handling ([edc286c](https://github.com/psyattack/WEave/commit/edc286c)) +- feat(updater): Improve update dialog, auto-check flow and focus handling ([edc286c](https://github.com/psyattack/WEave/commit/edc286c)) by @psyattack ### Changed -- chore(release): bump version to 4.11.0 ([3ec8041](https://github.com/psyattack/WEave/commit/3ec8041)) -- style(pagination): Improve spacing around page slash separator ([1ca2259](https://github.com/psyattack/WEave/commit/1ca2259)) -- style(ui): Remove focus outline from selects and tooltip from hotkeys ([2fb28dd](https://github.com/psyattack/WEave/commit/2fb28dd)) -- refactor(dialogs): Update Legal and Info dialogs and add NOTICE.md ([73607bc](https://github.com/psyattack/WEave/commit/73607bc)) -- chore: remove knip from repository ([1189551](https://github.com/psyattack/WEave/commit/1189551)) +- chore(release): bump version to 4.11.0 ([3ec8041](https://github.com/psyattack/WEave/commit/3ec8041)) by @psyattack +- style(pagination): Improve spacing around page slash separator ([1ca2259](https://github.com/psyattack/WEave/commit/1ca2259)) by @psyattack +- style(ui): Remove focus outline from selects and tooltip from hotkeys ([2fb28dd](https://github.com/psyattack/WEave/commit/2fb28dd)) by @psyattack +- refactor(dialogs): Update Legal and Info dialogs and add NOTICE.md ([73607bc](https://github.com/psyattack/WEave/commit/73607bc)) by @psyattack +- chore: remove knip from repository ([1189551](https://github.com/psyattack/WEave/commit/1189551)) by @psyattack ### Fixed -- fix(window): Prevent blank window flash on app startup ([406ff22](https://github.com/psyattack/WEave/commit/406ff22)) +- fix(window): Prevent blank window flash on app startup ([406ff22](https://github.com/psyattack/WEave/commit/406ff22)) by @psyattack
@@ -44,11 +42,11 @@
Detailed Changelog ### Changed -- chore(release): bump version to 4.10.3 ([78219c8](https://github.com/psyattack/WEave/commit/78219c8)) -- ci(release): skip version header in generated release body ([eac2d0a](https://github.com/psyattack/WEave/commit/eac2d0a)) -- chore(release): bump version to 4.10.2 ([bfa471d](https://github.com/psyattack/WEave/commit/bfa471d)) -- ci: add GitHub Actions workflows for CI and release ([ed6ce39](https://github.com/psyattack/WEave/commit/ed6ce39)) -- docs(readme): Update features description and formatting ([9b68fb1](https://github.com/psyattack/WEave/commit/9b68fb1)) -- chore: Update documentation structure and filter cookie store logs ([dde6819](https://github.com/psyattack/WEave/commit/dde6819)) +- chore(release): bump version to 4.10.3 ([78219c8](https://github.com/psyattack/WEave/commit/78219c8)) by @psyattack +- ci(release): skip version header in generated release body ([eac2d0a](https://github.com/psyattack/WEave/commit/eac2d0a)) by @psyattack +- chore(release): bump version to 4.10.2 ([bfa471d](https://github.com/psyattack/WEave/commit/bfa471d)) by @psyattack +- ci: add GitHub Actions workflows for CI and release ([ed6ce39](https://github.com/psyattack/WEave/commit/ed6ce39)) by @psyattack +- docs(readme): Update features description and formatting ([9b68fb1](https://github.com/psyattack/WEave/commit/9b68fb1)) by @psyattack +- chore: Update documentation structure and filter cookie store logs ([dde6819](https://github.com/psyattack/WEave/commit/dde6819)) by @psyattack
diff --git a/README.md b/README.md index 0d6b9c6..af1db99 100644 --- a/README.md +++ b/README.md @@ -142,19 +142,12 @@ npm run tauri build npm run test # Frontend tests cd src-tauri && cargo test # Backend tests -# Checks backend (personal recommendation) +# Checks backend cargo check -cargo machete -cargo clippy -- -W dead_code -cargo +nightly udeps -# Checks frontend (personal recommendation) -npx knip +# Checks frontend npm run typecheck npm run lint - -# Bump version -npm run bump -- ``` diff --git a/README.ru.md b/README.ru.md index 1e31839..9c66167 100644 --- a/README.ru.md +++ b/README.ru.md @@ -142,19 +142,12 @@ npm run tauri build npm run test # Тесты frontend cd src-tauri && cargo test # Тесты backend -# Проверки backend (личная рекомендация) +# Проверки backend cargo check -cargo machete -cargo clippy -- -W dead_code -cargo +nightly udeps -# Проверки frontend (личная рекомендация) -npx knip +# Проверки frontend npm run typecheck npm run lint - -# Сменить версию -npm run bump -- ``` diff --git a/package-lock.json b/package-lock.json index 1ecbd80..8198ffc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5100,9 +5100,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -5312,9 +5312,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "dev": true, "funding": [ { @@ -5332,7 +5332,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, diff --git a/package.json b/package.json index 1d4e750..723f5b8 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lint": "eslint src", "typecheck": "tsc --noEmit", "test": "vitest run", - "bump": "node version.mjs" + "bump": "node .github/scripts/bump.mjs" }, "dependencies": { "@radix-ui/react-dialog": "^1.1.17", diff --git a/src/components/common/Dialog.tsx b/src/components/common/Dialog.tsx index 0d9f6c2..852deab 100644 --- a/src/components/common/Dialog.tsx +++ b/src/components/common/Dialog.tsx @@ -66,7 +66,7 @@ export default function Dialog({ exit={{ opacity: 0, y: 8, scale: 0.97 }} transition={{ duration: 0.18, ease: [0.2, 0.8, 0.2, 1] }} className={cn( - "pointer-events-auto relative flex max-h-[calc(100vh-2rem)] w-full flex-col overflow-hidden rounded-xl border border-white/10 bg-surface/60 shadow-[0_16px_40px_rgba(0,0,0,0.6)] backdrop-blur-2xl outline-none focus:outline-none focus:ring-0 focus-visible:outline-none focus-visible:ring-0", + "pointer-events-auto relative flex max-h-[calc(100vh-2rem)] w-full flex-col overflow-hidden rounded-xl border border-white/10 bg-surface/60 shadow-[0_16px_40px_rgba(0,0,0,0.6)] backdrop-blur-2xl outline-none focus:ring-0 focus:outline-none focus-visible:ring-0 focus-visible:outline-none", SIZES[size], )} > diff --git a/src/components/common/Select.tsx b/src/components/common/Select.tsx index c86a51b..827a696 100644 --- a/src/components/common/Select.tsx +++ b/src/components/common/Select.tsx @@ -55,7 +55,7 @@ export default function Select({ diff --git a/src/components/common/details/PresetSettings.tsx b/src/components/common/details/PresetSettings.tsx index a4c80b4..c6cbd08 100644 --- a/src/components/common/details/PresetSettings.tsx +++ b/src/components/common/details/PresetSettings.tsx @@ -192,7 +192,7 @@ export default function PresetSettings({ item, open }: PresetSettingsProps) { } e.target.blur(); }} - className="w-full cursor-pointer appearance-none rounded-md border border-white/5 bg-black/40 px-3 py-1.5 text-sm text-foreground shadow-sm backdrop-blur-xl transition-colors hover:bg-black/60 focus:outline-none focus:ring-0" + className="w-full cursor-pointer appearance-none rounded-md border border-white/5 bg-black/40 px-3 py-1.5 text-sm text-foreground shadow-sm backdrop-blur-xl transition-colors hover:bg-black/60 focus:ring-0 focus:outline-none" > {options.map((opt: string, i: number) => { const optVal = optionValues ? optionValues[i] : i; diff --git a/src/components/dialogs/LegalDialog.tsx b/src/components/dialogs/LegalDialog.tsx index a982bdb..09ab8e9 100644 --- a/src/components/dialogs/LegalDialog.tsx +++ b/src/components/dialogs/LegalDialog.tsx @@ -126,7 +126,7 @@ export default function LegalDialog({

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

-

+

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

diff --git a/src/components/dialogs/UpdateDialog.tsx b/src/components/dialogs/UpdateDialog.tsx index 16328e0..38ab534 100644 --- a/src/components/dialogs/UpdateDialog.tsx +++ b/src/components/dialogs/UpdateDialog.tsx @@ -99,7 +99,7 @@ export default function UpdateDialog({ open, onOpenChange }: Props) {