Compare commits

...

855 commits

Author SHA1 Message Date
anatawa12
9a1044df51
Merge pull request #2941 from nekobako/feature/project-sorting-by-creation-date
プロジェクトの登録順ソート
2026-06-18 22:40:23 +09:00
anatawa12
e71c48141b
chore: Apply localization suggestions from code review
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2026-06-18 22:34:31 +09:00
nekobako
467434903a docs(changelog-gui): update changelog 2026-06-17 23:20:01 +09:00
nekobako
ba8606d312 chore(gui): adjust project list spacing 2026-06-17 23:20:01 +09:00
nekobako
ed42cdfca4 feat(gui): implement project sorting by creation date 2026-06-17 23:20:01 +09:00
anatawa12
dbd479fbc9
Merge pull request #2976 from vrc-get/dependabot/cargo/uuid-1.23.3
chore(deps): bump uuid from 1.23.2 to 1.23.3
2026-06-15 19:44:33 +09:00
anatawa12
db54f0c8ae
Merge pull request #2970 from vrc-get/native-package
build: use package manager native toolchain to build linux packages
2026-06-15 17:46:38 +09:00
dependabot[bot]
da419a0374
chore(deps): bump uuid from 1.23.2 to 1.23.3
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.23.2 to 1.23.3.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.23.2...v1.23.3)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.23.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-15 07:43:41 +00:00
anatawa12
8351270552
chore!: remove deb / rpm build command 2026-06-15 16:01:18 +09:00
anatawa12
50fccc9a50
ci: migrate publish workflow to package manager native building toolchain 2026-06-15 09:56:40 +09:00
anatawa12
cf7075a6d5
fix: version name in bult binary is separated by ~ 2026-06-15 09:25:05 +09:00
anatawa12
5e4709209f
ci: do not patch source code in spec file, in source tar instead 2026-06-15 08:08:52 +09:00
anatawa12
269cb8aeda
ci: use jammy for building debian package 2026-06-15 00:29:45 +09:00
anatawa12
ba9ad1f59c
ci: add debian package and build on ci 2026-06-14 02:16:31 +09:00
anatawa12
23b1bb2515
ci: add rpm spec file and build on ci 2026-06-11 15:09:19 +09:00
github-actions[bot]
2c36473e6e chore: prepare for next version: gui 1.1.7 2026-06-02 10:44:59 +00:00
github-actions[bot]
791e50d94f gui v1.1.6 2026-06-02 10:29:07 +00:00
anatawa12
a77ab4a0a3
chore: better url handling 2026-06-02 19:26:07 +09:00
anatawa12
aa14673468
Merge pull request #2951 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vite-8.0.16
chore(deps-dev): bump vite from 8.0.14 to 8.0.16 in /vrc-get-gui
2026-06-02 16:21:30 +09:00
anatawa12
36aa59b304
Merge pull request #2949 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/biomejs/biome-2.4.16
chore(deps-dev): bump @biomejs/biome from 2.4.15 to 2.4.16 in /vrc-get-gui
2026-06-02 16:10:27 +09:00
anatawa12
b61c44c64a
Merge pull request #2950 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/lucide-react-1.17.0
chore(deps): bump lucide-react from 1.16.0 to 1.17.0 in /vrc-get-gui
2026-06-02 16:10:11 +09:00
anatawa12
0a5ab490b8
Merge pull request #2947 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/i18next-f873b873ff
chore(deps): bump i18next from 26.2.0 to 26.3.0 in /vrc-get-gui in the i18next group across 1 directory
2026-06-02 16:09:50 +09:00
dependabot[bot]
cfc1b627eb
chore(deps-dev): bump vite from 8.0.14 to 8.0.16 in /vrc-get-gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.14 to 8.0.16.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 01:32:47 +00:00
dependabot[bot]
1b2065afe0
chore(deps-dev): bump @biomejs/biome in /vrc-get-gui
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.4.15 to 2.4.16.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.16/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 01:32:23 +00:00
anatawa12
4634c42410
Merge pull request #2946 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-116e156dcc
chore(deps): bump the tanstack-router group across 1 directory with 2 updates
2026-06-02 10:30:13 +09:00
dependabot[bot]
fd8b735ac9
chore(deps): bump the tanstack-router group across 1 directory with 2 updates
Bumps the tanstack-router group with 2 updates in the /vrc-get-gui directory: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).


Updates `@tanstack/react-router` from 1.170.8 to 1.170.10
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.170.10/packages/react-router)

Updates `@tanstack/router-plugin` from 1.168.11 to 1.168.13
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-plugin/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-plugin@1.168.13/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.170.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.168.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 01:13:54 +00:00
anatawa12
580c8da047
Merge pull request #2948 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/rollup/pluginutils-5.4.0
chore(deps-dev): bump @rollup/pluginutils from 5.3.0 to 5.4.0 in /vrc-get-gui
2026-06-02 10:07:13 +09:00
dependabot[bot]
0ebfb25263
chore(deps): bump lucide-react from 1.16.0 to 1.17.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.16.0 to 1.17.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.17.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 01:06:55 +00:00
dependabot[bot]
9eaf99b3d1
chore(deps): bump i18next
Bumps the i18next group with 1 update in the /vrc-get-gui directory: [i18next](https://github.com/i18next/i18next).


Updates `i18next` from 26.2.0 to 26.3.0
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.2.0...v26.3.0)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 01:06:08 +00:00
anatawa12
87753ceffa
Merge pull request #2945 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/react-cd43639a56
chore(deps): bump the react group in /vrc-get-gui with 3 updates
2026-06-02 10:02:18 +09:00
anatawa12
0fa954cef0
Merge pull request #2944 from vrc-get/dependabot/cargo/uuid-1.23.2
chore(deps): bump uuid from 1.23.1 to 1.23.2
2026-06-02 10:00:32 +09:00
anatawa12
41e25d4e86
Merge pull request #2943 from vrc-get/dependabot/cargo/sysinfo-0.39.3
chore(deps): bump sysinfo from 0.39.2 to 0.39.3
2026-06-02 10:00:15 +09:00
anatawa12
3c499f9d6a
Merge pull request #2942 from vrc-get/dependabot/cargo/reqwest-0.13.4
chore(deps): bump reqwest from 0.13.3 to 0.13.4
2026-06-02 09:59:47 +09:00
dependabot[bot]
65e37ff7af
chore(deps-dev): bump @rollup/pluginutils in /vrc-get-gui
Bumps [@rollup/pluginutils](https://github.com/rollup/plugins/tree/HEAD/packages/pluginutils) from 5.3.0 to 5.4.0.
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/pluginutils/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/pluginutils-v5.4.0/packages/pluginutils)

---
updated-dependencies:
- dependency-name: "@rollup/pluginutils"
  dependency-version: 5.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 00:15:03 +00:00
dependabot[bot]
48e1866ff3
chore(deps): bump the react group in /vrc-get-gui with 3 updates
Bumps the react group in /vrc-get-gui with 3 updates: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `react` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react)

Updates `@types/react` from 19.2.15 to 19.2.16
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.6 to 19.2.7
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.7/packages/react-dom)

Updates `@types/react` from 19.2.15 to 19.2.16
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 00:14:30 +00:00
dependabot[bot]
968ae63a4c
chore(deps): bump uuid from 1.23.1 to 1.23.2
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.23.1 to 1.23.2.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.23.1...v1.23.2)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.23.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 00:13:19 +00:00
dependabot[bot]
805be35ac6
chore(deps): bump sysinfo from 0.39.2 to 0.39.3
Bumps [sysinfo](https://github.com/GuillaumeGomez/sysinfo) from 0.39.2 to 0.39.3.
- [Changelog](https://github.com/GuillaumeGomez/sysinfo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GuillaumeGomez/sysinfo/compare/v0.39.2...v0.39.3)

---
updated-dependencies:
- dependency-name: sysinfo
  dependency-version: 0.39.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 00:12:47 +00:00
dependabot[bot]
901368c9bf
chore(deps): bump reqwest from 0.13.3 to 0.13.4
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.13.3 to 0.13.4.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.13.3...v0.13.4)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.13.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-02 00:12:33 +00:00
github-actions[bot]
09c8190634 v1.9.2-rc.0 2026-05-30 16:11:35 +00:00
anatawa12
5eed047fa4
Merge pull request #2940 from vrc-get/publish-workflow-crash
build: check-static-link for aarch64 linux is broken
2026-05-31 01:10:13 +09:00
anatawa12
056073834c
build: check-static-link for aarch64 linux is broken 2026-05-31 00:58:26 +09:00
anatawa12
c4117c7457
ci: allow dry-run for non-master branch 2026-05-31 00:37:37 +09:00
anatawa12
3bf6b96b93
ci: dry-run for cli build 2026-05-31 00:33:40 +09:00
anatawa12
00fb4d8546
ci: upload artifacts regardless build failure 2026-05-31 00:28:53 +09:00
github-actions[bot]
4d4c0c27d3 gui v1.1.6-rc.0 2026-05-30 14:43:02 +00:00
anatawa12
a31c947c1a
Merge pull request #2935 from nekochanfood/feat/reorder-user-repos
feat: リポジトリ一覧で並び替えができるようにする
2026-05-30 21:48:44 +09:00
nekochanfood
f6e677909c fix(gui): reject remove/reorder when settings.json drifted externally
remove/reorder targeted userRepos entries by array position only. An
external write to settings.json (another ALCOM instance, VCC, vrc-get
CLI, manual edit) between the frontend's last fetch and the call
could silently delete or reorder the wrong repo.

The frontend already has the expected id (part of TauriUserRepository),
so send it alongside the index and have the backend verify the repo at
that index still has the expected id before mutating. On mismatch,
reject with an `unrecoverable_str` error; the frontend's existing
onError + onSettled refetch rolls back optimistic state and shows the
on-disk truth.

- environment_remove_repository takes (index, expected_id)
- environment_reorder_repositories takes Vec<TauriUserRepositoryRef>;
  all pairs verified up front, no partial reorder on mismatch
- verify_repo_at_index helper centralises the lookup + comparison
2026-05-30 20:50:24 +09:00
nekochanfood
8b58270235 chore: move the order of the change 2026-05-30 20:27:04 +09:00
nekochanfood
c1b297e02a chore: clean up changelog entries for reorder/remove repo changes 2026-05-30 20:21:02 +09:00
Kissa Ruokanen
a0ec779fab
Merge pull request #1 from nekochanfood/feat/improve-duplicate-repo-handling
Feat/improve duplicate repo handling
2026-05-30 14:56:51 +09:00
nekochanfood
800278a0c3 style(vpm): satisfy fmt and clippy on reorder_user_repos_by_indices
Auto-applied cargo fmt for the collect-chain split, then folded the
nested `if let` into a let-chain and replaced the manual `if let Some`
loop with `into_iter().flatten()`.
2026-05-30 14:55:43 +09:00
nekochanfood
334492e5c6 refactor: clean up issues found in branch review
- vpm: drop unused id-based reorder_user_repos; reorder_user_repos_by_indices is the only caller
- CHANGELOG: reflect the actual public API surface (reorder_user_repos_by_indices, remove_repo_at_index)
- gui: rollback optimistic delete on error in RemoveRepositoryDialog, matching setHideRepository
- gui: demote per-reorder log from info to debug to reduce noise
2026-05-30 14:45:42 +09:00
nekochanfood
1a947b7a6c fix(gui): preserve listId identity for duplicate repos across refetch
Repos with duplicate (id, url) pairs had their per-row React keys
regenerated as `crypto.randomUUID()` on every refetch, causing scroll
reset and remount on the entire list. Stabilizing by `${id} ${url}`
key with an iteration-order counter would normally fix this, but for
duplicate-keyed rows the counter assignment depends on iteration
order: when two such repos swap positions, their slot keys swap, and
the lookup returns each other's UUID — React reconciles by tearing
both rows down (visible as a flicker on the row the dragged row
crossed over).

- Stabilize listId across refetch via listIdMapRef keyed on slot key
- Extract computeSlotKey helper for reuse
- Pin listIds to the new optimistic order in reorderMutation.onMutate
  so the post-refetch augmentation lookup returns the same listIds
- Snapshot and restore the previous map in onError so a failed reorder
  rolls back cleanly
2026-05-30 14:45:13 +09:00
nekochanfood
514f52a419 Revert "fix(gui): fix DnD drop artifact and item displacement flicker"
This reverts commit 6dfdd9c5f3.
2026-05-30 12:53:59 +09:00
nekochanfood
3e42f0de4e Revert "fix(gui): fix double-row artifact and scroll reset on dnd drop"
This reverts commit 21a0e19722.
2026-05-30 12:53:54 +09:00
nekochanfood
6dfdd9c5f3 fix(gui): fix DnD drop artifact and item displacement flicker
Replaced sideEffects-based opacity hack (broken by React re-renders) with
a droppingListId state that keeps the source row hidden for the duration of
the drop animation via React's own style prop.

Removed the visualIndex estimate (rowIndex ± 1 based on transform.y) that
caused continuous className toggling during drag; rows now use their stable
rowIndex for stripe coloring, eliminating the flicker.
2026-05-30 12:50:06 +09:00
nekochanfood
21a0e19722 fix(gui): fix double-row artifact and scroll reset on dnd drop
Two regressions introduced by the listId/UUID change:

- Scroll reset: crypto.randomUUID() in useMemo regenerated all listIds
  on every re-fetch, causing React to unmount/remount all rows and lose
  scroll position. Fixed by using String(r.index) instead — index is
  stable across re-fetches for items that haven't moved, so React can
  reconcile rows in place.

- Double-row artifact: on drop, isDragging becomes false before the
  DragOverlay drop animation completes, making the real row visible at
  the destination while the overlay is still animating there. Fixed by
  using defaultDropAnimationSideEffects to force opacity:0 on the
  original element for the duration of the drop animation.
2026-05-30 12:12:24 +09:00
nekochanfood
6ab9c49c94 fix(gui): stabilize repo list against duplicate IDs in userRepos
Repositories with duplicate `id` values in settings.json caused the
frontend list to break: React keys were non-unique, dnd-kit's
SortableContext misbehaved, and the Map lookup silently discarded
duplicate entries.

- Add `index` field to `TauriUserRepository` (position in the
  userRepos array, never persisted) so operations can target a
  specific entry regardless of ID uniqueness
- Replace ID-based remove/reorder commands with index-based variants
  (`remove_repo_at_index`, `reorder_user_repos_by_indices`) in both
  vpm_settings and the Tauri command layer
- Augment each repo with a frontend-only `listId` (crypto.randomUUID)
  used exclusively as React key and dnd-kit sortable item ID
2026-05-30 11:37:11 +09:00
Kissa Ruokanen
04adf285b5 style(gui): fix CSS selector formatting to satisfy Biome formatter 2026-05-30 09:41:43 +09:00
anatawa12
665513d0fc
Merge branch 'master' into feat/reorder-user-repos 2026-05-30 01:12:28 +09:00
anatawa12
6f8cd53159
Merge pull request #2939 from vrc-get/fix-buildx-devtools-not-working
build: cargo xtask build-alcom --devtools not working
2026-05-30 01:12:17 +09:00
anatawa12
ec6454b0d4
fix: cargo xtask build-alcom --devtools not working 2026-05-30 01:04:29 +09:00
nekochanfood
533a40b1eb fix(gui): account for vertical scrollbar width in ScrollableCardTable
When the vertical scrollbar is visible, its overlay covers the rightmost
10px of the table content. Add pe-2.5 to the content wrapper via CSS
so all ScrollableCardTable instances reserve space for the scrollbar.
2026-05-29 22:19:31 +09:00
nekochanfood
90c7e249cd fix(gui): fix scroll stuttering when dragging repository list items
- Move guiAnimation query and setHideRepository mutation from each
  RepositoryRow to PageBody, passing them down as props. Because
  useSortable subscribes all rows to DnD context, every pointermove
  during drag re-rendered every row. With O(N) expensive hooks per row
  this blocked the main thread for ~130ms per event (~7fps).

- Disable dnd-kit's built-in autoScroll (autoScroll={false}) and replace
  it with a useDragAutoScroll hook. dnd-kit's AutoScroller caused jitter
  due to wrong scroll-container detection in Radix UI ScrollArea and
  double-smoothing from the viewport's scroll-behavior: smooth. The
  custom hook targets the viewport directly via viewportRef and uses
  behavior: instant to avoid CSS smooth-scroll interference.

- Suppress background-color transition on rows during active drag to
  reduce paint operations when rows shift position.

- Replace orderedIds.includes() with a Set lookup in collisionDetection.
2026-05-29 20:56:30 +09:00
Kissa Ruokanen
e057838795 docs(changelog-gui): add entry for drag-and-drop repository reordering 2026-05-29 16:04:20 +09:00
Kissa Ruokanen
437a63bcc6 fix: sort @dnd-kit/core imports to satisfy biome lint 2026-05-29 16:02:18 +09:00
Kissa Ruokanen
836bf82351
Merge branch 'master' into feat/reorder-user-repos 2026-05-29 15:47:06 +09:00
Kissa Ruokanen
316c73a6b6 feat: animate drag overlay row color based on current drop position
Track the hovered droppable via onDragOver and compute the overlay's
visual index so its background color updates in real-time as it moves
between rows, matching the same bg-secondary/30 / transition spec used
by the sortable rows.
2026-05-29 15:38:35 +09:00
Kissa Ruokanen
ec04492af8 Merge branch 'feat/reorder-user-repos' of https://github.com/nekochanfood/vrc-get into feat/reorder-user-repos 2026-05-29 15:26:38 +09:00
Kissa Ruokanen
ebd117afd2 feat: animate row colors during drag with O(k) re-renders
Replace useDndContext() + arrayMove approach with transform.y sign
detection to compute visual row index. Previously all n rows subscribed
to the dnd context and re-rendered on every collision change, each
doing an O(n) arrayMove+indexOf -- O(n^2) total.

Now only rows whose transform changes re-render, and each computes its
visual index in O(1) from the sign of transform.y from useSortable.
Total cost is O(k) where k is the number of displaced rows (typically 1-2).

Also adds background-color to the inline transition string so the
200ms color animation works correctly alongside the transform animation,
and removes guiAnimation prop drilling through RepositoryTableBody.
2026-05-29 15:26:29 +09:00
Kissa Ruokanen
253a0266e6 fix: vertically center checkboxes in repository list
Wrap checkbox in flex container to eliminate inline-block descender
space, which caused the button to align to the text baseline rather
than the vertical center of the cell.
2026-05-29 15:14:27 +09:00
Kissa Ruokanen
0cf635e892 fix: vertically center checkboxes in repository list
Add align-middle to CELL_CLASS so all table cells use vertical-align: middle.
2026-05-29 14:56:48 +09:00
anatawa12
f8923dce1b
Merge pull request #2936 from vrc-get/funding-yml
docs: add FUNDING.yml
2026-05-29 14:52:50 +09:00
anatawa12
9fc228eed0
docs: add FUNDING.yml 2026-05-29 14:46:45 +09:00
Kissa Ruokanen
54113144a8 refactor: clean up animation-related code in repository list
- Remove redundant isDragging state; derive from activeId !== null
- Move TABLE_HEAD and DRAG_OVERLAY_MODIFIERS to module level to avoid
  per-render allocations
- Remove unnecessary ?? true fallback on initialData: true query result
- Eliminate guiAnimation prop drilling through RepositoryTableBody;
  RepositoryRow now reads directly from the shared React Query cache
2026-05-29 14:37:10 +09:00
Kissa Ruokanen
0ab6c9434b feat: add smooth drop animation for repository reordering
Use DragOverlay from @dnd-kit/core to show a floating row clone while
dragging, giving a smooth drop animation on release. The overlay uses
colgroup-based fixed column widths measured from the thead at drag start,
so columns align pixel-perfectly with the underlying table. Movement is
restricted to the vertical axis via a custom modifier.

Animation respects the existing gui-animation setting: dropAnimation is
disabled when animations are turned off, and non-active rows lose their
transition as well.

Extract shared RepositoryRowCells component so the table row and the drag
overlay render identical structure and styling from a single definition.
2026-05-29 14:33:52 +09:00
Kissa Ruokanen
9d94d8b929 refactor: memoize dragStyle and remove redundant index checks in handleDragEnd 2026-05-29 14:14:14 +09:00
Kissa Ruokanen
d1887eb467 fix: eliminate drag stutter by using custom collision detection
Replace live orderedIds updates during onDragOver with a custom
collision detection that filters droppable targets to user repos only.
This ensures `over` is always a valid user repo (clamping to the
boundary when the cursor leaves the list), so dnd-kit handles all
visual movement through CSS transforms without DOM reordering.
Eliminates the position warp that occurred when items swapped.
2026-05-29 14:06:13 +09:00
Kissa Ruokanen
45ed34f573 fix: preserve drag position when cursor leaves list bounds
Track last valid sort order via dragOverOrderRef during onDragOver so
that when the pointer leaves the sortable region (triggering cancel or
landing on a non-user-repo row), the item stays at its last reached
position instead of snapping back or jumping to the end of the list.
Also disable pointer-events on HNavBar while dragging to prevent Radix
UI from stealing pointer capture.
2026-05-29 13:39:11 +09:00
Kissa Ruokanen
930715960e fix: prevent snap-back when dragging outside list bounds
Use closestCenter collision detection so over never becomes null
when the cursor moves beyond the top or bottom of the sortable list.
2026-05-29 13:21:26 +09:00
Kissa Ruokanen
8db24b7b7c feat: implement drag-and-drop reordering of user repositories
Use @dnd-kit/core and @dnd-kit/sortable to wire up the existing drag
handles so users can reorder repositories by dragging. DndContext is
placed at the page level so pointer tracking is not lost when the cursor
moves outside the list area. Adds an info log in the Rust command so the
new order is visible in the app log viewer.
2026-05-29 13:19:33 +09:00
Kissa Ruokanen
44ed683c23 feat: dim drag handle and show not-allowed cursor for non-reorderable repositories
Official and curated repositories cannot be reordered, so their drag
handles are now rendered with opacity-50 and cursor-not-allowed to
visually indicate they are not interactive, consistent with how their
remove buttons are already disabled.
2026-05-29 12:40:56 +09:00
Kissa Ruokanen
c248b0ed55 chore: regenerate bindings.ts with environmentReorderRepositories 2026-05-29 10:57:51 +09:00
Kissa Ruokanen
9d11a5e816
Merge branch 'master' into feat/reorder-user-repos 2026-05-29 10:48:40 +09:00
Kissa Ruokanen
81d66143c9 feat: add environment_reorder_repositories Tauri command
Add `reorder_user_repos` to `VpmSettings` and `Settings`, and expose it
as the `environment_reorder_repositories` Tauri command to allow
reordering `userRepos` in `settings.json`.
2026-05-29 10:36:49 +09:00
anatawa12
6f143ac5e3
Merge pull request #2933 from vrc-get/settings-json-corruption-recover
recover from settings.json corruption with backup file
2026-05-29 10:29:58 +09:00
anatawa12
f44633a2ad
fix: toast are not shown because of delay in webview2 initialization 2026-05-29 09:30:19 +09:00
anatawa12
3fb8281a47
Merge pull request #2934 from JustBuddy/german-translation
chore(l10n): [de_DE] update locale
2026-05-29 08:53:35 +09:00
JustBuddy
244946c234
chore(l10n): [de_DE] update locale 2026-05-28 22:57:28 +02:00
anatawa12
ccd252f8aa
docs(changelog-gui): We also added a backup file to recover from settings.json corruption 2026-05-28 23:31:10 +09:00
anatawa12
c2b2b9b491
feat: show warning toast when settings.json is recovered from corruption 2026-05-28 23:27:23 +09:00
anatawa12
9decfe400c
feat: create backup of settings.json to recover from corruption caused by VCC
VCC sometimes leaves settings.json corrupted and filled with NUL bytes,
likely because file contents are not fully synced to disk before or during writing.
vrc-get already uses fsynced temp-file replacement when writing settings.json,
but this does not protect against corruption caused by external writes.
This commit adds a backup file to recover from such corruption.
2026-05-28 23:21:41 +09:00
anatawa12
35e7537a90
Merge pull request #2932 from CirnoV/locale/ko-KR
chore(l10n): [ko] update locale
2026-05-28 20:09:32 +09:00
CirnoV
1800951c12 chore(l10n): [ko] update locale 2026-05-28 19:52:48 +09:00
anatawa12
76b0f05651
feat: recover project list from settings.json when settings json is corrupted 2026-05-28 19:46:03 +09:00
anatawa12
f45ee6514e
Merge pull request #2911 from Spokeek/french-translation
Update FR locales for 1.1.6
2026-05-28 10:23:12 +09:00
Spokeek
d421ee04b2
remove === prefix 2026-05-27 18:51:40 +02:00
Spokeek
bd92649248
Fix json5 2026-05-27 18:46:13 +02:00
Spokeek
68be14aa90
Update FR locales for 1.1.6 2026-05-27 18:20:57 +02:00
anatawa12
dd9673c2cb
Merge pull request #2924 from vrc-community-assets-tc-translators/master
chore(l10n): [zh_hant] update locale
2026-05-27 19:11:15 +09:00
anatawa12
73cfa96f45
Merge pull request #2930 from vrc-get/support-empty-string-for-optional-url-field
chore: allow empty `changelogUrl` and `documentationUrl`
2026-05-26 22:58:20 +09:00
anatawa12
fa22fc3611
docs(changelog): Empty string for documentationUrl and changelogUrl are now allowed and ignored 2026-05-26 21:13:24 +09:00
anatawa12
8b61a0c806
chore: allow blank changelogUrl and documentationUrl 2026-05-26 20:13:55 +09:00
anatawa12
c37758d4c1
chore: allow empty changelogUrl and documentationUrl 2026-05-26 19:49:26 +09:00
夜嵐蝶Alma
37688599ae chore(l10n): [zh_hant] update locale 2026-05-25 21:40:04 +08:00
夜嵐蝶Alma
fcb0c5263d
Merge branch 'vrc-get:master' into master 2026-05-25 21:37:32 +08:00
github-actions[bot]
a7e19a6479 gui v1.1.6-beta.2 2026-05-25 11:36:25 +00:00
anatawa12
f0a7cbd050
Merge pull request #2926 from vrc-get/dependabot/cargo/log-0.4.30
chore(deps): bump log from 0.4.29 to 0.4.30
2026-05-25 20:15:45 +09:00
anatawa12
a9322f4d64
Merge pull request #2927 from vrc-get/dependabot/cargo/tar-0.4.46
chore(deps): bump tar from 0.4.45 to 0.4.46
2026-05-25 20:14:54 +09:00
dependabot[bot]
0c895bf4a5
chore(deps): bump tar from 0.4.45 to 0.4.46
Bumps [tar](https://github.com/composefs/tar-rs) from 0.4.45 to 0.4.46.
- [Release notes](https://github.com/composefs/tar-rs/releases)
- [Commits](https://github.com/composefs/tar-rs/compare/0.4.45...0.4.46)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 0.4.46
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 11:07:42 +00:00
dependabot[bot]
07e7279c31
chore(deps): bump log from 0.4.29 to 0.4.30
Bumps [log](https://github.com/rust-lang/log) from 0.4.29 to 0.4.30.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.29...0.4.30)

---
updated-dependencies:
- dependency-name: log
  dependency-version: 0.4.30
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 11:07:29 +00:00
anatawa12
a9e135b940
Merge pull request #2862 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tauri-apps/api-2.11.0
chore(deps): bump @tauri-apps/api from 2.10.1 to 2.11.0 in /vrc-get-gui
2026-05-25 19:51:23 +09:00
anatawa12
d2aca1554c
Merge pull request #2890 from vrc-get/dependabot/cargo/tauri-347ba455b6
chore(deps): bump the tauri group across 1 directory with 2 updates
2026-05-25 19:48:59 +09:00
anatawa12
5be2c13984
chore: support LIBDBUS_1_3 versioned symbol 2026-05-25 19:40:21 +09:00
anatawa12
1b1a0eefae
Merge pull request #2923 from vrc-get/dependabot/cargo/rpm-0.24.0
chore(deps): bump rpm from 0.22.0 to 0.24.0
2026-05-25 17:34:11 +09:00
copilot-swe-agent[bot]
3e94514b13
fix(xtask): handle non-numeric ELF symbol versions in linux bundling 2026-05-25 08:05:17 +00:00
copilot-swe-agent[bot]
56a32bad04
fix: add payload feature to rpm dependency to fix compilation errors 2026-05-25 07:59:08 +00:00
dependabot[bot]
fb6a6538d7
chore(deps): bump @tauri-apps/api from 2.10.1 to 2.11.0 in /vrc-get-gui
Bumps [@tauri-apps/api](https://github.com/tauri-apps/tauri) from 2.10.1 to 2.11.0.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/api-v2.10.1...@tauri-apps/api-v2.11.0)

---
updated-dependencies:
- dependency-name: "@tauri-apps/api"
  dependency-version: 2.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 07:52:24 +00:00
anatawa12
ab64f403a5
Merge pull request #2910 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-fc9df4cbb5
chore(deps): bump the tanstack-router group across 1 directory with 3 updates
2026-05-25 16:50:04 +09:00
dependabot[bot]
96d8ced3bb
chore(deps): bump rpm from 0.22.0 to 0.24.0
Bumps [rpm](https://github.com/rpm-rs/rpm) from 0.22.0 to 0.24.0.
- [Changelog](https://github.com/rpm-rs/rpm-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rpm-rs/rpm/compare/v0.22.0...v0.24.0)

---
updated-dependencies:
- dependency-name: rpm
  dependency-version: 0.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 07:43:39 +00:00
anatawa12
bde10abd3b
Merge pull request #2896 from vrc-get/dependabot/cargo/object-0.39.1
chore(deps): bump object from 0.39.0 to 0.39.1
2026-05-25 16:41:19 +09:00
dependabot[bot]
e3313f0327
chore(deps): bump the tanstack-router group across 1 directory with 3 updates
Bumps the tanstack-router group with 3 updates in the /vrc-get-gui directory: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [@tanstack/router-devtools](https://github.com/TanStack/router/tree/HEAD/packages/router-devtools) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).


Updates `@tanstack/react-router` from 1.168.25 to 1.170.8
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.170.8/packages/react-router)

Updates `@tanstack/router-devtools` from 1.166.13 to 1.167.0
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-devtools/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-devtools@1.167.0/packages/router-devtools)

Updates `@tanstack/router-plugin` from 1.167.28 to 1.168.11
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-plugin/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-plugin@1.168.11/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.170.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-devtools"
  dependency-version: 1.167.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.168.6
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 07:40:08 +00:00
anatawa12
bb0b8cda55
Merge pull request #2908 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tauri-apps/cli-2.11.2
chore(deps-dev): bump @tauri-apps/cli from 2.10.1 to 2.11.2 in /vrc-get-gui
2026-05-25 16:37:44 +09:00
anatawa12
11b6b1cad4
Merge pull request #2877 from vrc-get/dependabot/cargo/rpassword-7.5.2
chore(deps): bump rpassword from 7.4.0 to 7.5.3
2026-05-25 15:29:41 +09:00
dependabot[bot]
92cff628c2
chore(deps): bump rpassword from 7.4.0 to 7.5.3
Bumps [rpassword](https://github.com/conradkleinespel/rpassword) from 7.4.0 to 7.5.3.
- [Release notes](https://github.com/conradkleinespel/rpassword/releases)
- [Commits](https://github.com/conradkleinespel/rpassword/compare/v7.4.0...v7.5.3)

---
updated-dependencies:
- dependency-name: rpassword
  dependency-version: 7.5.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:49:03 +00:00
dependabot[bot]
3f3465d74b
chore(deps-dev): bump @tauri-apps/cli in /vrc-get-gui
Bumps [@tauri-apps/cli](https://github.com/tauri-apps/tauri) from 2.10.1 to 2.11.2.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v2.10.1...@tauri-apps/cli-v2.11.2)

---
updated-dependencies:
- dependency-name: "@tauri-apps/cli"
  dependency-version: 2.11.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:44:08 +00:00
dependabot[bot]
d1c28f6479
chore(deps): bump the tauri group across 1 directory with 2 updates
Bumps the tauri group with 1 update in the / directory: [tauri](https://github.com/tauri-apps/tauri).


Updates `tauri` from 2.10.3 to 2.11.2
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/tauri-v2.10.3...tauri-v2.11.2)

Updates `tauri-build` from 2.5.6 to 2.6.2
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/tauri-build-v2.5.6...tauri-build-v2.6.2)

---
updated-dependencies:
- dependency-name: tauri
  dependency-version: 2.11.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tauri
- dependency-name: tauri-build
  dependency-version: 2.6.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tauri
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:34:01 +00:00
anatawa12
089427cbfa
Merge pull request #2907 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/lucide-react-1.16.0
chore(deps): bump lucide-react from 1.11.0 to 1.16.0 in /vrc-get-gui
2026-05-25 14:31:21 +09:00
anatawa12
375894c6c3
Merge pull request #2894 from vrc-get/dependabot/cargo/tauri-plugin-single-instance-2.4.2
chore(deps): bump tauri-plugin-single-instance from 2.4.1 to 2.4.2
2026-05-25 14:29:15 +09:00
anatawa12
eed54886b8
Merge pull request #2895 from vrc-get/dependabot/cargo/serde_with-3.20.0
chore(deps): bump serde_with from 3.18.0 to 3.20.0
2026-05-25 14:28:31 +09:00
anatawa12
11c1b7048b
Merge pull request #2914 from vrc-get/dependabot/cargo/openssl-0.10.80
chore(deps): bump openssl from 0.10.77 to 0.10.80
2026-05-25 14:28:08 +09:00
anatawa12
b613f834ea
Merge pull request #2925 from vrc-get/dependabot/cargo/rustls-webpki-0.103.13
chore(deps): bump rustls-webpki from 0.103.12 to 0.103.13
2026-05-25 14:27:17 +09:00
anatawa12
5d9c6ce802
Merge pull request #2870 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tailwindcss-8cf3a4f383
chore(deps-dev): bump @tailwindcss/vite from 4.2.4 to 4.3.0 in /vrc-get-gui in the tailwindcss group across 1 directory
2026-05-25 14:26:24 +09:00
anatawa12
f15e489515
Merge pull request #2868 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/i18next-50f7a7efee
chore(deps): bump the i18next group across 1 directory with 2 updates
2026-05-25 14:25:56 +09:00
anatawa12
687904918d
Merge pull request #2891 from vrc-get/dependabot/cargo/clap-4445c6f202
chore(deps): bump clap_complete from 4.6.2 to 4.6.5 in the clap group across 1 directory
2026-05-25 14:25:30 +09:00
anatawa12
c5d38a1f6e
Merge pull request #2892 from vrc-get/dependabot/cargo/tauri-plugin-dialog-2.7.1
chore(deps): bump tauri-plugin-dialog from 2.7.0 to 2.7.1
2026-05-25 14:24:45 +09:00
anatawa12
55635bbe9c
Merge pull request #2893 from vrc-get/dependabot/cargo/nix-0.31.3
chore(deps): bump nix from 0.31.2 to 0.31.3
2026-05-25 14:24:27 +09:00
anatawa12
ca30b889f1
Merge pull request #2906 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vitejs/plugin-react-6.0.2
chore(deps-dev): bump @vitejs/plugin-react from 6.0.1 to 6.0.2 in /vrc-get-gui
2026-05-25 14:23:55 +09:00
anatawa12
0a17c9a1cd
Merge pull request #2897 from vrc-get/dependabot/cargo/tokio-1.52.3
chore(deps): bump tokio from 1.52.1 to 1.52.3
2026-05-25 14:22:42 +09:00
anatawa12
50aba0530e
Merge pull request #2899 from vrc-get/dependabot/cargo/plist-1.9.0
chore(deps): bump plist from 1.8.0 to 1.9.0
2026-05-25 14:22:14 +09:00
anatawa12
33be110c7a
Merge pull request #2900 from vrc-get/dependabot/cargo/async-compression-0.4.42
chore(deps): bump async-compression from 0.4.41 to 0.4.42
2026-05-25 14:21:54 +09:00
anatawa12
2aad318387
Merge pull request #2871 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/biomejs/biome-2.4.15
chore(deps-dev): bump @biomejs/biome from 2.4.13 to 2.4.15 in /vrc-get-gui
2026-05-25 14:20:26 +09:00
anatawa12
43ca6755ff
Merge pull request #2872 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tailwind-merge-3.6.0
chore(deps): bump tailwind-merge from 3.5.0 to 3.6.0 in /vrc-get-gui
2026-05-25 14:19:38 +09:00
anatawa12
92bc6cf38e
Merge pull request #2901 from vrc-get/dependabot/cargo/reqwest-0.13.3
chore(deps): bump reqwest from 0.13.2 to 0.13.3
2026-05-25 14:18:28 +09:00
anatawa12
8d293e5e69
Merge pull request #2902 from vrc-get/dependabot/cargo/open-5.3.5
chore(deps): bump open from 5.3.3 to 5.3.5
2026-05-25 14:16:31 +09:00
anatawa12
1e9a100d9c
Merge pull request #2903 from vrc-get/dependabot/cargo/sysinfo-0.39.2
chore(deps): bump sysinfo from 0.38.4 to 0.39.2
2026-05-25 14:14:20 +09:00
anatawa12
8624950ca5
Merge pull request #2904 from vrc-get/dependabot/cargo/trash-5.2.6
chore(deps): bump trash from 5.2.5 to 5.2.6
2026-05-25 14:12:10 +09:00
anatawa12
57c9a54d37
Merge pull request #2918 from vrc-get/dependabot/cargo/either-1.16.0
chore(deps): bump either from 1.15.0 to 1.16.0
2026-05-25 14:10:28 +09:00
dependabot[bot]
6470169cf1
chore(deps): bump object from 0.39.0 to 0.39.1
Bumps [object](https://github.com/gimli-rs/object) from 0.39.0 to 0.39.1.
- [Changelog](https://github.com/gimli-rs/object/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/v0.39.0...v0.39.1)

---
updated-dependencies:
- dependency-name: object
  dependency-version: 0.39.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:09:18 +00:00
dependabot[bot]
795699baf0
chore(deps): bump lucide-react from 1.11.0 to 1.16.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.11.0 to 1.16.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.16.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:07:04 +00:00
dependabot[bot]
7fbf8c60d1
chore(deps-dev): bump @vitejs/plugin-react in /vrc-get-gui
Bumps [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.0.2/packages/plugin-react)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react"
  dependency-version: 6.0.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:02:33 +00:00
anatawa12
a5c5d6e128
Merge pull request #2921 from vrc-get/dependabot/cargo/serde_json-1.0.150
chore(deps): bump serde_json from 1.0.149 to 1.0.150
2026-05-25 14:01:58 +09:00
dependabot[bot]
a3aa50256f
chore(deps): bump the i18next group across 1 directory with 2 updates
Bumps the i18next group with 2 updates in the /vrc-get-gui directory: [i18next](https://github.com/i18next/i18next) and [react-i18next](https://github.com/i18next/react-i18next).


Updates `i18next` from 26.0.8 to 26.2.0
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.0.8...v26.2.0)

Updates `react-i18next` from 17.0.4 to 17.0.8
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v17.0.4...v17.0.8)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: i18next
- dependency-name: react-i18next
  dependency-version: 17.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:01:37 +00:00
dependabot[bot]
498eedc1d6
chore(deps): bump tailwind-merge from 3.5.0 to 3.6.0 in /vrc-get-gui
Bumps [tailwind-merge](https://github.com/dcastil/tailwind-merge) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/dcastil/tailwind-merge/releases)
- [Commits](https://github.com/dcastil/tailwind-merge/compare/v3.5.0...v3.6.0)

---
updated-dependencies:
- dependency-name: tailwind-merge
  dependency-version: 3.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 05:01:32 +00:00
anatawa12
c863bc4461
Merge pull request #2919 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack/react-query-5.100.14
chore(deps): bump @tanstack/react-query from 5.100.5 to 5.100.14 in /vrc-get-gui
2026-05-25 13:58:58 +09:00
anatawa12
8fd964fa83
Merge pull request #2920 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/react-388b784d7d
chore(deps): bump the react group across 1 directory with 3 updates
2026-05-25 13:57:55 +09:00
dependabot[bot]
c7012c5e81
chore(deps): bump rustls-webpki from 0.103.12 to 0.103.13
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.12 to 0.103.13.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.12...v/0.103.13)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 04:57:40 +00:00
anatawa12
cf6c82adbd
Merge pull request #2922 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vite-8.0.14
chore(deps-dev): bump vite from 8.0.10 to 8.0.14 in /vrc-get-gui
2026-05-25 13:56:38 +09:00
夜嵐蝶Alma
e0931be79a chore(l10n): [zh_hant] update locale 2026-05-25 11:08:29 +08:00
dependabot[bot]
e0dce679d7
chore(deps): bump serde_json from 1.0.149 to 1.0.150
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.149 to 1.0.150.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.149...v1.0.150)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.150
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:32:04 +00:00
dependabot[bot]
f9ca613378
chore(deps-dev): bump vite from 8.0.10 to 8.0.14 in /vrc-get-gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.10 to 8.0.14.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.14/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:32:04 +00:00
dependabot[bot]
0fa0c7ca00
chore(deps): bump clap_complete in the clap group across 1 directory
Bumps the clap group with 1 update in the / directory: [clap_complete](https://github.com/clap-rs/clap).


Updates `clap_complete` from 4.6.2 to 4.6.5
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.6.2...clap_complete-v4.6.5)

---
updated-dependencies:
- dependency-name: clap_complete
  dependency-version: 4.6.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: clap
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:31:57 +00:00
dependabot[bot]
9c1465868e
chore(deps): bump the react group across 1 directory with 3 updates
Bumps the react group with 3 updates in the /vrc-get-gui directory: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom).


Updates `react` from 19.2.5 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react)

Updates `@types/react` from 19.2.14 to 19.2.15
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.2.5 to 19.2.6
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.6/packages/react-dom)

Updates `@types/react` from 19.2.14 to 19.2.15
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:31:52 +00:00
dependabot[bot]
874492f3fc
chore(deps): bump @tanstack/react-query in /vrc-get-gui
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.100.5 to 5.100.14.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.100.14/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.100.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:31:50 +00:00
dependabot[bot]
8588a7276c
chore(deps-dev): bump @tailwindcss/vite
Bumps the tailwindcss group with 1 update in the /vrc-get-gui directory: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite).


Updates `@tailwindcss/vite` from 4.2.4 to 4.3.0
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.0/packages/@tailwindcss-vite)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: tailwindcss
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:31:47 +00:00
dependabot[bot]
0a5b9c38eb
chore(deps): bump either from 1.15.0 to 1.16.0
Bumps [either](https://github.com/rayon-rs/either) from 1.15.0 to 1.16.0.
- [Commits](https://github.com/rayon-rs/either/compare/1.15.0...1.16.0)

---
updated-dependencies:
- dependency-name: either
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-25 02:31:40 +00:00
anatawa12
17a28fa609
Merge pull request #2916 from vrc-get/workaround-world-sdk
chore: workaround VRCDefaultWorldScene generation issue
2026-05-24 02:09:01 +09:00
anatawa12
099883a33d
docs(changelog): Added workaround for VRCDefaultWorldScene generation issue in SDK 3.10.2 or later 2026-05-24 01:49:55 +09:00
anatawa12
5cb60c4002
chore: workaround VRCDefaultWorldScene generation issue
workarounds https://feedback.vrchat.com/sdk-bug-reports/p/3102-3103-vrcscenetemplateinitializer-does-not-create-sample-scene-if-udon-prepr
2026-05-24 01:45:01 +09:00
anatawa12
cdb1b8294d
Merge pull request #2915 from vrc-get/update_locale_ja
chore(l10n): [ja] update locale
2026-05-23 23:43:50 +09:00
Sayamame-beans
0de963736f chore(l10n): [ja] update locale 2026-05-23 02:33:25 +09:00
anatawa12
0026f5029c
Merge pull request #2731 from lonelyicer/feat/show-hidden-packages
feat: show hidden packages
2026-05-22 18:26:18 +09:00
dependabot[bot]
987357354e
chore(deps): bump openssl from 0.10.77 to 0.10.80
Bumps [openssl](https://github.com/rust-openssl/rust-openssl) from 0.10.77 to 0.10.80.
- [Release notes](https://github.com/rust-openssl/rust-openssl/releases)
- [Commits](https://github.com/rust-openssl/rust-openssl/compare/openssl-v0.10.77...openssl-v0.10.80)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.80
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-22 06:41:01 +00:00
anatawa12
f13add3409
Merge pull request #2888 from vrc-get/fix-updater
Fix updater.exe
2026-05-22 15:39:37 +09:00
anatawa12
2d7fefb34c
fix: shlwapi.dll is not part of static link checker 2026-05-22 09:19:44 +09:00
RingLo_
e625630856
feat: show list of sources that we should enable 2026-05-20 05:01:37 +08:00
anatawa12
4943a671e0
fix: compile error 2026-05-19 00:31:16 +09:00
dependabot[bot]
6e63cdba25
chore(deps): bump trash from 5.2.5 to 5.2.6
Bumps [trash](https://github.com/ArturKovacs/trash) from 5.2.5 to 5.2.6.
- [Release notes](https://github.com/ArturKovacs/trash/releases)
- [Changelog](https://github.com/Byron/trash-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ArturKovacs/trash/compare/v5.2.5...v5.2.6)

---
updated-dependencies:
- dependency-name: trash
  dependency-version: 5.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:26:43 +00:00
dependabot[bot]
e04d1ee919
chore(deps): bump sysinfo from 0.38.4 to 0.39.2
Bumps [sysinfo](https://github.com/GuillaumeGomez/sysinfo) from 0.38.4 to 0.39.2.
- [Changelog](https://github.com/GuillaumeGomez/sysinfo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GuillaumeGomez/sysinfo/compare/v0.38.4...v0.39.2)

---
updated-dependencies:
- dependency-name: sysinfo
  dependency-version: 0.39.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:26:23 +00:00
dependabot[bot]
a4992e3973
chore(deps): bump open from 5.3.3 to 5.3.5
Bumps [open](https://github.com/Byron/open-rs) from 5.3.3 to 5.3.5.
- [Release notes](https://github.com/Byron/open-rs/releases)
- [Changelog](https://github.com/Byron/open-rs/blob/main/changelog.md)
- [Commits](https://github.com/Byron/open-rs/compare/v5.3.3...v5.3.5)

---
updated-dependencies:
- dependency-name: open
  dependency-version: 5.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:26:01 +00:00
dependabot[bot]
185b7aa8b7
chore(deps): bump reqwest from 0.13.2 to 0.13.3
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.13.2 to 0.13.3.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.13.2...v0.13.3)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.13.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:25:48 +00:00
dependabot[bot]
24ae2b33de
chore(deps): bump async-compression from 0.4.41 to 0.4.42
Bumps [async-compression](https://github.com/Nullus157/async-compression) from 0.4.41 to 0.4.42.
- [Release notes](https://github.com/Nullus157/async-compression/releases)
- [Commits](https://github.com/Nullus157/async-compression/compare/async-compression-v0.4.41...async-compression-v0.4.42)

---
updated-dependencies:
- dependency-name: async-compression
  dependency-version: 0.4.42
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:25:32 +00:00
dependabot[bot]
1b928b150b
chore(deps): bump plist from 1.8.0 to 1.9.0
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Changelog](https://github.com/ebarnard/rust-plist/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.8.0...v1.9.0)

---
updated-dependencies:
- dependency-name: plist
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:25:19 +00:00
dependabot[bot]
2d859d993e
chore(deps): bump tokio from 1.52.1 to 1.52.3
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.52.1 to 1.52.3.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.52.1...tokio-1.52.3)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.52.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:24:49 +00:00
dependabot[bot]
4018f718a7
chore(deps): bump serde_with from 3.18.0 to 3.20.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.18.0 to 3.20.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.18.0...v3.20.0)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.20.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:24:21 +00:00
dependabot[bot]
de73063b98
chore(deps): bump tauri-plugin-single-instance from 2.4.1 to 2.4.2
Bumps [tauri-plugin-single-instance](https://github.com/tauri-apps/plugins-workspace) from 2.4.1 to 2.4.2.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/fs-v2.4.1...fs-v2.4.2)

---
updated-dependencies:
- dependency-name: tauri-plugin-single-instance
  dependency-version: 2.4.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:24:08 +00:00
dependabot[bot]
d6ea9b3079
chore(deps): bump nix from 0.31.2 to 0.31.3
Bumps [nix](https://github.com/nix-rust/nix) from 0.31.2 to 0.31.3.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.31.2...v0.31.3)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.31.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:23:53 +00:00
dependabot[bot]
eaf09ecb6a
chore(deps): bump tauri-plugin-dialog from 2.7.0 to 2.7.1
Bumps [tauri-plugin-dialog](https://github.com/tauri-apps/plugins-workspace) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/log-v2.7.0...log-v2.7.1)

---
updated-dependencies:
- dependency-name: tauri-plugin-dialog
  dependency-version: 2.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-18 12:23:37 +00:00
RingLo_
d74c7b16b8
chore: use visibleSources in package list and add tooltip 2026-05-18 12:04:38 +08:00
RingLo_
6c46983cae
Merge branch 'master' into feat/show-hidden-packages 2026-05-18 11:40:16 +08:00
anatawa12
36b76933fc
docs(changelog-gui): add pr number to changelog entry 2026-05-17 03:11:52 +09:00
anatawa12
ad7efa259e
Merge pull request #2887 from fivezett/fix-toastify-dark-theme
fix(style): keep react-toastify toasts in sync with dark mode
2026-05-17 03:08:19 +09:00
anatawa12
97042ebc6a
chore: add windows manifest resource to disable Installer detection technology 2026-05-17 03:03:34 +09:00
anatawa12
e135092745
fix: installer file should always have .exe extension 2026-05-17 02:58:19 +09:00
fivezett
5607daf7b5 fix(style): keep react-toastify toasts in sync with dark mode
react-toastify 11.1.0 changed its CSS injection to append the <style>
to the end of <head> on mount, so its `:root` variable defaults
started overriding ours by source order, and toasts stopped following
the dark theme.

Declaring the `--toastify-*` overrides on `body` instead of `:root`
makes toasts inherit them regardless of stylesheet order, since
react-toastify only declares these variables on `:root`.
2026-05-17 01:51:08 +09:00
github-actions[bot]
2861fcaa68 gui v1.1.6-beta.1 2026-05-15 15:15:00 +00:00
anatawa12
8a71e426d6
Merge pull request #2882 from vrc-get/additional-headers-for-future-extension
feat: include version number and os in the header for future extension
2026-05-15 22:25:20 +09:00
anatawa12
cd242e389b
docs(changelog): add pr number to changelog 2026-05-15 22:14:36 +09:00
anatawa12
95dc46666b
feat: include version number and os in the header for future extension 2026-05-15 22:12:32 +09:00
anatawa12
f0c4de7d78
Merge pull request #2881 from vrc-get/updater-windows-fixes
windows updater fixes
2026-05-15 22:06:32 +09:00
anatawa12
e9a994a932
Merge pull request #2880 from fivezett/createProject1RowLoading
style: align creating project dialog spinner and label on one row
2026-05-15 19:28:46 +09:00
anatawa12
803fbf3395
fix: non-windows platform build failure 2026-05-15 19:22:05 +09:00
anatawa12
20d24b496b
docs(changelog): add pr number to changelog entry 2026-05-15 19:21:52 +09:00
anatawa12
a1ff52fed4
fix: updater json does not include args 2026-05-15 19:18:56 +09:00
anatawa12
4a99cfe4c9
Merge branch 'master' into createProject1RowLoading 2026-05-15 17:31:17 +09:00
fivezett
8b13244b74 style: align creating project dialog spinner and label on one row 2026-05-15 17:24:50 +09:00
anatawa12
875a989d52
fix: failure from ShellExecuteW is not handled 2026-05-15 15:19:05 +09:00
anatawa12
973c91c9c0
fix: close file before launching installer 2026-05-15 15:16:45 +09:00
anatawa12
3d2dd2e058
Merge pull request #2875 from vrc-get/setup-exe-in-zip
fix: setup.exe.zip is unexpectedly unavailable
2026-05-15 03:50:00 +09:00
anatawa12
16d8a787ec
Merge pull request #2876 from vrc-get/debug-only-updater-override
feat: debug-only updater overrides
2026-05-15 03:49:46 +09:00
anatawa12
4ccc7d7bc8
feat: debug-only updater overrides 2026-05-14 14:58:29 +09:00
anatawa12
8c8315f57d
fix: setup.exe.zip is unexpectedly unavailable 2026-05-14 14:47:04 +09:00
anatawa12
4cac964713
Merge pull request #2867 from vrc-get/copy-parallelism-limit
fix: too many open files when copying project
2026-05-14 00:54:16 +09:00
anatawa12
fb32bd97cd
docs(changelog-gui): Too many open files when copying project 2026-05-14 00:33:41 +09:00
anatawa12
1a70d2db82
Merge pull request #2851 from vrc-get/datailed-error-message
chore: much detailed error message
2026-05-14 00:32:27 +09:00
dependabot[bot]
cacb9a5e9a
chore(deps-dev): bump @biomejs/biome in /vrc-get-gui
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.4.13 to 2.4.15.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.15/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.15
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-11 09:56:18 +00:00
anatawa12
4700bfa2c0
fix: too many open files when copying project 2026-05-08 20:41:53 +09:00
anatawa12
223be38368
Merge pull request #2850 from vrc-get/unity-hub
fix: Unity from editors-v2.json may not be recognized
2026-05-02 14:54:02 +09:00
anatawa12
523ede22ea
docs(changelog): New Unity Hub loading method fixes 2026-05-02 14:47:58 +09:00
anatawa12
38a7649fbd
Merge pull request #2852 from vrc-get/copilot/fix-typo-in-documentation
Fix typo in SHA256 hash mismatch error message
2026-05-02 03:09:38 +09:00
anatawa12
d61b46ded8
fix: incorrect configuration dir for unity hub on linux 2026-05-02 00:54:33 +09:00
copilot-swe-agent[bot]
4756f6c115
fix: fix typo in SHA256 hash error message (his -> This)
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/bea04e30-e11e-4933-9ea9-2b563af74d47

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-05-01 02:19:14 +00:00
anatawa12
e14806c72c
chore: much detailed error message 2026-05-01 09:56:02 +09:00
anatawa12
8324a4ec04
fix: Unity from editors-v2.json may not be recognized 2026-05-01 09:29:07 +09:00
anatawa12
a9f2a9713f
Merge pull request #2849 from vrc-get/enforce-zip-hash
chore!: package hash check is now enforced when installing package
2026-04-30 19:22:18 +09:00
anatawa12
40cd4487d5
Merge pull request #2848 from vrc-get/improve-error-messages
fix: fix "[object Object]" appearing as an error message
2026-04-30 10:33:55 +09:00
anatawa12
56a2139df6
docs(changelog): Package hash checks are now enforced when installing packages 2026-04-30 10:00:48 +09:00
anatawa12
175008956c
style: biome format fix 2026-04-30 09:58:55 +09:00
anatawa12
00a928e58e
chore!: package hash check is now enforced when installing package 2026-04-30 09:56:17 +09:00
anatawa12
7037a758bc
docs(changelog): Uninformative [object Object] appearing as an error message 2026-04-30 09:39:27 +09:00
anatawa12
f457ffcc69
fix: fix "[object Object]" appearing as an error message
We show JSON instead
2026-04-30 09:24:48 +09:00
anatawa12
9291853c19
Merge pull request #2847 from JustBuddy/german-translation
chore(l10n): [de_DE] update locale
2026-04-30 01:08:27 +09:00
JustBuddy
0e6d011ee5
chore(l10n): [de_DE] update locale 2026-04-29 17:34:45 +02:00
anatawa12
be5c9aa765
Merge pull request #2846 from vrc-get/copilot/fix-template-export-extension-issue
Fix missing file extensions in save dialog default names
2026-04-29 23:11:06 +09:00
anatawa12
b090c440ac
Merge pull request #2845 from vrc-get/backslash-in-path
feat: replace backslashes with slash extracting zip on unix
2026-04-29 22:54:29 +09:00
copilot-swe-agent[bot]
3c51a2de31
docs: add changelog entry for PR #2846
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/379a1c4c-6953-48f9-86f7-1c0134e08af9

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-29 13:51:37 +00:00
copilot-swe-agent[bot]
04fa1f8244
fix: append file extension to default file names in save dialogs
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/379a1c4c-6953-48f9-86f7-1c0134e08af9

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-29 13:51:17 +00:00
anatawa12
35b26d9322
docs(changelog): Backslashes in path in zip file are now treated as path separator on unix 2026-04-29 22:47:45 +09:00
copilot-swe-agent[bot]
478c25b03a
Initial plan 2026-04-29 13:47:25 +00:00
anatawa12
20e5836985
feat: replace backslashes with slash extracting zip on unix 2026-04-29 22:32:17 +09:00
anatawa12
ce8de700a7
Merge pull request #2844 from vrc-get/improved-package-installation
Improved robustness for package installation errors
2026-04-29 22:02:31 +09:00
anatawa12
3076713ea6
docs(changelog): Improved robustness for package installation errors 2026-04-29 17:38:09 +09:00
anatawa12
75974f4ad9
test: add test for error while downloading package 2026-04-29 17:30:04 +09:00
anatawa12
4eadf2bdcd
feat: installing vpm package is more atomic now 2026-04-29 17:23:01 +09:00
anatawa12
c43ed4a828
Merge pull request #2842 from vrc-get/improve-error-for-bad-version-range
Improve error for bad version range
2026-04-29 00:59:31 +09:00
anatawa12
f675d29173
docs(changelog): Unclear error message for invalid version name or version range 2026-04-28 19:51:56 +09:00
anatawa12
c45e4e399f
Merge pull request #2843 from vrc-get/copilot/add-retry-logic-for-hdiutil
fix: retry hdiutil create with exponential backoff on failure
2026-04-28 19:30:55 +09:00
anatawa12
f5f7ac794e
docs: remove changelog entry 2026-04-28 16:36:40 +09:00
copilot-swe-agent[bot]
88fd6a06a7
fix: extract retry constants and move changelog entry to bottom of Fixed section
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/a90adc5d-6de2-4b6f-aed9-fe753c4a2232

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-28 06:31:13 +00:00
copilot-swe-agent[bot]
c3020225f3
fix: retry hdiutil create with exponential backoff on failure
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/a90adc5d-6de2-4b6f-aed9-fe753c4a2232

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-28 06:27:32 +00:00
anatawa12
d2f9a39b67
chore: improve error message for other string value with format 2026-04-28 15:02:18 +09:00
anatawa12
776bd4b4e8
chore: improve error message for invalid version or invalid version range 2026-04-28 14:50:24 +09:00
anatawa12
4ae3507f96
Merge pull request #2833 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-034c7544f4
chore(deps): bump the tanstack-router group across 1 directory with 2 updates
2026-04-27 22:31:07 +09:00
dependabot[bot]
7b105639f9
chore(deps): bump the tanstack-router group across 1 directory with 2 updates
Bumps the tanstack-router group with 2 updates in the /vrc-get-gui directory: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).


Updates `@tanstack/react-router` from 1.168.23 to 1.168.25
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.168.25/packages/react-router)

Updates `@tanstack/router-plugin` from 1.167.22 to 1.167.28
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-plugin/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-plugin@1.167.28/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.168.25
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.167.28
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 13:24:30 +00:00
anatawa12
fc177add7c
Merge pull request #2834 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tailwindcss-a1e0053666
chore(deps-dev): bump @tailwindcss/vite from 4.2.2 to 4.2.4 in /vrc-get-gui in the tailwindcss group
2026-04-27 22:22:52 +09:00
anatawa12
4063021e2a
Merge pull request #2837 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack/react-query-5.100.5
chore(deps): bump @tanstack/react-query from 5.99.2 to 5.100.5 in /vrc-get-gui
2026-04-27 22:21:07 +09:00
anatawa12
463b4c5df7
Merge pull request #2838 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/biomejs/biome-2.4.13
chore(deps-dev): bump @biomejs/biome from 2.4.12 to 2.4.13 in /vrc-get-gui
2026-04-27 19:55:48 +09:00
anatawa12
bbbbd19926
Merge pull request #2836 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/lucide-react-1.11.0
chore(deps): bump lucide-react from 1.8.0 to 1.11.0 in /vrc-get-gui
2026-04-27 19:53:14 +09:00
anatawa12
3d7b2b8e22
Merge pull request #2835 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/i18next-498519f72f
chore(deps): bump i18next from 26.0.6 to 26.0.8 in /vrc-get-gui in the i18next group
2026-04-27 19:52:58 +09:00
anatawa12
b24bcf1c38
Merge pull request #2839 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vite-8.0.10
chore(deps-dev): bump vite from 8.0.9 to 8.0.10 in /vrc-get-gui
2026-04-27 17:36:32 +09:00
dependabot[bot]
19bde29c6b
chore(deps-dev): bump vite from 8.0.9 to 8.0.10 in /vrc-get-gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.9 to 8.0.10.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.10/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:20:37 +00:00
dependabot[bot]
f18bc14777
chore(deps-dev): bump @biomejs/biome in /vrc-get-gui
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.4.12 to 2.4.13.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.4.13/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.4.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:20:24 +00:00
dependabot[bot]
07a5eb27b3
chore(deps): bump @tanstack/react-query in /vrc-get-gui
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.99.2 to 5.100.5.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.100.5/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.100.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:20:16 +00:00
dependabot[bot]
6a5c60a79e
chore(deps): bump lucide-react from 1.8.0 to 1.11.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.8.0 to 1.11.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.11.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:20:07 +00:00
dependabot[bot]
2b04760299
chore(deps): bump i18next in /vrc-get-gui in the i18next group
Bumps the i18next group in /vrc-get-gui with 1 update: [i18next](https://github.com/i18next/i18next).


Updates `i18next` from 26.0.6 to 26.0.8
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.0.6...v26.0.8)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:19:59 +00:00
dependabot[bot]
1845e8083d
chore(deps-dev): bump @tailwindcss/vite
Bumps the tailwindcss group in /vrc-get-gui with 1 update: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite).


Updates `@tailwindcss/vite` from 4.2.2 to 4.2.4
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.4/packages/@tailwindcss-vite)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tailwindcss
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 08:19:53 +00:00
anatawa12
faf432fd61
Merge pull request #2831 from CirnoV/locale/ko-KR
chore(l10n): [ko] update locale
2026-04-26 15:18:07 +09:00
CirnoV
45942829df chore(l10n): [ko] update locale 2026-04-26 12:55:04 +09:00
anatawa12
b64e09dc55
Merge pull request #2830 from lonelyicer/patch-1
chore(l10N): [zh_Hans] update for #2827
2026-04-26 03:21:41 +09:00
RingLo_
dee9a2fb78
chore(l10N): [zh_Hans] update for #2827 2026-04-26 02:02:12 +08:00
anatawa12
508d62b3e6
Merge pull request #2827 from vrc-get/copilot/fix-backup-warning-roaming-folder
Fix AppData warning missing for Roaming and LocalLow backup/project paths
2026-04-24 19:58:53 +09:00
anatawa12
f119b203f9
Merge pull request #2828 from vrc-get/linux-deps
fix: missing libc dependencies information for deb/rpm distribution
2026-04-24 14:27:20 +09:00
anatawa12
a64cb3af9b
chore: change i18n key to "settings⚠️in-app-data" 2026-04-23 23:13:37 +09:00
anatawa12
70f7f8c78e
chore: remove localappdata from global settings 2026-04-23 23:12:57 +09:00
anatawa12
b64058cab0
docs(changelog): Missing glibc and libgcc_s dependency notation in .deb / .rpm distributon 2026-04-23 23:05:56 +09:00
anatawa12
3e8d5cc9d9
fix: missing dependencies information for deb/rpm distribution 2026-04-23 23:03:57 +09:00
anatawa12
2809d94996
fix: bad tar archive was generated 2026-04-23 23:03:57 +09:00
copilot-swe-agent[bot]
dccd85be31
fix: show AppData warning for Roaming/LocalLow folders, not just Local
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/ed7b1ab9-d3da-4a4d-abd5-d130fe90ee2b

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-23 00:58:06 +00:00
copilot-swe-agent[bot]
726ca0c068
Initial plan 2026-04-23 00:52:20 +00:00
anatawa12
5887c5631c
Merge pull request #2826 from vrc-get/fix-timeout
chore(gui): extend connect/read timeout to 1 min
2026-04-23 09:35:32 +09:00
anatawa12
a57de0d7f1
docs(changelog): Extended some timeouts to 1 minutes 2026-04-23 09:28:55 +09:00
anatawa12
9bc7d26fff
Merge branch 'master' into fix-timeout 2026-04-23 09:26:07 +09:00
anatawa12
20c20a49b0
Merge pull request #2824 from vrc-get/copilot/remove-added-packages-suggestion
Template Editor: Exclude already-added packages from package name suggestions
2026-04-23 09:25:34 +09:00
anatawa12
6a4648ddbb
chore(gui): extend connect/read timeout to 1 min 2026-04-23 09:15:52 +09:00
anatawa12
4783761910
Merge pull request #2825 from vrc-get/copilot-instruction
dev: update copilot instruction
2026-04-23 00:32:58 +09:00
anatawa12
1fdb97d04a
dev: update copilot instruction 2026-04-23 00:26:15 +09:00
anatawa12
b3430d926b
fix: useReorderableList().value always return new array 2026-04-23 00:22:31 +09:00
copilot-swe-agent[bot]
4edda28776
Address review feedback: move changelog to Changed, use useMemo for addedPackageNames set
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/3de0d89e-1f21-4b64-8f9e-4869f497f742

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-22 15:13:27 +00:00
anatawa12
b8903da155
Merge pull request #2823 from vrc-get/copilot/update-bulkupdate-card-padding
style: compact BulkUpdateCard in compact mode
2026-04-23 00:12:46 +09:00
copilot-swe-agent[bot]
38ac981d22
Filter already-added packages from template editor suggestions
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/df9f3421-a51d-44c1-b81b-bab02f9f7d30

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-22 14:56:30 +00:00
anatawa12
9fa4d25637
Merge pull request #2822 from vrc-get/dependency-locked
fix: panic when resolving projects where dependency packages depend on newer versions of locked packages
2026-04-22 23:53:48 +09:00
copilot-swe-agent[bot]
490190606c
Initial plan 2026-04-22 14:52:35 +00:00
copilot-swe-agent[bot]
fd6eb27b09
style: reduce BulkUpdateCard padding in compact mode
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/5dc5a118-7d9b-410d-a016-e4a711a76895

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-22 14:51:41 +00:00
copilot-swe-agent[bot]
5fd5109f3b
Initial plan 2026-04-22 14:50:33 +00:00
anatawa12
496a1c91c1
docs(changelog): Panic when resolving projects where dependency packages depend on newer versions of locked packages 2026-04-22 23:39:39 +09:00
anatawa12
42f1835360
test: panic when resolving projects where dependency packages depend on newer versions of locked packages 2026-04-22 23:38:21 +09:00
anatawa12
4b89aec67a
fix: panic when resolving projects where dependency packages depend on newer versions of locked packages 2026-04-22 23:38:21 +09:00
anatawa12
422b4b1b8d
chore: add more information to panic 2026-04-22 23:38:21 +09:00
anatawa12
98cde02985
Merge pull request #2811 from vrc-get/wording-updates
chore(i18n): breaking changes => may affect compatibility
2026-04-22 20:48:47 +09:00
anatawa12
b6cb3f51f7
chore(i18n): Apply suggestions from code review
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2026-04-22 20:25:36 +09:00
anatawa12
50bc72d662
Merge pull request #2821 from vrc-get/fix-unitypackage-import
fixes for unitypackage import feature
2026-04-22 19:55:58 +09:00
anatawa12
9655865ba9
docs(changelog): Unabled to import some untypackages 2026-04-22 19:49:42 +09:00
anatawa12
827042c827
fix: some unitypackages won't work well
some unitypackages may have `\n00.meta` at the end of their pathname and ALCOM saves it as-is so fs error on Windows or bad file name on unix platforms ocurs.
Unity removes any text after last `\n` so we implement this to fix the problem
2026-04-22 19:46:34 +09:00
anatawa12
e265b8fcdb
Merge pull request #2820 from Misaka-L/patch-3
chore(l10n): [zh_hans] update locale
2026-04-22 19:39:23 +09:00
Misaka_L
3394e59e49
chore(l10n): [zh_hans] update locale 2026-04-22 15:04:16 +08:00
anatawa12
dccfbc2867
Merge pull request #2819 from vrc-get/copilot-instructions
dev: copilot instructions
2026-04-22 14:54:47 +09:00
anatawa12
1cbc34bb30
chore: add warning log when non-assets unitypackage found 2026-04-22 14:52:38 +09:00
anatawa12
61832aa154
Merge pull request #2818 from vrc-get/update_locale_ja
chore(l10n): [ja] update locale
2026-04-22 14:50:06 +09:00
anatawa12
b696c7cc31
dev: copilot instructions 2026-04-22 14:48:26 +09:00
Sayamame-beans
847d76cb5c chore(l10n): [ja] update locale 2026-04-22 14:17:15 +09:00
anatawa12
a29a9bc9e2
Merge pull request #2817 from vrc-get/error-message-for-noexec
chore(en): Improve error message for noexec filesystem issues
2026-04-22 12:18:58 +09:00
anatawa12
72103a67a5
chore(en): Improve error message for noexec filesystem 2026-04-22 11:44:52 +09:00
anatawa12
7f1be1818e
chore(en): Improve error message for noexec filesystem issues 2026-04-22 11:27:27 +09:00
anatawa12
6a7d60d89c
Merge pull request #2814 from vrc-get/copilot/add-warning-for-noexec-mounts-again
Warn when opening Unity projects on noexec mount points (Linux/macOS)
2026-04-22 09:41:35 +09:00
anatawa12
7df14594d1
docs(changelog): ALCOM now refuses launching project if project is on noexec mount points 2026-04-22 09:35:44 +09:00
anatawa12
001a6a330e
style: rustfmt 2026-04-22 09:34:27 +09:00
anatawa12
9ff7c8e1e7
chore: remove locales other than ja/en 2026-04-22 09:34:15 +09:00
anatawa12
17f315a44a
chore: handle error in one place 2026-04-22 09:31:12 +09:00
copilot-swe-agent[bot]
d2cdc980e2
Fix unlocalized error message in open-unity.tsx
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/cd0fa504-9fd3-4469-a12c-7509f26a5b52

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-21 17:34:57 +00:00
copilot-swe-agent[bot]
9c9e8b8f9c
Add noexec filesystem check when opening Unity projects on Linux/macOS
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/cd0fa504-9fd3-4469-a12c-7509f26a5b52

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-21 17:31:27 +00:00
copilot-swe-agent[bot]
b7dc45c2c3
Initial plan 2026-04-21 17:12:31 +00:00
anatawa12
ebb17f10e3
Merge pull request #2812 from vrc-get/copilot/fix-xdg-data-home-fallback
Fix XDG_DATA_HOME fallback for FLATPAK_USER_INSTALLATION path
2026-04-22 01:44:52 +09:00
anatawa12
da26f04917
docs(changelog): ALCOM cannot detect per-user flatpak installation of unity hub 2026-04-22 00:07:59 +09:00
copilot-swe-agent[bot]
930c79d649
Fix FLATPAK_USER_INSTALLATION: use $HOME/.local/share as fallback for XDG_DATA_HOME
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/b5341545-defb-4ca1-81b4-9cdd2d37d523

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-21 14:47:23 +00:00
copilot-swe-agent[bot]
f19b9d0084
Initial plan 2026-04-21 14:45:54 +00:00
anatawa12
c771de380a
chore(i18n): Apply suggestions from code review
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2026-04-21 23:01:54 +09:00
anatawa12
bb26d062de
chore(i18n): breaking changes => may affect compatibility 2026-04-21 20:27:29 +09:00
anatawa12
41b1514f66
Merge pull request #2809 from vrc-get/linux-build-improvement
feat: add --bundle buildroot for package manager distributions
2026-04-21 09:22:13 +09:00
anatawa12
09aebbcb8b
fix: compile error on windows 2026-04-21 01:20:28 +09:00
anatawa12
df8174341e
fix: setting permission is not valid on non-unix 2026-04-21 00:42:56 +09:00
anatawa12
93012d8bd1
Merge pull request #2808 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/react-toastify-11.1.0
chore(deps): bump react-toastify from 11.0.5 to 11.1.0 in /vrc-get-gui
2026-04-21 00:38:33 +09:00
anatawa12
9a739177bc
Merge pull request #2803 from vrc-get/copilot/red-untag-button
Make "Clear Selection" button warning (yellow) in package management
2026-04-21 00:34:49 +09:00
anatawa12
34ef49a629
feat: add --bundle buildroot for package manager distributions 2026-04-21 00:04:55 +09:00
anatawa12
647799180a
Merge pull request #2801 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/i18next-ba25c5e4f4
chore(deps): bump i18next from 26.0.5 to 26.0.6 in /vrc-get-gui in the i18next group across 1 directory
2026-04-20 19:22:26 +09:00
anatawa12
e00162180f
Merge pull request #2805 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-999b6383b5
chore(deps): bump @tanstack/react-router from 1.168.22 to 1.168.23 in /vrc-get-gui in the tanstack-router group
2026-04-20 19:21:39 +09:00
anatawa12
1567b9dec2
Merge pull request #2806 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vite-8.0.9
chore(deps-dev): bump vite from 8.0.8 to 8.0.9 in /vrc-get-gui
2026-04-20 19:20:11 +09:00
anatawa12
2e5962422a
Merge pull request #2807 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack/react-query-5.99.2
chore(deps): bump @tanstack/react-query from 5.99.0 to 5.99.2 in /vrc-get-gui
2026-04-20 19:15:52 +09:00
anatawa12
fb292da426
Merge pull request #2802 from lonelyicer/gui-locale-zh_Hans
chore(l10n): [zh_hans] update locale
2026-04-20 18:10:53 +09:00
anatawa12
98b8df7bb2
Merge pull request #2804 from vrc-get/dependabot/github_actions/samypr100/setup-dev-drive-4
chore(deps): bump samypr100/setup-dev-drive from 3 to 4
2026-04-20 18:05:48 +09:00
dependabot[bot]
a5355dd287
chore(deps): bump react-toastify from 11.0.5 to 11.1.0 in /vrc-get-gui
Bumps [react-toastify](https://github.com/fkhadra/react-toastify) from 11.0.5 to 11.1.0.
- [Release notes](https://github.com/fkhadra/react-toastify/releases)
- [Commits](https://github.com/fkhadra/react-toastify/compare/v11.0.5...v11.1.0)

---
updated-dependencies:
- dependency-name: react-toastify
  dependency-version: 11.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 08:03:28 +00:00
dependabot[bot]
8915177909
chore(deps): bump @tanstack/react-query in /vrc-get-gui
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.99.0 to 5.99.2.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.99.2/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.99.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 08:03:21 +00:00
dependabot[bot]
ad232e3506
chore(deps-dev): bump vite from 8.0.8 to 8.0.9 in /vrc-get-gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 8.0.8 to 8.0.9.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.0.9/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.0.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 08:03:13 +00:00
dependabot[bot]
a8aed0a011
chore(deps): bump @tanstack/react-router
Bumps the tanstack-router group in /vrc-get-gui with 1 update: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router).


Updates `@tanstack/react-router` from 1.168.22 to 1.168.23
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.168.23/packages/react-router)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.168.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 08:03:01 +00:00
dependabot[bot]
79b7776e40
chore(deps): bump samypr100/setup-dev-drive from 3 to 4
Bumps [samypr100/setup-dev-drive](https://github.com/samypr100/setup-dev-drive) from 3 to 4.
- [Release notes](https://github.com/samypr100/setup-dev-drive/releases)
- [Changelog](https://github.com/samypr100/setup-dev-drive/blob/main/CHANGELOG.md)
- [Commits](https://github.com/samypr100/setup-dev-drive/compare/v3...v4)

---
updated-dependencies:
- dependency-name: samypr100/setup-dev-drive
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-20 08:02:44 +00:00
copilot-swe-agent[bot]
d96ae23a60
Change Clear Selection button variant from destructive to warning
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/6da5a28d-c1db-48e8-9ada-1c98934996ed

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-20 05:56:39 +00:00
copilot-swe-agent[bot]
c44bbe2584
Make the Clear Selection button red (destructive) in package management
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/aaf4dce4-b804-43e8-85b8-bd1d7dcf30e1

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-20 05:29:17 +00:00
copilot-swe-agent[bot]
fa05c2bc30
Initial plan 2026-04-20 05:26:41 +00:00
RingLo_
9b26a5fdb3
chore(l10n): [zh_hans] update locale 2026-04-20 11:49:08 +08:00
RingLo_
c8b0cf89c8
chore: fix type 2026-04-20 11:31:22 +08:00
RingLo_
911c0a5e51
feat: always show installed packages
also hide hidden sources
2026-04-20 11:22:51 +08:00
RingLo_
8773f3d3e6
Merge branch 'master' into feat/show-hidden-packages 2026-04-20 11:01:27 +08:00
dependabot[bot]
974a195a3c
chore(deps): bump i18next
Bumps the i18next group with 1 update in the /vrc-get-gui directory: [i18next](https://github.com/i18next/i18next).


Updates `i18next` from 26.0.5 to 26.0.6
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v26.0.5...v26.0.6)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 26.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-18 20:20:32 +00:00
anatawa12
9b63d1919f
Merge pull request #2799 from vrc-get/bump-deps
Bump deps
2026-04-19 04:36:48 +09:00
anatawa12
04b65168b8
fix: bad import 2026-04-19 03:51:51 +09:00
anatawa12
f2ce2829eb
chore(deps): migrate to vite 8 2026-04-19 01:00:00 +09:00
anatawa12
d3d127efb8
chore(deps): upgrade dependencies (including breaking changes) 2026-04-19 01:00:00 +09:00
anatawa12
98a9bf6938
Merge pull request #2798 from CirnoV/locale/ko-KR
chore(l10n): [ko] update locale
2026-04-19 00:57:29 +09:00
CirnoV
56f586974e chore(l10n): [ko] update locale 2026-04-18 22:54:32 +09:00
anatawa12
2f6e52032e
Merge pull request #2797 from vrc-get/update_locale_en_ja
chore(l10n): [en/ja] update locale
2026-04-18 22:25:12 +09:00
anatawa12
09d60c804f
chore(ja): Apply suggestions from code review
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2026-04-18 21:58:39 +09:00
Sayamame-beans
8c210c248f chore(l10n): [ja] update locale 2026-04-18 21:43:27 +09:00
Sayamame-beans
3f6ba916c0 chore(l10n): [en] chore message 2026-04-18 21:43:01 +09:00
anatawa12
3213f9288a
Merge pull request #2635 from vrc-get/feat-2633
feat: allow reselecting unitypackage path on Template Editor
2026-04-18 21:11:52 +09:00
anatawa12
2411f7482b
Merge branch 'master' into feat-2633 2026-04-18 20:59:19 +09:00
anatawa12
7ac0b41800
Merge pull request #2795 from vrc-get/copilot/add-notice-for-prerelease-packages
Add stability warning and confirmation dialog for "Show Prerelease Packages"
2026-04-18 19:09:59 +09:00
anatawa12
03f1140d71
chore(i18n): Apply suggestions from code review
Co-authored-by: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com>
2026-04-18 18:43:01 +09:00
Sayamame-beans
3e58fc6d1a
Merge branch 'master' into feat-2633 2026-04-18 18:04:11 +09:00
anatawa12
fe0f711d62
docs(changelog): We added dialog on enabling "Show Prerelease Packages" 2026-04-18 01:21:27 +09:00
anatawa12
dbd5fbbca8
chore: change button level to warning 2026-04-18 01:21:10 +09:00
copilot-swe-agent[bot]
da12ba3cad
Use direct bug language, rename Enable to Show, make button destructive
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/7a06eb84-7c48-4632-945b-21d68b087265

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-17 16:14:13 +00:00
copilot-swe-agent[bot]
1178e151ef
Add error handling to prerelease dialog promise
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/5ef365b7-5da5-4179-ad50-ce8ec4a88ba8

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-17 07:50:12 +00:00
copilot-swe-agent[bot]
0cbbaacd12
Add warning and confirmation dialog for prerelease packages option
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/5ef365b7-5da5-4179-ad50-ce8ec4a88ba8

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-17 07:48:50 +00:00
copilot-swe-agent[bot]
bd7f84196b
Initial plan 2026-04-17 07:44:30 +00:00
anatawa12
8babbb0e04
Merge pull request #2746 from siloneco/perf/parallel-zip-compression
perf: improve backup project performance by parallelizing zip compression
2026-04-17 14:49:57 +09:00
anatawa12
63d40420c9
Merge branch 'master' into perf/parallel-zip-compression 2026-04-17 09:54:14 +09:00
anatawa12
6afa1e07b5
Merge pull request #2794 from vrc-get/ci-bundles
ci: ci builds of ALCOM doesn't include any bundles
2026-04-17 09:53:27 +09:00
anatawa12
6f5359c7a3
ci: ci builds of ALCOM doesn't include any bundles 2026-04-17 09:26:36 +09:00
anatawa12
60f20b2b22
Merge remote-tracking branch 'origin/master' into perf/parallel-zip-compression 2026-04-17 09:19:59 +09:00
anatawa12
25e19296d0
Merge pull request #2792 from Misaka-L/patch-2
chore(l10n): [zh_hans] update locale
2026-04-17 08:59:00 +09:00
Misaka_L
fd66eee442
chore(l10n): [zh_hans] update locale 2026-04-17 02:54:28 +08:00
anatawa12
f2809b0d19
Merge pull request #2786 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/lucide-react-1.8.0
chore(deps): bump lucide-react from 1.7.0 to 1.8.0 in /vrc-get-gui
2026-04-17 01:17:56 +09:00
anatawa12
91d8b73fad
Merge pull request #2763 from vrc-get/dependabot/cargo/tauri-plugin-dialog-2.7.0
chore(deps): bump tauri-plugin-dialog from 2.6.0 to 2.7.0
2026-04-17 00:39:52 +09:00
anatawa12
5ac23e1ca3
Merge pull request #2780 from vrc-get/dependabot/github_actions/actions/github-script-9
chore(deps): bump actions/github-script from 8 to 9
2026-04-17 00:36:41 +09:00
anatawa12
0961bcad1d
Merge pull request #2791 from JustBuddy/german-translation
chore(l10n): [de_DE] update locale
2026-04-17 00:35:53 +09:00
anatawa12
4c8ccea7c3
Merge pull request #2790 from vrc-get/lint
lint: fix new lints
2026-04-17 00:32:45 +09:00
JustBuddy
68ff4c3205
chore(l10n): [de_DE] update locale 2026-04-16 17:06:58 +02:00
anatawa12
b30df5621a
lint: fix new lints 2026-04-16 23:46:33 +09:00
anatawa12
02759caf1c
Merge pull request #2759 from vrc-get/inno-setup
Changes how alcom is installed and how distributed
2026-04-16 23:32:00 +09:00
anatawa12
9df7055ee1
docs: update how to build and add changelog entries 2026-04-16 23:24:27 +09:00
anatawa12
60636fb8c3
build: fix we cannot call npm on windows 2026-04-16 22:33:16 +09:00
anatawa12
1b7263e35e
ci: dev drive is too small 2026-04-16 20:27:00 +09:00
anatawa12
5937594af1
ci: try t to workaround actions/checkout behavior 2026-04-16 20:21:38 +09:00
anatawa12
4da483032e
ci: try dev drive 2026-04-16 19:50:43 +09:00
anatawa12
93cb37ff77
build: merge building web part into xtask 2026-04-16 19:38:53 +09:00
anatawa12
0ae87b7b49
chore: completely remove bundle related options from tauri.toml 2026-04-16 14:11:21 +09:00
anatawa12
dfe9e97b00
fix: macos build part not working 2026-04-16 01:09:56 +09:00
anatawa12
51b7f9ccee
fix: --updater-instruction-message detection not working 2026-04-16 01:04:12 +09:00
anatawa12
44a5f5eadf
fix: configuration for macos overrides everything 2026-04-16 00:58:14 +09:00
anatawa12
a89bcbfa16
chore: remove esigner 2026-04-16 00:44:48 +09:00
anatawa12
3436711467
ci: split building appimage and deb/rpm 2026-04-16 00:41:52 +09:00
anatawa12
dd160c5199
chore: change how do we customize build 2026-04-16 00:11:24 +09:00
anatawa12
4e31d23b0c
chore: change how do we pass customized message 2026-04-15 23:55:39 +09:00
anatawa12
6fb9f631a1
fix: manually specify to use native-tls 2026-04-15 12:55:57 +09:00
anatawa12
fca8805043
chore: use xtask to sign updater artifact 2026-04-15 09:48:18 +09:00
anatawa12
9d533a2051
chore: try to improve ci speed 2026-04-15 09:36:09 +09:00
anatawa12
f7a0099b53
Merge remote-tracking branch 'origin/master' into inno-setup 2026-04-14 22:10:38 +09:00
anatawa12
d98339017f
fix: artifact name conflict 2026-04-14 19:36:15 +09:00
anatawa12
6bc973dd66
ci: configure signing windows build 2026-04-14 13:38:27 +09:00
anatawa12
7fca14868f
ci: split setup exe and updater exe
the updater won't be signed and will only be used by legacy updater
2026-04-14 09:27:03 +09:00
anatawa12
a9378ac341
ci: fix sign-alcom does not support base64 with newlines 2026-04-13 19:38:13 +09:00
anatawa12
09bca3b5fd
ci: fix file name mismatch and improve 2026-04-13 19:34:05 +09:00
dependabot[bot]
001880b49d
chore(deps): bump lucide-react from 1.7.0 to 1.8.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 1.7.0 to 1.8.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.8.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 07:54:04 +00:00
dependabot[bot]
bcb7131054
chore(deps): bump actions/github-script from 8 to 9
Bumps [actions/github-script](https://github.com/actions/github-script) from 8 to 9.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v8...v9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 07:53:15 +00:00
anatawa12
b5d93a3bab
ci: use --release for publishing gui 2026-04-13 15:11:27 +09:00
anatawa12
6c411dd7a2
fix(rpm): version name cannot include '-' 2026-04-13 14:56:07 +09:00
anatawa12
3e3b2155cd
lint: remove unused imports 2026-04-13 14:55:47 +09:00
anatawa12
95d8af8559
fix(rpm): file permission instead of mode 2026-04-13 14:43:23 +09:00
anatawa12
358ca77692
fix: downloading appimagetool 2026-04-13 09:56:07 +09:00
anatawa12
8ec535701c
fix: downloading appimagetool not working 2026-04-13 09:39:26 +09:00
anatawa12
07472f8622
chore(xtask): remove unused deps 2026-04-13 09:37:05 +09:00
anatawa12
0680a57066
chore(xtask): allow adding features in build-alcom and use them 2026-04-13 09:35:36 +09:00
anatawa12
88fa1c2b3d
ci: build release binary 2026-04-13 09:27:56 +09:00
anatawa12
b38f2393fd
ci: syntax error for windows build 2026-04-13 09:25:18 +09:00
anatawa12
b00beaae70
fix: icon path is not correct 2026-04-13 09:24:10 +09:00
anatawa12
d349e16411
fix: build directory is not correct for dev build 2026-04-13 09:15:32 +09:00
anatawa12
13e53bfba0
ci: run ci for non-master prs 2026-04-13 08:05:07 +09:00
anatawa12
281669e6c5
refactor: migrate build-alcom-installer to bundle-alcom 2026-04-13 01:47:33 +09:00
anatawa12
30d49406e4
refactor: remove reading tauri.toml 2026-04-13 01:03:36 +09:00
anatawa12
3fce6e45ea
feat: background for macos installer .dmg 2026-04-13 00:03:39 +09:00
anatawa12
2c8eeec473
fix: build command always passes target so it always cross build 2026-04-12 17:10:36 +09:00
anatawa12
ee527cf95c
chore: move dmg specific part to dmg.rs and update several parameters 2026-04-12 17:08:45 +09:00
copilot-swe-agent[bot]
02fe4e64ac
fix: use consistent number formatting in doc comments
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/fc1392fa-eac7-4db6-8c73-c1472e79ceb8

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-11 15:28:49 +00:00
copilot-swe-agent[bot]
99d526e0cf
feat: add util::ds_store module and write .DS_Store in DMG staging dir
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/fc1392fa-eac7-4db6-8c73-c1472e79ceb8

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-11 15:25:17 +00:00
anatawa12
16b48bb1db
refactor: completely refactors cargo xtask buindle-alcom 2026-04-11 23:53:10 +09:00
anatawa12
3e3ffabf7e
Merge pull request #2766 from vrc-get/dependabot/cargo/arc-swap-1.9.1
chore(deps): bump arc-swap from 1.9.0 to 1.9.1
2026-04-11 02:12:59 +09:00
anatawa12
fcbcf3a504
Merge pull request #2768 from vrc-get/dependabot/cargo/yoke-0.8.2
chore(deps): bump yoke from 0.8.1 to 0.8.2
2026-04-11 02:12:32 +09:00
anatawa12
370dc0f3d8
Merge pull request #2770 from vrc-get/dependabot/cargo/indexmap-2.13.1
chore(deps): bump indexmap from 2.13.0 to 2.13.1
2026-04-11 02:09:14 +09:00
copilot-swe-agent[bot]
8619197e92
feat: add --bundles option to bundle-alcom and new sign-alcom command
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/f6a86c70-4f97-4203-974e-45f12fd853b7

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 12:39:20 +00:00
copilot-swe-agent[bot]
205a60aafc
fix: use explicit format args in panic! macros
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/00d0aa2a-4624-4df5-b43f-73046f95d809

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 04:59:19 +00:00
copilot-swe-agent[bot]
5c0d2789d8
feat: add build-alcom command, fix arch detection, use fs_extra for dir copy
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/00d0aa2a-4624-4df5-b43f-73046f95d809

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 04:55:31 +00:00
copilot-swe-agent[bot]
3790d10f96
refactor: use plist, rpm, and ar crates instead of manual parsing and external commands
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/fe7a550a-71c9-4b7a-b324-4ec4906eacc0

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 01:11:43 +00:00
anatawa12
72e927edd3
chore: hardcode where icons are put 2026-04-10 09:36:22 +09:00
anatawa12
506b389e40
lint: clippy 2026-04-10 09:35:48 +09:00
anatawa12
22a40d64cd
style: rustfmt 2026-04-10 09:33:59 +09:00
copilot-swe-agent[bot]
4586b5f5b3
fix: address code review issues (plist parser underflow, unwrap on parent)
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/38030954-a556-4574-a386-7e075f2f66b1

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 00:13:25 +00:00
copilot-swe-agent[bot]
9a46a49c36
feat: add bundle-alcom xtask command and migrate CI from tauri-action
Agent-Logs-Url: https://github.com/vrc-get/vrc-get/sessions/38030954-a556-4574-a386-7e075f2f66b1

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2026-04-10 00:09:33 +00:00
copilot-swe-agent[bot]
bf53c697a3
Initial plan 2026-04-09 23:54:38 +00:00
anatawa12
96fd94e2a1
feat: allow user to install different directory than previous installation 2026-04-09 09:34:57 +09:00
anatawa12
bbda611499
feat: new updater system 2026-04-09 09:34:57 +09:00
dependabot[bot]
083d320cf1
chore(deps): bump indexmap from 2.13.0 to 2.13.1
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.13.0 to 2.13.1.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.13.0...2.13.1)

---
updated-dependencies:
- dependency-name: indexmap
  dependency-version: 2.13.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 07:44:46 +00:00
dependabot[bot]
d79cd05fe6
chore(deps): bump yoke from 0.8.1 to 0.8.2
Bumps [yoke](https://github.com/unicode-org/icu4x) from 0.8.1 to 0.8.2.
- [Release notes](https://github.com/unicode-org/icu4x/releases)
- [Changelog](https://github.com/unicode-org/icu4x/blob/main/CHANGELOG.md)
- [Commits](https://github.com/unicode-org/icu4x/commits)

---
updated-dependencies:
- dependency-name: yoke
  dependency-version: 0.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 07:44:27 +00:00
dependabot[bot]
1411a7405f
chore(deps): bump arc-swap from 1.9.0 to 1.9.1
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.9.0 to 1.9.1.
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.9.0...v1.9.1)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-version: 1.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 07:44:15 +00:00
dependabot[bot]
7639563544
chore(deps): bump tauri-plugin-dialog from 2.6.0 to 2.7.0
Bumps [tauri-plugin-dialog](https://github.com/tauri-apps/plugins-workspace) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/log-v2.6.0...log-v2.7.0)

---
updated-dependencies:
- dependency-name: tauri-plugin-dialog
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 07:43:34 +00:00
siloneco
4c8f24da3f fix: move unreachable code to correct position 2026-04-05 15:37:19 +09:00
anatawa12
1ae45e3b47
Merge remote-tracking branch 'origin/master' into inno-setup 2026-04-05 15:13:37 +09:00
siloneco
19ef64ef32 docs: add changelog for this performance improvements 2026-04-05 14:21:47 +09:00
siloneco
650d0bf8ff fix: increase file descriptor limit on app init 2026-04-05 14:10:12 +09:00
siloneco
7ba6106a63 refactor: fix clippy warnings 2026-04-05 14:10:12 +09:00
siloneco
52234179f3 chore: remove hard-coded memory usage soft limit 2026-04-05 14:10:12 +09:00
siloneco
976fd95517 fix: unable to create zip file with Compression::Stored 2026-04-05 14:10:12 +09:00
siloneco
ee2a73994e chore: delete unnecessary lock file 2026-04-05 14:10:12 +09:00
siloneco
439a639d15 fix: change default compression level to zip-fast 2026-04-05 14:10:12 +09:00
siloneco
9c57629211 feat: show finalizing message until all merge tasks are complete 2026-04-05 13:10:24 +09:00
anatawa12
fa7dc36c83
ci: fix mising env vars
Add environment variables for Tauri signing in Windows installer build step.
2026-04-05 03:10:55 +09:00
anatawa12
06cdd8d5cc
Merge pull request #2751 from vrc-get/dependabot/cargo/object-0.39.0
chore(deps): bump object from 0.38.1 to 0.39.0
2026-04-05 02:50:08 +09:00
anatawa12
d28d8dcdc6
Merge pull request #2752 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/lucide-react-1.7.0
chore(deps): bump lucide-react from 0.577.0 to 1.7.0 in /vrc-get-gui
2026-04-05 02:16:59 +09:00
anatawa12
23d087e6cc
Merge pull request #2753 from vrc-get/dependabot/cargo/env_logger-0.11.10
chore(deps): bump env_logger from 0.11.9 to 0.11.10
2026-04-05 02:13:51 +09:00
anatawa12
a657a77633
Merge pull request #2756 from vrc-get/dependabot/cargo/sha2-0.11.0
chore(deps): bump sha2 from 0.10.9 to 0.11.0
2026-04-05 02:12:03 +09:00
anatawa12
6e0b28ee2c
fix: calling windows installer sign script does not work as expected 2026-04-05 02:10:06 +09:00
anatawa12
727f963923
ci: update publish action to migrate installer 2026-04-05 01:13:46 +09:00
anatawa12
7229201ad3
fix: nsis settings is not correctly removed 2026-04-05 00:52:33 +09:00
anatawa12
042dfa9f69
fix: missing system libraries in current dependencies (typo fix) 2026-04-05 00:01:55 +09:00
anatawa12
bdd312152c
fix: missing system libraries in current dependencies 2026-04-04 23:54:45 +09:00
anatawa12
00051c6e53
chore: remove nsis installer from build bundle 2026-04-04 23:38:14 +09:00
siloneco
4f6cee33c2 feat: implement soft limit for memory usage during compression 2026-04-04 22:17:26 +09:00
anatawa12
02fcb00bb3
chore: change wrapper exe name to alcom-setup.exe 2026-04-04 17:04:09 +09:00
anatawa12
0e62041ab4
ci: exclude windows-installer-wrapper from clippy lint 2026-04-04 16:55:45 +09:00
anatawa12
06fe826379
ci: change how to handle .exe 2026-04-04 16:53:57 +09:00
anatawa12
57ae7c7df8
fix: skip rlibs 2026-04-04 01:06:45 +09:00
anatawa12
40b3edc0e2
ci: fix xtask is not called correctly 2026-04-04 00:59:33 +09:00
anatawa12
7f1d7f36e8
feat: add xbuild task to build alcom installer 2026-04-04 00:42:18 +09:00
anatawa12
dd645a5b5b
feat: add installer wrapper for nsis compatibility 2026-04-04 00:40:37 +09:00
anatawa12
da81afe549
fix: removal of build-updater-json in not committed 2026-04-01 09:29:40 +09:00
anatawa12
e29fafa6d2
feat: add inno setup based installer 2026-04-01 01:47:35 +09:00
siloneco
571a6e71fb feat: use async_zip crate instead of zip and rayon crate 2026-03-31 03:31:15 +09:00
dependabot[bot]
27835f9ce0
chore(deps): bump sha2 from 0.10.9 to 0.11.0
Bumps [sha2](https://github.com/RustCrypto/hashes) from 0.10.9 to 0.11.0.
- [Commits](https://github.com/RustCrypto/hashes/compare/sha2-v0.10.9...sha2-v0.11.0)

---
updated-dependencies:
- dependency-name: sha2
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 07:46:52 +00:00
dependabot[bot]
b0a1f5b6d9
chore(deps): bump env_logger from 0.11.9 to 0.11.10
Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.11.9 to 0.11.10.
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.11.9...v0.11.10)

---
updated-dependencies:
- dependency-name: env_logger
  dependency-version: 0.11.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 07:46:29 +00:00
dependabot[bot]
a9474fae66
chore(deps): bump lucide-react from 0.577.0 to 1.7.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.577.0 to 1.7.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.7.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 07:46:22 +00:00
dependabot[bot]
301ae004b6
chore(deps): bump object from 0.38.1 to 0.39.0
Bumps [object](https://github.com/gimli-rs/object) from 0.38.1 to 0.39.0.
- [Changelog](https://github.com/gimli-rs/object/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/0.38.1...v0.39.0)

---
updated-dependencies:
- dependency-name: object
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 07:46:17 +00:00
siloneco
d32d7f854a perf: avoid loading the entire file at once 2026-03-30 02:24:57 +09:00
siloneco
7eda8cedde refactor: use FileSystemTree instead of original struct 2026-03-30 02:19:38 +09:00
siloneco
0f63d3bc4e perf: remove unnecessary semaphore 2026-03-30 02:10:43 +09:00
siloneco
9cb256d4ec fix: keep duplicate code to ensure maintainability 2026-03-30 02:09:51 +09:00
anatawa12
2a87edcaa3
chore: migrate build-updater-json to xtask 2026-03-29 23:50:09 +09:00
siloneco
e543d5329f perf: parallelize backups to speed up execution 2026-03-29 19:50:06 +09:00
anatawa12
0943241884
chore: migrate build-check-static-link to xtask 2026-03-28 20:37:10 +09:00
anatawa12
d0a90046b7
Merge pull request #2737 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-845dc2c481
chore(deps): bump the tanstack-router group in /vrc-get-gui with 3 updates
2026-03-24 23:18:44 +09:00
anatawa12
9922e0da2c
Merge pull request #2732 from vrc-get/dependabot/cargo/tar-0.4.45
chore(deps): bump tar from 0.4.44 to 0.4.45
2026-03-24 22:39:04 +09:00
dependabot[bot]
2cc9c692d7
chore(deps): bump the tanstack-router group
Bumps the tanstack-router group in /vrc-get-gui with 3 updates: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [@tanstack/router-devtools](https://github.com/TanStack/router/tree/HEAD/packages/router-devtools) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).


Updates `@tanstack/react-router` from 1.166.3 to 1.168.2
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.168.2/packages/react-router)

Updates `@tanstack/router-devtools` from 1.166.3 to 1.166.11
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-devtools/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-devtools@1.166.11/packages/router-devtools)

Updates `@tanstack/router-plugin` from 1.166.3 to 1.167.3
- [Release notes](https://github.com/TanStack/router/releases)
- [Changelog](https://github.com/TanStack/router/blob/main/packages/router-plugin/CHANGELOG.md)
- [Commits](https://github.com/TanStack/router/commits/@tanstack/router-plugin@1.167.3/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.168.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-devtools"
  dependency-version: 1.166.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.167.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-24 13:04:25 +00:00
anatawa12
93609bb42d
Merge pull request #2734 from vrc-get/dependabot/cargo/rustls-webpki-0.103.10
chore(deps): bump rustls-webpki from 0.103.9 to 0.103.10
2026-03-24 21:57:42 +09:00
anatawa12
22f50c3e05
Merge pull request #2736 from vrc-get/dependabot/cargo/arc-swap-1.9.0
chore(deps): bump arc-swap from 1.8.2 to 1.9.0
2026-03-24 21:57:12 +09:00
anatawa12
f0854c9a78
Merge pull request #2738 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tailwindcss-c5f55f59c8
chore(deps-dev): bump @tailwindcss/vite from 4.2.1 to 4.2.2 in /vrc-get-gui in the tailwindcss group
2026-03-24 21:54:40 +09:00
anatawa12
82d4babc13
Merge pull request #2739 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack/react-query-5.95.0
chore(deps): bump @tanstack/react-query from 5.90.21 to 5.95.0 in /vrc-get-gui
2026-03-24 21:54:29 +09:00
dependabot[bot]
8b7df92640
chore(deps): bump @tanstack/react-query in /vrc-get-gui
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.90.21 to 5.95.0.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.95.0/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.95.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 07:44:43 +00:00
dependabot[bot]
ed26112f7e
chore(deps-dev): bump @tailwindcss/vite
Bumps the tailwindcss group in /vrc-get-gui with 1 update: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite).


Updates `@tailwindcss/vite` from 4.2.1 to 4.2.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.2/packages/@tailwindcss-vite)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.2.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tailwindcss
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 07:44:30 +00:00
dependabot[bot]
40a1f6fef7
chore(deps): bump arc-swap from 1.8.2 to 1.9.0
Bumps [arc-swap](https://github.com/vorner/arc-swap) from 1.8.2 to 1.9.0.
- [Changelog](https://github.com/vorner/arc-swap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vorner/arc-swap/compare/v1.8.2...v1.9.0)

---
updated-dependencies:
- dependency-name: arc-swap
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-23 07:43:33 +00:00
dependabot[bot]
7b259d47f4
chore(deps): bump rustls-webpki from 0.103.9 to 0.103.10
Bumps [rustls-webpki](https://github.com/rustls/webpki) from 0.103.9 to 0.103.10.
- [Release notes](https://github.com/rustls/webpki/releases)
- [Commits](https://github.com/rustls/webpki/compare/v/0.103.9...v/0.103.10)

---
updated-dependencies:
- dependency-name: rustls-webpki
  dependency-version: 0.103.10
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-21 09:41:45 +00:00
dependabot[bot]
faf15cd44a
chore(deps): bump tar from 0.4.44 to 0.4.45
Bumps [tar](https://github.com/alexcrichton/tar-rs) from 0.4.44 to 0.4.45.
- [Commits](https://github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 0.4.45
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 18:09:45 +00:00
RingLo_
40d0786b19
chore: clean code 2026-03-20 08:02:05 +08:00
RingLo_
7fdd1192e1
docs(changelog): update for #2731 2026-03-20 07:54:27 +08:00
RingLo_
d09244291f
feat: show hide packages 2026-03-20 07:47:40 +08:00
anatawa12
eae4745ce6
Merge pull request #2712 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tanstack-router-8d241097f2
chore(deps): bump the tanstack-router group in /vrc-get-gui with 3 updates
2026-03-16 20:42:23 +09:00
anatawa12
9554373332
Merge pull request #2719 from vrc-get/dependabot/github_actions/auguwu/clippy-action-1.5.0
chore(deps): bump auguwu/clippy-action from 1.4.0 to 1.5.0
2026-03-16 20:41:50 +09:00
anatawa12
22d757ed52
Merge pull request #2723 from vrc-get/dependabot/cargo/anstyle-1.0.14
chore(deps): bump anstyle from 1.0.13 to 1.0.14
2026-03-16 20:41:32 +09:00
anatawa12
9fbce2a575
Merge pull request #2724 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vitejs/plugin-react-swc-4.3.0
chore(deps-dev): bump @vitejs/plugin-react-swc from 4.2.3 to 4.3.0 in /vrc-get-gui
2026-03-16 20:40:47 +09:00
dependabot[bot]
9257f1fed5
chore(deps): bump anstyle from 1.0.13 to 1.0.14
Bumps [anstyle](https://github.com/rust-cli/anstyle) from 1.0.13 to 1.0.14.
- [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.13...v1.0.14)

---
updated-dependencies:
- dependency-name: anstyle
  dependency-version: 1.0.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 11:33:56 +00:00
anatawa12
b52b04a81e
Merge pull request #2721 from vrc-get/dependabot/github_actions/actions/create-github-app-token-3
chore(deps): bump actions/create-github-app-token from 2 to 3
2026-03-16 20:30:43 +09:00
anatawa12
3d4757f267
Merge pull request #2718 from vrc-get/dependabot/cargo/clap-712b10af58
chore(deps): bump the clap group with 2 updates
2026-03-16 20:30:07 +09:00
anatawa12
9dd4a13596
Merge pull request #2711 from vrc-get/dependabot/cargo/uuid-1.22.0
chore(deps): bump uuid from 1.21.0 to 1.22.0
2026-03-16 20:29:34 +09:00
anatawa12
2e2ee22add
Merge pull request #2715 from vrc-get/dependabot/cargo/quinn-proto-0.11.14
chore(deps): bump quinn-proto from 0.11.13 to 0.11.14
2026-03-16 20:28:33 +09:00
anatawa12
f852312336
Merge pull request #2720 from vrc-get/dependabot/cargo/serde_with-3.18.0
chore(deps): bump serde_with from 3.17.0 to 3.18.0
2026-03-16 17:29:57 +09:00
dependabot[bot]
0d82e0e5ec
chore(deps-dev): bump @vitejs/plugin-react-swc in /vrc-get-gui
Bumps [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react-swc) from 4.2.3 to 4.3.0.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/v4.3.0/packages/plugin-react-swc)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react-swc"
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 07:44:13 +00:00
dependabot[bot]
d5434497da
chore(deps): bump actions/create-github-app-token from 2 to 3
Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2 to 3.
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Commits](https://github.com/actions/create-github-app-token/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/create-github-app-token
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 07:43:46 +00:00
dependabot[bot]
78d6ff1a3c
chore(deps): bump serde_with from 3.17.0 to 3.18.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.17.0 to 3.18.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.17.0...v3.18.0)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 07:43:43 +00:00
dependabot[bot]
205c9e66d7
chore(deps): bump auguwu/clippy-action from 1.4.0 to 1.5.0
Bumps [auguwu/clippy-action](https://github.com/auguwu/clippy-action) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/auguwu/clippy-action/releases)
- [Commits](https://github.com/auguwu/clippy-action/compare/1.4.0...1.5.0)

---
updated-dependencies:
- dependency-name: auguwu/clippy-action
  dependency-version: 1.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 07:43:36 +00:00
dependabot[bot]
e5eee65f66
chore(deps): bump the clap group with 2 updates
Bumps the clap group with 2 updates: [clap](https://github.com/clap-rs/clap) and [clap_complete](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.60 to 4.6.0
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.60...clap_complete-v4.6.0)

Updates `clap_complete` from 4.5.66 to 4.6.0
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.66...clap_complete-v4.6.0)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: clap
- dependency-name: clap_complete
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: clap
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-16 07:43:30 +00:00
dependabot[bot]
714b1b3b8a
chore(deps): bump quinn-proto from 0.11.13 to 0.11.14
Bumps [quinn-proto](https://github.com/quinn-rs/quinn) from 0.11.13 to 0.11.14.
- [Release notes](https://github.com/quinn-rs/quinn/releases)
- [Commits](https://github.com/quinn-rs/quinn/compare/quinn-proto-0.11.13...quinn-proto-0.11.14)

---
updated-dependencies:
- dependency-name: quinn-proto
  dependency-version: 0.11.14
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-11 00:21:13 +00:00
dependabot[bot]
fa0a5e4e37
chore(deps): bump the tanstack-router group
Bumps the tanstack-router group in /vrc-get-gui with 3 updates: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [@tanstack/router-devtools](https://github.com/TanStack/router/tree/HEAD/packages/router-devtools) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).


Updates `@tanstack/react-router` from 1.163.3 to 1.166.3
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.166.3/packages/react-router)

Updates `@tanstack/router-devtools` from 1.163.3 to 1.166.3
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.166.3/packages/router-devtools)

Updates `@tanstack/router-plugin` from 1.164.0 to 1.166.3
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.166.3/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.166.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-devtools"
  dependency-version: 1.166.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.166.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 07:44:40 +00:00
dependabot[bot]
9a430541df
chore(deps): bump uuid from 1.21.0 to 1.22.0
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 07:44:11 +00:00
anatawa12
20489da9d6
Merge pull request #2710 from vrc-get/json-with-zeros
chore: treat file filled with \0 as empty file while processing file
2026-03-08 00:57:00 +09:00
anatawa12
2f1755cb03
docs(changelog): File filled with '\0' or whitespace will be treated as empty file 2026-03-08 00:14:40 +09:00
anatawa12
a3b44389ee
chore: treat file filled with \0 as empty file while processing file 2026-03-07 23:44:31 +09:00
anatawa12
ca4cacbfff
Merge pull request #2709 from vrc-get/fix-null
chore: allow null on optional field, treat as omit (default)
2026-03-07 23:18:01 +09:00
anatawa12
fc0b40a27f
docs(changelog): null as vpmDependencies value is not allowed 2026-03-07 23:05:53 +09:00
anatawa12
063639e389
chore: allow null on optional field, treat as omit (default) 2026-03-07 23:02:17 +09:00
anatawa12
b0aafd0411
Merge pull request #2687 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vite-7.3.1
chore(deps-dev): bump vite from 6.4.1 to 7.3.1 in /vrc-get-gui
2026-03-05 02:09:37 +09:00
anatawa12
87f784b613
Merge pull request #2708 from vrc-get/wmi-0.18
chore(deps): update wmi to 0.18
2026-03-05 01:52:36 +09:00
anatawa12
9f0ba1abfb
chore(deps): update wmi to 0.18 2026-03-05 01:41:31 +09:00
anatawa12
a4a86b0ab1
Merge pull request #2705 from vrc-get/dependabot/cargo/object-0.38.1
chore(deps): bump object from 0.37.3 to 0.38.1
2026-03-05 01:33:27 +09:00
anatawa12
a69ecb0cf1
Merge pull request #2569 from vrc-get/dependabot/github_actions/actions/setup-node-6
chore(deps): bump actions/setup-node from 4 to 6
2026-03-05 01:30:16 +09:00
dependabot[bot]
bb44461bab
chore(deps-dev): bump vite from 6.4.1 to 7.3.1 in /vrc-get-gui
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 6.4.1 to 7.3.1.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.1/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 16:25:38 +00:00
anatawa12
4332876651
Merge pull request #2557 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/react-47b46a4058
chore(deps): bump the react group across 1 directory with 4 updates
2026-03-05 01:23:19 +09:00
anatawa12
50e38cebbe
Merge pull request #2682 from vrc-get/dependabot/cargo/bytes-1.11.1
chore(deps): bump bytes from 1.10.1 to 1.11.1
2026-03-05 01:21:36 +09:00
dependabot[bot]
88a0b77e5d
chore(deps): bump actions/setup-node from 4 to 6
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 16:21:15 +00:00
anatawa12
fe7d9d776c
Merge pull request #2686 from vrc-get/dependabot/github_actions/actions/download-artifact-8
chore(deps): bump actions/download-artifact from 5 to 8
2026-03-05 01:20:29 +09:00
anatawa12
9e3171b56c
Merge pull request #2688 from vrc-get/dependabot/github_actions/actions/upload-artifact-7
chore(deps): bump actions/upload-artifact from 4 to 7
2026-03-05 01:20:15 +09:00
anatawa12
df7d7e0f56
Merge pull request #2511 from vrc-get/dependabot/github_actions/actions/github-script-8
chore(deps): bump actions/github-script from 7 to 8
2026-03-05 01:05:14 +09:00
anatawa12
bfe8041047
Merge pull request #2512 from vrc-get/dependabot/github_actions/actions/labeler-6
chore(deps): bump actions/labeler from 5 to 6
2026-03-05 01:04:46 +09:00
anatawa12
96248ade9d
Merge pull request #2620 from vrc-get/dependabot/github_actions/actions/checkout-6
chore(deps): bump actions/checkout from 5 to 6
2026-03-05 01:03:45 +09:00
dependabot[bot]
c8e8ab51d5
chore(deps): bump the react group across 1 directory with 4 updates
Bumps the react group with 4 updates in the /vrc-get-gui directory: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react), [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).


Updates `react` from 19.1.1 to 19.2.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.0/packages/react)

Updates `@types/react` from 19.1.11 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.1.1 to 19.2.0
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.2.0/packages/react-dom)

Updates `@types/react-dom` from 19.1.7 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@types/react` from 19.1.11 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.1.7 to 19.2.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 15:56:18 +00:00
anatawa12
d746140499
Merge pull request #2707 from vrc-get/update-deps
chore: update more deps
2026-03-05 00:54:19 +09:00
anatawa12
ce829ccae4
Merge pull request #2647 from vrc-get/dependabot/github_actions/actions/cache-5
chore(deps): bump actions/cache from 4 to 5
2026-03-05 00:48:07 +09:00
anatawa12
b231c500a3
chore: update more deps 2026-03-05 00:38:33 +09:00
dependabot[bot]
911541bac4
chore(deps): bump actions/download-artifact from 5 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 15:38:25 +00:00
anatawa12
5c2385ea96
Merge pull request #2706 from vrc-get/dependabot/cargo/windows-0.62.2
chore(deps): bump windows from 0.61.3 to 0.62.2
2026-03-05 00:36:08 +09:00
anatawa12
29c076dc9a
Merge pull request #2704 from vrc-get/dependabot/cargo/nix-0.31.2
chore(deps): bump nix from 0.30.1 to 0.31.2
2026-03-05 00:35:25 +09:00
anatawa12
fbe3d42492
Merge pull request #2702 from vrc-get/dependabot/cargo/log-0.4.29
chore(deps): bump log from 0.4.27 to 0.4.29
2026-03-05 00:35:09 +09:00
dependabot[bot]
7d74bcec30
chore(deps): bump windows from 0.61.3 to 0.62.2
Bumps [windows](https://github.com/microsoft/windows-rs) from 0.61.3 to 0.62.2.
- [Release notes](https://github.com/microsoft/windows-rs/releases)
- [Commits](https://github.com/microsoft/windows-rs/commits)

---
updated-dependencies:
- dependency-name: windows
  dependency-version: 0.62.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 15:19:15 +00:00
dependabot[bot]
e8505ace12
chore(deps): bump object from 0.37.3 to 0.38.1
Bumps [object](https://github.com/gimli-rs/object) from 0.37.3 to 0.38.1.
- [Changelog](https://github.com/gimli-rs/object/blob/master/CHANGELOG.md)
- [Commits](https://github.com/gimli-rs/object/compare/0.37.3...0.38.1)

---
updated-dependencies:
- dependency-name: object
  dependency-version: 0.38.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 15:18:52 +00:00
dependabot[bot]
2faca4c5a2
chore(deps): bump nix from 0.30.1 to 0.31.2
Bumps [nix](https://github.com/nix-rust/nix) from 0.30.1 to 0.31.2.
- [Changelog](https://github.com/nix-rust/nix/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nix-rust/nix/compare/v0.30.1...v0.31.2)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 0.31.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 15:17:56 +00:00
anatawa12
5252b0e0e6
Merge pull request #2703 from vrc-get/fix-lint
lint: update to fix lints
2026-03-05 00:14:04 +09:00
anatawa12
8d914e3cf4
lint: update to fix lints 2026-03-05 00:04:55 +09:00
anatawa12
bdc5a8ac36
Merge pull request #2681 from vrc-get/update-deps
chore: update deps
2026-03-04 23:55:13 +09:00
anatawa12
483f8dd0fd
chore: register zlib license 2026-03-04 23:43:35 +09:00
anatawa12
b570f01931
chore: match tauri versions 2026-03-04 22:44:50 +09:00
dependabot[bot]
d5ae35c5c1
chore(deps): bump log from 0.4.27 to 0.4.29
Bumps [log](https://github.com/rust-lang/log) from 0.4.27 to 0.4.29.
- [Release notes](https://github.com/rust-lang/log/releases)
- [Changelog](https://github.com/rust-lang/log/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/log/compare/0.4.27...0.4.29)

---
updated-dependencies:
- dependency-name: log
  dependency-version: 0.4.29
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 13:43:54 +00:00
dependabot[bot]
345006328d
chore(deps): bump actions/upload-artifact from 4 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 13:35:50 +00:00
anatawa12
d34a1ff529
Merge pull request #2679 from vrc-get/fix-unitypackage-extract
fix: UnityPackages with files Packages fails to extract
2026-03-04 20:41:55 +09:00
dependabot[bot]
408916325b
chore(deps): bump bytes from 1.10.1 to 1.11.1
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 11:33:42 +00:00
anatawa12
072e401d82
Merge branch 'master' into fix-unitypackage-extract 2026-03-04 20:24:46 +09:00
anatawa12
a7dbf1e85e
chore: update deps (cargo) 2026-03-04 20:19:25 +09:00
anatawa12
42031f1716
chore: update deps (npm) 2026-03-04 20:17:06 +09:00
anatawa12
3ad5ccb200
Merge pull request #2677 from vrc-get/use-rsvg-convert
chore: use rsvg-convert for generating booth thumbnail
2026-03-04 20:10:01 +09:00
anatawa12
86e5529b0e
docs(changelog): Fails to import UnityPackages with files in Packages directory 2026-03-04 20:07:14 +09:00
dependabot[bot]
f0440d3c40
chore(deps): bump actions/labeler from 5 to 6
Bumps [actions/labeler](https://github.com/actions/labeler) from 5 to 6.
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](https://github.com/actions/labeler/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/labeler
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 11:05:49 +00:00
anatawa12
4695d60b56
fix: UnityPackages with files Packages fails to extract 2026-03-04 20:05:02 +09:00
dependabot[bot]
f846d2c41f
chore(deps): bump actions/github-script from 7 to 8
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 11:02:28 +00:00
anatawa12
cc55272841
chore: use rsvg-convert for generating booth thumbnail 2026-03-04 19:54:56 +09:00
anatawa12
8c85a9cb13
Merge pull request #2671 from Spokeek/update-dependencies
Update NPM Javascript dependencies
2026-03-04 19:29:09 +09:00
anatawa12
21ed073c99
fix: typecheck for SideBar 2026-03-04 19:17:50 +09:00
Spokeek
1544967281
chores: Fix issues with Tanstack Router
Required since upgrade of the tanstack route generation changes that value automatically
Some routines to provide intellisense aren't working, had to temporary disable
2026-02-13 21:43:56 +01:00
Spokeek
d0d8cdaf19
chores: Run npm upgrade
Updates to latest compatible version for JS libraries
2026-02-13 20:56:44 +01:00
Spokeek
c3291d9993
chores: lock version for tauri packages 2026-02-13 20:34:17 +01:00
Spokeek
1de47356ad
lint: Enable TailwindDirectives for Biome linter 2026-02-13 20:26:09 +01:00
Spokeek
9a6475f001
feat: Using a sharp library to prepare the booth preview picture 2026-02-13 20:23:47 +01:00
Spokeek
7c6ee29928
depency: removal of sharp-cli library 2026-02-13 19:53:15 +01:00
Spokeek
2753ffa3db
chore: removed unused serde deserialize use 2026-02-13 19:52:58 +01:00
Spokeek
2228b08b3a
chore: Apply last default route from TanStack Router 2026-02-13 19:30:39 +01:00
Spokeek
aa9dbb0057
chore: cleanup npm lock 2026-02-13 19:29:14 +01:00
dependabot[bot]
61e2a9a78d
chore(deps-dev): bump typescript from 5.9.2 to 5.9.3 in /vrc-get-gui
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.9.2 to 5.9.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.2...v5.9.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.9.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:55 +01:00
dependabot[bot]
b6ac50cc74
chore(deps): bump @tanstack/react-query in /vrc-get-gui
Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.85.5 to 5.90.12.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.90.12/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.90.12
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:54 +01:00
dependabot[bot]
377b4ce340
chore(deps-dev): bump @vitejs/plugin-react-swc in /vrc-get-gui
Bumps [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react-swc) from 4.0.1 to 4.2.2.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react-swc@4.2.2/packages/plugin-react-swc)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react-swc"
  dependency-version: 4.2.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:54 +01:00
dependabot[bot]
18fc1fa4bd
chore(deps-dev): bump vite-plugin-json5 in /vrc-get-gui
Bumps [vite-plugin-json5](https://github.com/sneakylenny/vite-plugin-json5) from 1.1.9 to 1.2.0.
- [Release notes](https://github.com/sneakylenny/vite-plugin-json5/releases)
- [Commits](https://github.com/sneakylenny/vite-plugin-json5/compare/v1.1.9...v1.2.0)

---
updated-dependencies:
- dependency-name: vite-plugin-json5
  dependency-version: 1.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:54 +01:00
dependabot[bot]
6e2caedc2d
chore(deps-dev): bump tw-animate-css from 1.3.7 to 1.4.0 in /vrc-get-gui
Bumps [tw-animate-css](https://github.com/Wombosvideo/tw-animate-css) from 1.3.7 to 1.4.0.
- [Release notes](https://github.com/Wombosvideo/tw-animate-css/releases)
- [Commits](https://github.com/Wombosvideo/tw-animate-css/compare/v1.3.7...v1.4.0)

---
updated-dependencies:
- dependency-name: tw-animate-css
  dependency-version: 1.4.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:54 +01:00
dependabot[bot]
b39242c710
chore(deps): bump the tanstack-router group
Bumps the tanstack-router group in /vrc-get-gui with 3 updates: [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router), [@tanstack/router-devtools](https://github.com/TanStack/router/tree/HEAD/packages/router-devtools) and [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin).

Updates `@tanstack/react-router` from 1.131.27 to 1.131.31
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.131.31/packages/react-router)

Updates `@tanstack/router-devtools` from 1.131.27 to 1.131.31
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.131.31/packages/router-devtools)

Updates `@tanstack/router-plugin` from 1.131.27 to 1.131.31
- [Release notes](https://github.com/TanStack/router/releases)
- [Commits](https://github.com/TanStack/router/commits/v1.131.31/packages/router-plugin)

---
updated-dependencies:
- dependency-name: "@tanstack/react-router"
  dependency-version: 1.131.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-devtools"
  dependency-version: 1.131.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
- dependency-name: "@tanstack/router-plugin"
  dependency-version: 1.131.31
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tanstack-router
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:54 +01:00
dependabot[bot]
30c7fb2c1b
chore(deps-dev): bump @tailwindcss/vite
Bumps the tailwindcss group in /vrc-get-gui with 1 update: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite).


Updates `@tailwindcss/vite` from 4.1.12 to 4.1.13
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.13/packages/@tailwindcss-vite)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.1.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tailwindcss
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
dependabot[bot]
03771c8be3
chore(deps): bump tailwind-merge from 3.3.1 to 3.4.0 in /vrc-get-gui
Bumps [tailwind-merge](https://github.com/dcastil/tailwind-merge) from 3.3.1 to 3.4.0.
- [Release notes](https://github.com/dcastil/tailwind-merge/releases)
- [Commits](https://github.com/dcastil/tailwind-merge/compare/v3.3.1...v3.4.0)

---
updated-dependencies:
- dependency-name: tailwind-merge
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
dependabot[bot]
b332d12e0b
chore(deps): bump the radix-ui group in /vrc-get-gui with 4 updates
Bumps the radix-ui group in /vrc-get-gui with 4 updates: [@radix-ui/react-label](https://github.com/radix-ui/primitives), [@radix-ui/react-progress](https://github.com/radix-ui/primitives), [@radix-ui/react-separator](https://github.com/radix-ui/primitives) and [@radix-ui/react-slot](https://github.com/radix-ui/primitives).


Updates `@radix-ui/react-label` from 2.1.7 to 2.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-progress` from 1.1.7 to 1.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-separator` from 1.1.7 to 1.1.8
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

Updates `@radix-ui/react-slot` from 1.2.3 to 1.2.4
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-label"
  dependency-version: 2.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: radix-ui
- dependency-name: "@radix-ui/react-progress"
  dependency-version: 1.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: radix-ui
- dependency-name: "@radix-ui/react-separator"
  dependency-version: 1.1.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: radix-ui
- dependency-name: "@radix-ui/react-slot"
  dependency-version: 1.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: radix-ui
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
dependabot[bot]
df1fc5a591
chore(deps): bump the i18next group across 1 directory with 2 updates
Bumps the i18next group with 2 updates in the /vrc-get-gui directory: [i18next](https://github.com/i18next/i18next) and [react-i18next](https://github.com/i18next/react-i18next).


Updates `i18next` from 25.4.2 to 25.5.2
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v25.4.2...v25.5.2)

Updates `react-i18next` from 15.7.2 to 15.7.3
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/react-i18next/compare/v15.7.2...v15.7.3)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 25.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: i18next
- dependency-name: react-i18next
  dependency-version: 15.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
dependabot[bot]
28be7e8202
chore(deps-dev): bump @biomejs/biome from 2.2.2 to 2.3.8 in /vrc-get-gui
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.2.2 to 2.3.8.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.3.8/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.3.8
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
dependabot[bot]
23f09836a0
chore(deps): bump lucide-react from 0.541.0 to 0.561.0 in /vrc-get-gui
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.541.0 to 0.561.0.
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/0.561.0/packages/lucide-react)

---
updated-dependencies:
- dependency-name: lucide-react
  dependency-version: 0.561.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-13 19:28:14 +01:00
anatawa12
a9ff68b47a
Merge pull request #2632 from tompointexe/patch-1
Update French translations for ALCOM
2026-01-21 17:24:02 +09:00
anatawa12
edb8c2d2d9
Merge pull request #2641 from o-tr/fix/webkit-transition-bug
fix: アップデートのダウンロード時にプログレスバーがちらつく
2025-12-28 21:46:47 +09:00
anatawa12
3ce9fd58d3
lint: fix biome lint error 2025-12-28 21:36:05 +09:00
anatawa12
73998e7f2c
chore: update to include bugzilla link 2025-12-28 21:29:58 +09:00
dependabot[bot]
51aa98ab2b
chore(deps): bump actions/cache from 4 to 5
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 07:07:33 +00:00
ootr
df3efbcf65
fix: add comment to describe change from shadcn 2025-12-13 16:43:18 +09:00
ootr
3f28dbe371
fix: replace issue url with pr url 2025-12-13 16:40:27 +09:00
ootr
0abcadb979
chore: update changelog 2025-12-13 16:27:07 +09:00
ootr
e5d7c492d2
fix: remove transition-all to fix a webkit bug
close #2640
2025-12-13 16:21:07 +09:00
Sayamame-beans
670642d8cb chore(l10n): [ja] update locale 2025-12-06 20:59:03 +09:00
Sayamame-beans
d2cabbdc0b chore(l10n): [en] add "general:toast:invalid file" 2025-12-06 20:58:50 +09:00
Sayamame-beans
257a479f3e chore: rename "Id" for ReorderableList to "ReorderableListId" 2025-12-06 20:58:11 +09:00
Sayamame-beans
add44e04a9 chore: run cargo fmt 2025-12-06 18:12:23 +09:00
Sayamame-beans
c1eb9ffc16 docs(changelog-gui): update changelog 2025-12-06 18:09:40 +09:00
Sayamame-beans
6104fc017d feat: allow reselecting unitypackage path on Template Editor 2025-12-06 18:06:44 +09:00
Tom.exe
be4d898668
Update French translation
Changed "Mis en avant" by "Sélection par VRChat"
2025-12-05 11:37:22 +01:00
Tom.exe
a21606f011
Update French translations
Changed importing existing project translation
2025-12-04 13:41:50 +01:00
dependabot[bot]
5859403cad
chore(deps): bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-24 07:32:57 +00:00
github-actions[bot]
b9596cb56a chore: prepare for next version: gui 1.1.6 2025-11-16 09:12:33 +00:00
github-actions[bot]
9c2963b21c gui v1.1.5 2025-11-16 09:00:48 +00:00
github-actions[bot]
194ae0b96d gui v1.1.5-beta.1 2025-11-14 06:54:25 +00:00
anatawa12
d370a5195c
Merge pull request #2608 from vrc-get/anatawa12-patch-1 2025-11-14 14:52:13 +09:00
anatawa12
85edddbf0d
ci: use windows 2022 for publishing 2025-11-14 14:46:30 +09:00
anatawa12
ceaf3a9cce
Merge pull request #2607 from vrc-get/fix-unexpected-detected-loop
fix: unexpected 'Detected Loop' panic
2025-11-14 14:11:05 +09:00
anatawa12
ad5f28ce6a
docs(changelog): Fix 'Detected Loop' panic with valid database file 2025-11-14 14:02:54 +09:00
anatawa12
6251e87fbe
fix: unexpected 'Detected Loop' panic 2025-11-14 14:01:16 +09:00
anatawa12
a239686702
Merge pull request #2589 from lonelyicer/fix/dropdown-overlap
fix: limit max height of package version selector
2025-11-14 13:58:38 +09:00
anatawa12
6f4ded7ed7
Merge branch 'master' into fix/dropdown-overlap 2025-11-14 13:35:08 +09:00
anatawa12
912609d681
Merge pull request #2606 from vrc-get/bump-rust
Bump rust
2025-11-14 12:33:09 +09:00
anatawa12
a64426984c
lint: remove unused import 2025-11-14 12:21:22 +09:00
anatawa12
7a30129796
lint: remove with_added_extension witch is stable in 1.91 2025-11-14 12:20:15 +09:00
RingLo_
c706ce7b27
docs(changelog): add pr number 2025-11-14 07:18:40 +08:00
RingLo_
933933e287 docs(changelog): update for #2589 2025-10-30 20:37:12 +08:00
RingLo_
f5fa8a5e2f fix: limit max height of package version selector 2025-10-30 20:32:29 +08:00
anatawa12
d120156b50
Merge pull request #2562 from tukiminya/style/change-strong-tag
style: change strong to b tag for stylistic emphasis
2025-10-23 01:35:50 +09:00
anatawa12
0c50a14ba7
Merge branch 'master' into style/change-strong-tag 2025-10-23 01:17:20 +09:00
anatawa12
274ef9f33d
Merge pull request #2571 from vrc-get/fix-ci-failure
ci: try to fix the CI failure with aarc64 linux images
2025-10-23 01:15:01 +09:00
anatawa12
94971631a3
ci: override rustflags for static link check 2025-10-23 00:47:49 +09:00
tukimi
3aadcf21d7
style: change strong to b tag for stylistic emphasis 2025-10-18 04:15:03 +09:00
anatawa12
beffbeae47
Merge pull request #2517 from o-tr/fix/dialog
fix: replace some DialogDescription with div in dialog components
2025-09-15 03:43:51 +09:00
ootr
8b0956c6df
fix: formats 2025-09-15 02:29:17 +09:00
ootr
4db0e64e81
fix: update changelog for muted-foreground color fix and remove DialogDescription 2025-09-15 02:28:08 +09:00
ootr
c679ed69fa
fix: replace some DialogDescription with div in dialog components 2025-09-15 02:25:50 +09:00
anatawa12
1394691f4a
Merge pull request #2516 from o-tr/fix/muted-foreground-color
fix: muted-foreground color definition in css
2025-09-15 02:20:57 +09:00
ootr
229118fb9e
fix: update changelog for muted-foreground color fix 2025-09-15 01:56:39 +09:00
ootr
54e4ad3756
fix: muted-foreground color definition in css 2025-09-15 01:47:28 +09:00
github-actions[bot]
ed9a12ee80 chore: prepare for next version: gui 1.1.5 2025-09-02 04:40:32 +00:00
github-actions[bot]
dbe60c6a6e gui v1.1.4 2025-09-02 04:29:13 +00:00
anatawa12
caec80ce05
Merge pull request #2489 from CirnoV/locale/ko-KR
chore(l10n): [ko_kr] update locale
2025-09-02 00:29:42 +09:00
CirnoV
3c3dc35ea3 chore(l10n): [ko_kr] update locale 2025-09-01 22:48:53 +09:00
github-actions[bot]
03cac441dd gui v1.1.4-rc.1 2025-09-01 13:13:46 +00:00
anatawa12
45a9ab02fb
Merge pull request #2485 from vrc-get/less-settings-loss
Improve settings store / load for less error
2025-09-01 19:47:26 +09:00
anatawa12
35bc7ff4a5
docs(changelog): Improved saving interacting with setting files 2025-09-01 19:41:08 +09:00
anatawa12
447f371598
chore: treat empty file as '{}' instead of throwing error 2025-09-01 19:36:13 +09:00
anatawa12
2f71bcf9d3
feat: atomically overwrite existing file
This should improve crash stability
2025-09-01 19:01:55 +09:00
anatawa12
b42e4c29a1
Merge pull request #2482 from vrc-community-assets-tc-translators/master
chore(l10n): [zh_hant] update locale
2025-08-27 15:05:38 +09:00
夜嵐蝶Alma
033d8ea05c chore(l10n): [zh_hant] update locale 2025-08-27 13:54:56 +08:00
anatawa12
0a64ce7194
Merge pull request #2481 from Spokeek/french-translation
Updated FR translations for 1.1.4-rc
2025-08-25 22:46:17 +09:00
Spokeek
2362b55407
Updated FR translations for 1.1.4-rc 2025-08-25 15:04:26 +02:00
github-actions[bot]
420e640f00 gui v1.1.4-rc.0 2025-08-24 19:39:07 +00:00
anatawa12
3e60bf15e9
Merge pull request #2479 from vrc-get/localization-summary
Localization summary at discussion
2025-08-25 04:00:06 +09:00
anatawa12
7e240df2c5
ci: update English Localization and Text Representation 2025-08-25 03:54:23 +09:00
anatawa12
da4efddb1c
ci: refactor localization-updates.js 2025-08-25 03:54:23 +09:00
anatawa12
a4e447021c
Merge pull request #2478 from vrc-get/ringbuffer-0.16
chore(deps): ringbuffer 0.16
2025-08-25 03:20:12 +09:00
dependabot[bot]
693fc96583
Merge pull request #2476 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/vitejs/plugin-react-swc-4.0.1 2025-08-24 18:13:37 +00:00
anatawa12
68b63967db
Merge pull request #2477 from vrc-get/fix-for-old-bug
chore: add a fix for a bug in the previous version of ALCOM
2025-08-25 03:13:25 +09:00
anatawa12
50e458c5c6
chore(deps): ringbuffer 0.16 2025-08-25 03:09:24 +09:00
dependabot[bot]
3204c31447
chore(deps-dev): bump @vitejs/plugin-react-swc in /vrc-get-gui
Bumps [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react-swc) from 3.11.0 to 4.0.1.
- [Release notes](https://github.com/vitejs/vite-plugin-react/releases)
- [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@4.0.1/packages/plugin-react-swc)

---
updated-dependencies:
- dependency-name: "@vitejs/plugin-react-swc"
  dependency-version: 4.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-24 18:01:26 +00:00
dependabot[bot]
416448ddec
Merge pull request #2437 from vrc-get/dependabot/cargo/async_zip-0.0.18 2025-08-24 18:00:31 +00:00
anatawa12
b1ab5c46c0
chore: add a fix for a bug in the previous version of ALCOM 2025-08-25 02:59:14 +09:00
dependabot[bot]
b4eb2e4116
Merge pull request #2431 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/react-8560841430 2025-08-24 17:58:08 +00:00
dependabot[bot]
3ecd463963
Merge pull request #2475 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tauri-apps/cli-2.8.2 2025-08-24 17:47:44 +00:00
dependabot[bot]
bcb2c9253b
chore(deps): bump async_zip from 0.0.17 to 0.0.18
Bumps [async_zip](https://github.com/Majored/rs-async-zip) from 0.0.17 to 0.0.18.
- [Release notes](https://github.com/Majored/rs-async-zip/releases)
- [Commits](https://github.com/Majored/rs-async-zip/compare/v0.0.17...v0.0.18)

---
updated-dependencies:
- dependency-name: async_zip
  dependency-version: 0.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-24 17:45:52 +00:00
dependabot[bot]
874800f371
Merge pull request #2441 from vrc-get/dependabot/github_actions/actions/download-artifact-5 2025-08-24 17:45:37 +00:00
dependabot[bot]
18105daae5
chore(deps-dev): bump @tauri-apps/cli in /vrc-get-gui
Bumps [@tauri-apps/cli](https://github.com/tauri-apps/tauri) from 2.8.1 to 2.8.2.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/cli-v2.8.1...@tauri-apps/cli-v2.8.2)

---
updated-dependencies:
- dependency-name: "@tauri-apps/cli"
  dependency-version: 2.8.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-24 16:41:05 +00:00
dependabot[bot]
1713fb6f1c
chore(deps): bump the react group across 1 directory with 4 updates
Bumps the react group with 4 updates in the /vrc-get-gui directory: [react](https://github.com/facebook/react/tree/HEAD/packages/react), [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react), [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).


Updates `react` from 19.1.0 to 19.1.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.1.1/packages/react)

Updates `@types/react` from 19.1.7 to 19.1.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.1.0 to 19.1.1
- [Release notes](https://github.com/facebook/react/releases)
- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/react/commits/v19.1.1/packages/react-dom)

Updates `@types/react-dom` from 19.1.6 to 19.1.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@types/react` from 19.1.7 to 19.1.9
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.1.6 to 19.1.7
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: react
  dependency-version: 19.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: react-dom
  dependency-version: 19.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.1.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.1.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.1.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-24 16:41:03 +00:00
dependabot[bot]
c675d975bd
Merge pull request #2456 from vrc-get/dependabot/github_actions/actions/checkout-5 2025-08-24 16:38:27 +00:00
anatawa12
6c9900ed69
Merge pull request #2473 from vrc-get/update-deps
Update deps
2025-08-25 01:26:02 +09:00
anatawa12
2d83e0dade
fix: suppress unnecessary warnings 2025-08-25 01:19:36 +09:00
anatawa12
048ad943d4
fix: compiler warning with newer version of rust 2025-08-25 00:56:49 +09:00
anatawa12
a1b16b6ac6
chore(deps): update deps 2025-08-25 00:55:26 +09:00
anatawa12
518a8c671b
Merge pull request #2470 from vrc-get/compact-fixes
chore: improve compact mode and basic components
2025-08-24 23:56:40 +09:00
anatawa12
a7170b42c5
docs(changelog-gui): Add PR number to add compact gui option 2025-08-24 23:47:58 +09:00
anatawa12
ed70604b38
chore: improve compact mode and styling rule 2025-08-24 23:34:29 +09:00
anatawa12
30fa3e7bef
Merge pull request #2466 from vrc-get/copilot/fix-2464
Always allow Home/End and Up/Down keys for cursor navigation in autocomplete fields
2025-08-20 21:34:41 +09:00
copilot-swe-agent[bot]
a0e08ce48f Update changelog to include up/down arrow key functionality
Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 11:40:33 +00:00
copilot-swe-agent[bot]
d185db333c Allow up/down keys for cursor navigation when suggestions are not open
Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 10:26:20 +00:00
copilot-swe-agent[bot]
86f1afa140 Fix changelog to use PR number #2466 instead of issue number #2464
Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 10:22:04 +00:00
copilot-swe-agent[bot]
8485f35e17 Always allow Home/End keys for cursor navigation in autocomplete fields
Fixes #2464 where Home/End keys were inconsistently working for cursor navigation in Unity version and package information fields. Previously, these keys would sometimes be captured by the Command component for suggestion list navigation when suggestions were visible.

Now Home/End keys always control text cursor position regardless of autocomplete state, providing consistent behavior and better user experience.

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>

Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 10:07:17 +00:00
copilot-swe-agent[bot]
abcffbd849 Always allow Home/End keys to control cursor in autocomplete
Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 09:44:23 +00:00
copilot-swe-agent[bot]
b7e6d97484 Fix Home/End key navigation in autocomplete fields
Co-authored-by: anatawa12 <22656849+anatawa12@users.noreply.github.com>
2025-08-20 09:37:05 +00:00
copilot-swe-agent[bot]
9026343cdd Initial plan 2025-08-20 09:31:13 +00:00
anatawa12
74062136fd
Merge pull request #2450 from lonelyicer/chore/buton-compact
chore: button compact
2025-08-20 01:41:20 +09:00
Sayamame-beans
ec66e5c2f0
Merge pull request #2452 from vrc-get/fix-2435
fix: specifying a single unityversion doesn't work properly in alcomtemplate
2025-08-19 23:15:32 +09:00
Sayamame-beans
2e5c5da3cb
docs(changelog): Apply suggestion from code review
Co-authored-by: anatawa12 <anatawa12@icloud.com>
2025-08-19 22:50:54 +09:00
Sayamame-beans
0f0f0aaddb
Merge branch 'master' into fix-2435 2025-08-19 22:50:31 +09:00
RingLo_
5b7861a91e lint(biome): fix format 2025-08-19 21:13:38 +08:00
RingLo_
c90c495a31 chore: Improve compact mode sizing for navbars and buttons 2025-08-19 21:10:28 +08:00
RingLo_
c477121bc5
Merge branch 'master' into chore/buton-compact 2025-08-19 20:20:42 +08:00
RingLo_
7ff3b16c8e chore: Adjust layout spacing and wrapping in UI components 2025-08-19 20:19:44 +08:00
dependabot[bot]
d7b126f82a
chore(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 10:12:58 +00:00
Sayamame-beans
6af3d96cf2 fix: unintended breaking change for check for package version range 2025-08-18 08:04:59 +09:00
anatawa12
6a258a19b3
Merge pull request #2451 from JustBuddy/german-translation
chore(l10n): [de_DE] update locale
2025-08-18 02:38:30 +09:00
Sayamame-beans
544a9bd505 chore: apply biome fix 2025-08-18 02:11:26 +09:00
anatawa12
40ce7de7b7
Merge pull request #2449 from lonelyicer/gui-locale-zh_Hans
chore(l10n): [zh_hans] update locale
2025-08-18 01:32:42 +09:00
Sayamame-beans
6866b6f08c docs(changelog-gui): update changelog 2025-08-18 01:31:33 +09:00
Sayamame-beans
bcdb94861b fix: specifying a single unityversion doesn't work properly in alcomtemplate 2025-08-18 01:23:39 +09:00
JustBuddy
c32b59b9bf
chore(l10n): [de_DE] update locale
- Added compact mode keys.
2025-08-17 15:14:41 +02:00
RingLo_
b097013eba docs(changelog-gui): for #2450 2025-08-17 20:31:26 +08:00
RingLo_
d7d369b5fe lint(biome): fix format 2025-08-17 20:29:43 +08:00
RingLo_
520b79e0dd lint(biome): fix 2025-08-17 20:28:13 +08:00
RingLo_
52d3e158d3 chore: icon button size for compact 2025-08-17 19:39:49 +08:00
RingLo_
0a599c806b chore: button compact 2025-08-17 19:22:51 +08:00
RingLo_
16f65ec950 chore(l10n): [zh_hans] update locale 2025-08-17 17:40:35 +08:00
anatawa12
09ccfb9f4f
Merge pull request #2436 from nekobako/feature/compact-gui
feat: add compact gui option
2025-08-17 14:49:44 +09:00
nekobako
4d7a923eaf chore: fix format 2025-08-17 10:18:23 +09:00
nekobako
3c6385e75f feat: adjust compact styles 2025-08-17 10:18:13 +09:00
nekobako
8331d1d978 chore: fix format 2025-08-16 16:57:13 +09:00
nekobako
b1d28f4efc chore: replace Tooltip and Button in SideBar with SideBarButton 2025-08-16 12:40:17 +09:00
nekobako
54fbb7ceff Revert "chore: add TooltipButton"
This reverts commit dce7c74f45.
2025-08-15 19:20:08 +09:00
nekobako
dce7c74f45 chore: add TooltipButton 2025-08-14 21:18:48 +09:00
nekobako
4abb31287f chore: remove redundant element 2025-08-14 21:18:48 +09:00
nekobako
a7bf336674 feat: apply compact style to setup page 2025-08-14 21:18:48 +09:00
nekobako
0cb111bba8 feat: apply compact style to package list and log list 2025-08-13 18:33:46 +09:00
nekobako
68b1ed245b chore: use custom variant for styling 2025-08-13 02:23:59 +09:00
dependabot[bot]
f769dd45a6
chore(deps): bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 11:05:57 +00:00
nekobako
261f3a97cb docs(changelog-gui): Add compact gui option 2025-08-11 18:12:16 +09:00
nekobako
3399b0fa00 feat: add compact gui option 2025-08-09 21:32:17 +09:00
github-actions[bot]
e89e1340a0 chore: prepare for next version: gui 1.1.4 2025-07-28 12:21:30 +00:00
github-actions[bot]
70b0c7c7e6 gui v1.1.3 2025-07-28 12:07:51 +00:00
github-actions[bot]
6eb2422362 chore: prepare for next version: 1.9.2 2025-07-28 12:05:45 +00:00
github-actions[bot]
7b9f009e17 v1.9.1 2025-07-28 11:57:39 +00:00
anatawa12
12f4244814
Merge pull request #2402 from ColorlessColor/patch-1 2025-07-28 20:55:31 +09:00
ColorlessColor
cc139a07e1
chore(l10n): [zh_hans] update locale 2025-07-28 09:12:09 +08:00
github-actions[bot]
42e3ba176d gui v1.1.3-beta.2 2025-07-24 14:58:43 +00:00
anatawa12
0925dcbca6
Merge pull request #2400 from CirnoV/locale/ko-KR
chore(I10n): [ko_KR] update locale
2025-07-24 23:19:33 +09:00
CirnoV
2edaa8c846 chore(I10n): [ko_KR] update locale 2025-07-24 22:13:55 +09:00
anatawa12
f1c0afd6cc
Merge pull request #2398 from Spokeek/french-translation
Add fr translations 1.1.3
2025-07-19 14:39:20 +09:00
Spokeek
1a03dea7c9
fix typo 2025-07-18 18:00:02 +02:00
Spokeek
1ef62e6f79
Add fr translations 1.1.3 2025-07-18 17:58:46 +02:00
anatawa12
ef33365884
Merge pull request #2397 from lonelyicer/gui-locale-zh_Hans
chore(l10n): [zh_hans] update locale
2025-07-18 01:16:06 +09:00
RingLo_
b27a9ce01d chore(l10n): [zh_hans] update locale 2025-07-17 22:18:06 +08:00
anatawa12
13174eba98
Merge pull request #2395 from vrc-community-assets-tc-translators/master
chore(l10n): [zh_hant] update locale
2025-07-16 12:05:58 +09:00
夜嵐蝶Alma
0dbf59dd85 chore(l10n): [zh_hant] update locale 2025-07-16 00:35:03 +08:00
dependabot[bot]
7a5aed016d
Merge pull request #2392 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/i18next-10c2bfaf3b 2025-07-14 09:59:37 +00:00
dependabot[bot]
8e703a718b
Merge pull request #2389 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/biomejs/biome-2.1.1 2025-07-14 09:58:19 +00:00
anatawa12
a78ebd4f52
Merge pull request #2390 from JustBuddy/german-translation
chore(l10n): [de_DE] update locale
2025-07-14 18:56:39 +09:00
dependabot[bot]
3342e069dd
chore(deps): bump i18next in /vrc-get-gui in the i18next group
Bumps the i18next group in /vrc-get-gui with 1 update: [i18next](https://github.com/i18next/i18next).


Updates `i18next` from 25.3.1 to 25.3.2
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v25.3.1...v25.3.2)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 25.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: i18next
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 09:43:44 +00:00
dependabot[bot]
bde51b52e3
chore(deps-dev): bump @biomejs/biome from 2.0.6 to 2.1.1 in /vrc-get-gui
Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.0.6 to 2.1.1.
- [Release notes](https://github.com/biomejs/biome/releases)
- [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md)
- [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.1.1/packages/@biomejs/biome)

---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.1.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 09:40:40 +00:00
JustBuddy
357ead18ce
chore(l10n): [de_DE] update locale 2025-07-14 11:39:19 +02:00
dependabot[bot]
7c8a40bd2b
Merge pull request #2384 from vrc-get/dependabot/cargo/plist-1.7.4 2025-07-14 09:23:31 +00:00
dependabot[bot]
56d883fa6d
Merge pull request #2385 from vrc-get/dependabot/cargo/clap-8ce38b5983 2025-07-14 09:23:06 +00:00
dependabot[bot]
f69d968680
Merge pull request #2386 from vrc-get/dependabot/cargo/async-compression-0.4.27 2025-07-14 09:22:58 +00:00
dependabot[bot]
d5b4c28b34
chore(deps): bump async-compression from 0.4.25 to 0.4.27
Bumps [async-compression](https://github.com/Nullus157/async-compression) from 0.4.25 to 0.4.27.
- [Release notes](https://github.com/Nullus157/async-compression/releases)
- [Changelog](https://github.com/Nullus157/async-compression/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Nullus157/async-compression/compare/v0.4.25...v0.4.27)

---
updated-dependencies:
- dependency-name: async-compression
  dependency-version: 0.4.27
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 08:36:11 +00:00
dependabot[bot]
d7c8cea78a
chore(deps): bump the clap group with 2 updates
Bumps the clap group with 2 updates: [clap](https://github.com/clap-rs/clap) and [clap_complete](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.40 to 4.5.41
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.40...clap_complete-v4.5.41)

Updates `clap_complete` from 4.5.54 to 4.5.55
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.54...clap_complete-v4.5.55)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.41
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: clap
- dependency-name: clap_complete
  dependency-version: 4.5.55
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: clap
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 08:27:17 +00:00
dependabot[bot]
aebaf83dde
chore(deps): bump plist from 1.7.3 to 1.7.4
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.7.3 to 1.7.4.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Changelog](https://github.com/ebarnard/rust-plist/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.7.3...v1.7.4)

---
updated-dependencies:
- dependency-name: plist
  dependency-version: 1.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 08:12:36 +00:00
anatawa12
13feb4e889
Merge pull request #2383 from vrc-get/update_l10n_ja
chore(l10n): [ja] update locale
2025-07-09 18:13:20 +09:00
Sayamame-beans
cbcd0a5268 chore(l10n): [ja] update locale 2025-07-09 17:25:24 +09:00
github-actions[bot]
88b8043084 v1.9.1-beta.1 2025-07-08 10:18:01 +00:00
anatawa12
fe95e0f893
Merge pull request #2379 from vrc-get/litedb-on-crates-io
chore(deps): use litedb from crates.io
2025-07-08 15:47:28 +09:00
anatawa12
d741270d43
chore(deps): use litedb from crates.io 2025-07-08 15:40:31 +09:00
github-actions[bot]
ba826a9856 gui v1.1.3-beta.1 2025-07-08 05:47:27 +00:00
anatawa12
73a802103e
Merge pull request #2378 from vrc-get/release-concurrency
ci: set concurrency for publish actions
2025-07-08 14:46:25 +09:00
anatawa12
ecc94f9771
ci: set concurrency for publish actions 2025-07-08 14:40:06 +09:00
dependabot[bot]
92e71a4929
Merge pull request #2345 from vrc-get/dependabot/cargo/tauri-plugin-single-instance-2.3.0 2025-07-08 05:28:28 +00:00
dependabot[bot]
43869ae594
chore(deps): bump tauri-plugin-single-instance from 2.2.4 to 2.3.0
Bumps [tauri-plugin-single-instance](https://github.com/tauri-apps/plugins-workspace) from 2.2.4 to 2.3.0.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/opener-v2.2.4...os-v2.3.0)

---
updated-dependencies:
- dependency-name: tauri-plugin-single-instance
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-08 05:17:25 +00:00
anatawa12
9e23a3f794
Merge pull request #2377 from vrc-get/deps
remove svgo dep and update npm deps
2025-07-08 14:07:54 +09:00
anatawa12
5f57cd6954
chore: update installer.nsi for newer macro 2025-07-08 14:01:15 +09:00
dependabot[bot]
19fc2ea44f
Merge pull request #2362 from vrc-get/dependabot/cargo/vrc-get-litedb-f4692f8 2025-07-08 04:36:11 +00:00
anatawa12
77fc446770
chore: update routeTree.gen.ts 2025-07-08 13:35:48 +09:00
anatawa12
28b585a754
chore: add license file logic for unlicense 2025-07-08 13:29:20 +09:00
anatawa12
f0599e37f6
chore: add Unlicense as allowed license 2025-07-08 13:06:58 +09:00
anatawa12
08b4b83cf6
chore(deps): update npm deps 2025-07-08 12:59:26 +09:00
anatawa12
eddf19d989
chore(deps): remove svgo 2025-07-08 12:56:53 +09:00
dependabot[bot]
8830701a43
Merge pull request #2368 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tw-animate-css-1.3.5 2025-07-08 03:08:29 +00:00
dependabot[bot]
8cc0f2c865
chore(deps-dev): bump tw-animate-css from 1.3.4 to 1.3.5 in /vrc-get-gui
Bumps [tw-animate-css](https://github.com/Wombosvideo/tw-animate-css) from 1.3.4 to 1.3.5.
- [Release notes](https://github.com/Wombosvideo/tw-animate-css/releases)
- [Commits](https://github.com/Wombosvideo/tw-animate-css/compare/v1.3.4...v1.3.5)

---
updated-dependencies:
- dependency-name: tw-animate-css
  dependency-version: 1.3.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:53:02 +00:00
dependabot[bot]
50376cd537
Merge pull request #2365 from vrc-get/dependabot/cargo/reqwest-0.12.22 2025-07-07 19:44:15 +00:00
dependabot[bot]
acc97794c7
Merge pull request #2353 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tauri-apps/api-2.6.0 2025-07-07 19:41:53 +00:00
dependabot[bot]
4e85bd674b
Merge pull request #2349 from vrc-get/dependabot/cargo/tauri-plugin-dialog-2.3.0 2025-07-07 19:41:27 +00:00
dependabot[bot]
6085d0c8da
Merge pull request #2352 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/sharp-cli-5.2.0 2025-07-07 19:31:56 +00:00
dependabot[bot]
49d2383d0b
Merge pull request #2351 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/biomejs/biome-2.0.6 2025-07-07 19:31:20 +00:00
dependabot[bot]
3a059b8076
Merge pull request #2363 from vrc-get/dependabot/cargo/tokio-1.46.1 2025-07-07 19:27:31 +00:00
dependabot[bot]
3ea86ca01a
chore(deps): bump tauri-plugin-dialog from 2.2.2 to 2.3.0
Bumps [tauri-plugin-dialog](https://github.com/tauri-apps/plugins-workspace) from 2.2.2 to 2.3.0.
- [Release notes](https://github.com/tauri-apps/plugins-workspace/releases)
- [Commits](https://github.com/tauri-apps/plugins-workspace/compare/os-v2.2.2...os-v2.3.0)

---
updated-dependencies:
- dependency-name: tauri-plugin-dialog
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:22:36 +00:00
dependabot[bot]
b06d839f6f
chore(deps): bump @tauri-apps/api from 2.5.0 to 2.6.0 in /vrc-get-gui
Bumps [@tauri-apps/api](https://github.com/tauri-apps/tauri) from 2.5.0 to 2.6.0.
- [Release notes](https://github.com/tauri-apps/tauri/releases)
- [Commits](https://github.com/tauri-apps/tauri/compare/@tauri-apps/api-v2.5.0...@tauri-apps/api-v2.6.0)

---
updated-dependencies:
- dependency-name: "@tauri-apps/api"
  dependency-version: 2.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:07:08 +00:00
dependabot[bot]
889abbf080
chore(deps-dev): bump @biomejs/biome from 2.0.0 to 2.0.6 in /vrc-get-gui
---
updated-dependencies:
- dependency-name: "@biomejs/biome"
  dependency-version: 2.0.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:06:44 +00:00
dependabot[bot]
e27c81527b
chore(deps-dev): bump sharp-cli from 5.1.0 to 5.2.0 in /vrc-get-gui
Bumps [sharp-cli](https://github.com/vseventer/sharp-cli) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/vseventer/sharp-cli/releases)
- [Changelog](https://github.com/vseventer/sharp-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/vseventer/sharp-cli/compare/v5.1.0...v5.2.0)

---
updated-dependencies:
- dependency-name: sharp-cli
  dependency-version: 5.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:06:41 +00:00
dependabot[bot]
2afa04625a
chore(deps): bump reqwest from 0.12.20 to 0.12.22
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.12.20 to 0.12.22.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.20...v0.12.22)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-version: 0.12.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:02:21 +00:00
dependabot[bot]
264e7264d2
chore(deps): bump tokio from 1.45.1 to 1.46.1
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.1 to 1.46.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.1...tokio-1.46.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.46.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 19:01:20 +00:00
dependabot[bot]
fed69c51ae
Merge pull request #2366 from vrc-get/dependabot/cargo/plist-1.7.3 2025-07-07 18:47:50 +00:00
dependabot[bot]
be449abcb0
Merge pull request #2364 from vrc-get/dependabot/cargo/serde_with-3.14.0 2025-07-07 18:47:11 +00:00
dependabot[bot]
d36ad4d5f6
Merge pull request #2346 from vrc-get/dependabot/npm_and_yarn/vrc-get-gui/tailwindcss-ee6bf6b019 2025-07-07 18:44:42 +00:00
dependabot[bot]
52bf5045d1
Merge pull request #2344 from vrc-get/dependabot/cargo/indexmap-2.10.0 2025-07-07 18:44:26 +00:00
dependabot[bot]
62d65154ac
Merge pull request #2333 from vrc-get/dependabot/cargo/async-compression-0.4.25 2025-07-07 18:44:06 +00:00
anatawa12
a18ee8d27b
Merge pull request #2376 from vrc-get/template-on-creation
feat: favorite templates and preserve last used template
2025-07-08 03:42:44 +09:00
anatawa12
926549727b
Merge branch 'master' into template-on-creation 2025-07-08 03:36:45 +09:00
anatawa12
990c7a4792
docs(changelog-gui): Favorites and last used for templates 2025-07-08 03:36:20 +09:00
anatawa12
13eb2f2d80
lint: npx biome check --fix 2025-07-08 03:35:44 +09:00
anatawa12
f0d77b3c4d
feat: favorite templates and preserve last used template 2025-07-08 03:31:12 +09:00
dependabot[bot]
6c7e362853
chore(deps): bump plist from 1.7.2 to 1.7.3
Bumps [plist](https://github.com/ebarnard/rust-plist) from 1.7.2 to 1.7.3.
- [Release notes](https://github.com/ebarnard/rust-plist/releases)
- [Changelog](https://github.com/ebarnard/rust-plist/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ebarnard/rust-plist/compare/v1.7.2...v1.7.3)

---
updated-dependencies:
- dependency-name: plist
  dependency-version: 1.7.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 17:17:19 +00:00
anatawa12
f229e4fcfe
Merge pull request #2327 from vrc-get/remove-migrate-if-user-projects-absent
chore: improve behavior for future VCC versions
2025-07-08 02:15:32 +09:00
anatawa12
99416f5530
Merge branch 'master' into remove-migrate-if-user-projects-absent 2025-07-08 02:05:25 +09:00
anatawa12
b2dc61a903
test: add tests for vcc.litedb settings.json migration 2025-07-08 02:04:57 +09:00
anatawa12
44d6669d3c
Merge pull request #2373 from vrc-get/update-sdk-samples
chore: update project settings of templates to include Item layer
2025-07-08 01:06:53 +09:00
anatawa12
19636c3ee0
Merge pull request #2375 from vrc-get/keywords-support
feat: add support for `keywords` UPM manifest property
2025-07-08 01:05:56 +09:00
anatawa12
f717df3e52
test: add utility function to create template directory 2025-07-08 01:04:47 +09:00
anatawa12
bd79f1a3d7
Merge branch 'master' into remove-migrate-if-user-projects-absent 2025-07-08 01:02:36 +09:00
anatawa12
ab9f9a4ae5
docs(changelog-gui): Add support for keywords UPM manifest field 2025-07-08 00:58:26 +09:00
anatawa12
4bcaa4e564
feat: add support for keywords UPM manifest property 2025-07-08 00:57:18 +09:00
anatawa12
3c79f0c4c1
docs(changelog-gui): Updated project settings of templates to include Item layer 2025-07-08 00:48:04 +09:00
anatawa12
bd934ed698
chore: update project settings of templates to include Item layer 2025-07-08 00:45:09 +09:00
anatawa12
97be14fb5c
Merge pull request #2372 from vrc-get/package-install-uncheck
fix: packages are not deselected after installing packages
2025-07-08 00:38:24 +09:00
anatawa12
08309f1e80
Merge pull request #2371 from vrc-get/template-editor
Template Editor improvement with autocomplete
2025-07-08 00:25:39 +09:00
anatawa12
b8412ea607
docs(changelog-gui): Packages are not deselected after installing packages 2025-07-08 00:18:24 +09:00
anatawa12
7f0afbf3af
fix: packages are not deselected after installing packages 2025-07-08 00:17:20 +09:00
anatawa12
63e4ff482b
lint: npx biome check --fix 2025-07-08 00:06:38 +09:00
anatawa12
ff7f8a5dab
docs(changelog-gui): Improved the Template Editor with AutoComplete 2025-07-08 00:05:53 +09:00
anatawa12
c398d70326
chore: allow search by alias in template editor 2025-07-08 00:04:43 +09:00
anatawa12
4e30f45a3b
chore: improve template editor with autocomplete 2025-07-07 23:58:58 +09:00
anatawa12
4133a7550b
chore: improve autocomplete 2025-07-07 23:55:32 +09:00
anatawa12
9c99b7d19e
feat: add autocomplete component 2025-07-07 19:06:47 +09:00
anatawa12
0d97b76156
chore(deps): add command and popover shadcn elements 2025-07-07 18:48:42 +09:00
dependabot[bot]
e0288af16c
chore(deps): bump serde_with from 3.13.0 to 3.14.0
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.13.0 to 3.14.0.
- [Release notes](https://github.com/jonasbb/serde_with/releases)
- [Commits](https://github.com/jonasbb/serde_with/compare/v3.13.0...v3.14.0)

---
updated-dependencies:
- dependency-name: serde_with
  dependency-version: 3.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 08:54:17 +00:00
dependabot[bot]
8b2e029df8
chore(deps): bump vrc-get-litedb from ec44d07 to f4692f8
Bumps [vrc-get-litedb](https://github.com/anatawa12/litedb-rs) from `ec44d07` to `f4692f8`.
- [Release notes](https://github.com/anatawa12/litedb-rs/releases)
- [Commits](ec44d0740a...f4692f8462)

---
updated-dependencies:
- dependency-name: vrc-get-litedb
  dependency-version: f4692f846282413cdc8b22f960867f35b0dff562
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 08:41:21 +00:00
dependabot[bot]
5fb465b9e8
chore(deps-dev): bump @tailwindcss/vite
Bumps the tailwindcss group in /vrc-get-gui with 1 update: [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite).


Updates `@tailwindcss/vite` from 4.1.10 to 4.1.11
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.1.11/packages/@tailwindcss-vite)

---
updated-dependencies:
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.1.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: tailwindcss
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-07 07:49:53 +00:00
anatawa12
b75d4772bf
Merge pull request #2358 from vrc-get/images
ci: enable TAURI_BUNDLER_DMG_IGNORE_CI again
2025-07-02 12:56:44 +09:00
anatawa12
45260b65bb
ci: enable TAURI_BUNDLER_DMG_IGNORE_CI again 2025-07-02 10:27:19 +09:00
dependabot[bot]
4b05207f5c
chore(deps): bump indexmap from 2.9.0 to 2.10.0
Bumps [indexmap](https://github.com/indexmap-rs/indexmap) from 2.9.0 to 2.10.0.
- [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md)
- [Commits](https://github.com/indexmap-rs/indexmap/compare/2.9.0...2.10.0)

---
updated-dependencies:
- dependency-name: indexmap
  dependency-version: 2.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 09:03:42 +00:00
dependabot[bot]
3ea727bc7d
chore(deps): bump async-compression from 0.4.24 to 0.4.25
Bumps [async-compression](https://github.com/Nullus157/async-compression) from 0.4.24 to 0.4.25.
- [Release notes](https://github.com/Nullus157/async-compression/releases)
- [Changelog](https://github.com/Nullus157/async-compression/blob/main/CHANGELOG.md)
- [Commits](https://github.com/Nullus157/async-compression/compare/v0.4.24...v0.4.25)

---
updated-dependencies:
- dependency-name: async-compression
  dependency-version: 0.4.25
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 06:24:40 +00:00
github-actions[bot]
de7941e238 chore: prepare for next version: gui 1.1.3 2025-06-30 06:22:25 +00:00
github-actions[bot]
2f17a3f71e gui v1.1.2 2025-06-30 06:09:50 +00:00
github-actions[bot]
9c7d6e188d gui v1.1.2-rc.0 2025-06-29 07:52:50 +00:00
anatawa12
09425bb82e
Merge pull request #2341 from vrc-get/fix-error-when-package-invisible
fix: frontend error on package list update (especially for package removal from list)
2025-06-29 14:24:47 +09:00
anatawa12
e2918bd233
docs(changelog): Frontend error on package list update 2025-06-29 14:17:42 +09:00
anatawa12
803b7ca0e3
lint: remove unused imports 2025-06-29 14:15:55 +09:00
anatawa12
1577bdff55
Merge branch 'master' into fix-error-when-package-invisible 2025-06-29 14:11:24 +09:00
anatawa12
d190956c0f
Merge pull request #2343 from vrc-get/clippy-1.88
lint: fix new lints in rust 1.88 and 1.89 beta
2025-06-29 13:49:58 +09:00
anatawa12
b0d32afb04
lint: fix new lints in rust 1.88 and 1.89 beta 2025-06-29 04:00:50 +09:00
anatawa12
e2c20bb741
fix: frontend error on package list update (especially for package removal from list) 2025-06-27 17:01:12 +09:00
anatawa12
d02734aab8
Merge pull request #2337 from vrc-get/fix-hyphen-range-serialize
fix: serializing a - b version range may not emit correct format
2025-06-27 16:40:25 +09:00
anatawa12
627f1bb565
docs(changelog): Fixed a - b version range is not correctly serialized on the vpm-manifest.json 2025-06-25 16:43:08 +09:00
anatawa12
942cf708e5
fix: serializing a - b version range may not emit correct format 2025-06-25 16:28:05 +09:00
anatawa12
963ed90aec
Merge pull request #2329 from vrc-get/biome-v2
Biome v2
2025-06-23 16:34:23 +09:00
anatawa12
454dd753f3
lint: apply new biome rules 2025-06-23 14:39:26 +09:00
anatawa12
62d3ad81f1
dev: migrate biome.jsonc to v2 2025-06-23 14:14:31 +09:00
anatawa12
6a7bf4187e
chore(deps): install biome v2 2025-06-23 14:11:46 +09:00
github-actions[bot]
e22519b94a chore: prepare for next version: gui 1.1.2 2025-06-21 17:14:22 +00:00
github-actions[bot]
7d20291448 gui v1.1.1 2025-06-21 17:01:57 +00:00
anatawa12
d00609643c
docs: Improved behavior about settings.json to vcc.litedb migration 2025-06-22 01:56:15 +09:00
anatawa12
22e5ed0eb0
chore: improve behavior for future VCC versions 2025-06-22 01:47:31 +09:00
github-actions[bot]
70000416e0 gui v1.1.1-rc.1 2025-06-21 14:30:09 +00:00
anatawa12
7e4a235dca
Merge pull request #2326 from vrc-get/crash-on-creating-project
Crash on creating project
2025-06-21 23:16:22 +09:00
anatawa12
48699d9a88
docs(changelog): Crash on creating a new project on Windows 2025-06-21 23:09:08 +09:00
anatawa12
1207ad493f
lint: ban 'close' global 2025-06-21 22:59:08 +09:00
anatawa12
3e9f1f2814
fix: crash on creating project on windows platform 2025-06-21 22:54:29 +09:00
267 changed files with 16723 additions and 9744 deletions

2
.cargo/config.toml Normal file
View file

@ -0,0 +1,2 @@
[alias]
xtask = "run --profile xtask --target host-tuple -p xtask --"

2
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,2 @@
github: [anatawa12]
custom: [https://booth.pm/ja/items/6448396]

50
.github/actions/sign-windows/action.yml vendored Normal file
View file

@ -0,0 +1,50 @@
name: 'Sign in place'
description: 'Signs exe in-place'
inputs:
signpath-api-token:
description: SignPath REST API access token.
required: true
signing-policy-slug:
description: SignPath signing policy slug
version:
required: true
description: Version number of artifact we're signing
path:
description: The path of artifact we'll sign
required: true
artifact-name:
description: The name of artifact on github
required: true
runs:
using: "composite"
steps:
- name: upload unsigned artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v4
with:
path: ${{ inputs.path }}
name: ${{ inputs.artifact-name }}
- name: Sign on signpath
id: sign
uses: signpath/github-action-submit-signing-request@v2
with:
api-token: ${{ inputs.signpath-api-token }}
organization-id: 'c2d4dbf9-920f-4318-9017-7306e0fc7590'
project-slug: 'vrc-get'
signing-policy-slug: ${{ inputs.signing-policy-slug }}
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: .github/actions/sign-windows/signed/${{ inputs.artifact-name }}
parameters: |
version: ${{ toJSON(inputs.version) }}
- name: Copy artifact
env:
DOWNLOADED_PATH: .github/actions/sign-windows/signed/${{ inputs.artifact-name }}
REPLACE_TO: ${{ inputs.path }}
shell: bash
run:
cp -f "$DOWNLOADED_PATH/$(basename "$REPLACE_TO")" "$REPLACE_TO"

8
.github/copilot-instructions.md vendored Normal file
View file

@ -0,0 +1,8 @@
If you're writing code:
- Please don't make localization for locales other than en / ja. I cannot review those locales.
- Run cargo clippy for lints and cargo fmt for format before commit.
- After completing the code and commit, please add a changelog entry. Please note that the numbers in the changelog file are pull request numbers, not issue numbers.
- Please add it to the bottom of the change list.
- Please use the proper section for each change. "Fix" should be used only for bug fixes. UX improvements typically belong under "Change", and new features typically under "Add". These are not strict rules, so use them flexibly.
- You should use Conventional Commits (chore:, fix:, dev:, build:, docs:, style:, lint:, and others).
- Please split commits for implementation and changelog updates.

View file

@ -55,9 +55,21 @@ module.exports = async ({github, context}) => {
},
];
/** @type {{missingCount: number, extraCount: number, id: string, discussionNumber: number}[]} */
const localeData = [];
for (const locale of locales) {
await processOneLocale(github, owner, repo, locale.discussionNumber, locale.replyId, locale.id);
const proceed = await processOneLocale(github, owner, repo, locale.discussionNumber, locale.replyId, locale.id);
localeData.push({
id: locale.id,
discussionNumber: locale.discussionNumber,
missingCount: proceed.missingCount,
extraCount: proceed.extraCount,
})
}
// 894 is English Localization and Text Representation
await updateRootLocale(github, owner, repo, 894, localeData);
}
/**
@ -68,9 +80,113 @@ module.exports = async ({github, context}) => {
* @param number {number}
* @param replyToId {string}
* @param localeId {string}
* @return {Promise<void>}
* @return {Promise<{missingCount: number, extraCount: number}>}
*/
async function processOneLocale(github, owner, repo, number, replyToId, localeId) {
const enJson = json5.parse(await fs.readFile(`vrc-get-gui/locales/en.json5`, "utf8"));
const enKeys = normalizeKeys(Object.keys(enJson.translation));
const transJson = json5.parse(await fs.readFile(`vrc-get-gui/locales/${localeId}.json5`, "utf8"));
const transKeys = normalizeKeys(Object.keys(transJson.translation));
const {missingList: missingKeys, extraList: extraKeys} = missingAndExtras(enKeys, transKeys);
const newData = {
missingKeys,
extraKeys,
};
const newAutoPart = `**Missing Keys:**\n${listToMarkdown(missingKeys)}\n\n**Excess Keys:**\n${listToMarkdown(extraKeys)}\n`;
const {discussionId, previousJson: dataJson} = await updateComment(github, owner, repo, number, newAutoPart, newData);
dataJson.missingKeys ??= [];
dataJson.extraKeys ??= [];
// create comment if there are new missing / extra keys
const {extraList: newlyAddedMissingKeys} = missingAndExtras(normalizeKeys(dataJson.missingKeys), missingKeys);
const {extraList: newlyAddedExtraKeys} = missingAndExtras(normalizeKeys(dataJson.extraKeys), extraKeys);
if (newlyAddedMissingKeys.length > 0 || newlyAddedExtraKeys.length > 0) {
const text = `
There are new missing / excess keys in the translation. Please update the translation!
**New Missing Keys:**
${listToMarkdown(newlyAddedMissingKeys)}
**New Excess Keys:**
${listToMarkdown(newlyAddedExtraKeys)}
`
await github.graphql(`
mutation($discussionId: ID!, $replyToId: ID!, $body: String!) {
addDiscussionComment(input: {discussionId: $discussionId, replyToId: $replyToId, body: $body}) {
comment {
body
}
}
}
`, {discussionId, replyToId, body: text});
}
return {
missingCount: missingKeys.length,
extraCount: extraKeys.length,
}
}
/**
* Updates the root locale configuration for a specified repository.
*
* @param {import('@octokit/rest').Octokit} github - The GitHub API client instance used to interact with the GitHub API.
* @param {string} owner - The owner of the repository where the root locale is to be updated.
* @param {string} repo - The name of the repository where the root locale is to be updated.
* @param {number} number
* @param {{missingCount: number, extraCount: number, id: string, discussionNumber: number}[]} localeData - The locale data object containing the updated root locale configuration.
* @return {Promise<void>} A promise that resolves to the API response for the update operation.
*/
async function updateRootLocale(github, owner, repo, number, localeData) {
let table = "| locale | missing count | exceeding count | link |\n" +
"| -- | -- | -- | -- |\n"
for (let {missingCount, extraCount, id, discussionNumber} of localeData) {
table += `| ${id} | ${missingCount} | ${extraCount} | [link](https://github.com/${owner}/${repo}/discussions/${discussionNumber}) |\n`;
}
await updateComment(github, owner, repo, number, table, {});
}
/**
* @template T
* @param beforeList {T[]}
* @param afterList {T[]}
* @return {{missingList: T[], extraList: T[]}}
*/
function missingAndExtras(beforeList, afterList) {
const missingList = beforeList.filter(key => !afterList.includes(key)).filter(key => !optionalKeys.includes(key));
const extraList = afterList.filter(key => !beforeList.includes(key)).filter(key => !optionalKeys.includes(key));
return {missingList, extraList};
}
function listToMarkdown(values) {
return values.length === 0 ? 'nothing' : values.map(key => `- \`${key}\``).join('\n')
}
/**
*
* @param github {import('@octokit/rest').Octokit}
* @param owner {string}
* @param repo {string}
* @param number {number}
* @param content {string} the updated content
* @param newData {object} data stored in the comment
* @return {Promise<{previousJson: object, discussionId:string}>}
*/
async function updateComment(
github,
owner, repo, number,
content,
newData,
) {
/** @type {{data: {repository: {discussion: {body: string}}}}} */
const result = await github.graphql(`
query($owner: String!, $repo: String!, $number: Int!) {
@ -98,42 +214,14 @@ async function processOneLocale(github, owner, repo, number, replyToId, localeId
const postAutoPart = split1[1] ?? '';
const dataJsonLine = autoPart.split(/\r?\n/).find(l => l.startsWith(dataJsonLinePrefix));
// the dataJson is for computing the difference and create new comment if there are changes
const dataJson = dataJsonLine ? JSON.parse(dataJsonLine.slice(dataJsonLinePrefix.length)) : {};
dataJson.missingKeys ??= [];
dataJson.extraKeys ??= [];
const enJson = json5.parse(await fs.readFile(`vrc-get-gui/locales/en.json5`, "utf8"));
const enKeys = normalizeKeys(Object.keys(enJson.translation));
const transJson = json5.parse(await fs.readFile(`vrc-get-gui/locales/${localeId}.json5`, "utf8"));
const transKeys = normalizeKeys(Object.keys(transJson.translation));
const missingKeys = enKeys.filter(key => !transKeys.includes(key)).filter(key => !optionalKeys.includes(key));
const extraKeys = transKeys.filter(key => !enKeys.includes(key)).filter(key => !optionalKeys.includes(key));
const missingKeysStr = missingKeys.length === 0 ? 'nothing' : missingKeys.map(key => `- \`${key}\``).join('\n');
const excessKeysStr = extraKeys.length === 0 ? 'nothing' : extraKeys.map(key => `- \`${key}\``).join('\n');
const newData = {
missingKeys,
extraKeys,
};
const newAutoPart = `
**Missing Keys:**
${missingKeysStr}
**Excess Keys:**
${excessKeysStr}
const previousJson = dataJsonLine ? JSON.parse(dataJsonLine.slice(dataJsonLinePrefix.length)) : {};
const newBody = `${manualPart}${autoPartStart}
${content}
<!-- data part
${dataJsonLinePrefix}${JSON.stringify(newData)}
-->
`;
const newBody = `${manualPart}${autoPartStart}${newAutoPart}${autoPartEnd}${postAutoPart}`;
${autoPartEnd}${postAutoPart}`;
await github.graphql(`
mutation($discussionId: ID!, $body: String!) {
@ -145,36 +233,9 @@ ${dataJsonLinePrefix}${JSON.stringify(newData)}
}
`, {discussionId, body: newBody});
// create comment if there are new missing / extra keys
const oldMissingKeys = new Set(normalizeKeys(dataJson.missingKeys));
const oldExtraKeys = new Set(normalizeKeys(dataJson.extraKeys));
const newlyAddedMissingKeys = missingKeys.filter(key => !oldMissingKeys.has(key));
const newlyAddedExtraKeys = extraKeys.filter(key => !oldExtraKeys.has(key));
if (newlyAddedMissingKeys.length > 0 || newlyAddedExtraKeys.length > 0) {
const newMissingKeysStr = newlyAddedMissingKeys.length === 0 ? 'nothing' : newlyAddedMissingKeys.map(key => `- \`${key}\``).join('\n');
const newExcessKeysStr = newlyAddedExtraKeys.length === 0 ? 'nothing' : newlyAddedExtraKeys.map(key => `- \`${key}\``).join('\n');
const text = `
There are new missing / excess keys in the translation. Please update the translation!
**New Missing Keys:**
${newMissingKeysStr}
**New Excess Keys:**
${newExcessKeysStr}
`
await github.graphql(`
mutation($discussionId: ID!, $replyToId: ID!, $body: String!) {
addDiscussionComment(input: {discussionId: $discussionId, replyToId: $replyToId, body: $body}) {
comment {
body
}
}
}
`, {discussionId, replyToId, body: text});
return {
previousJson,
discussionId,
}
}

View file

@ -4,12 +4,9 @@ on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
CARGO_TERM_COLOR: always
# workaround of https://github.com/tauri-apps/tauri-action/issues/1091
TAURI_BUNDLER_DMG_IGNORE_CI: false
jobs:
build-gui:
@ -19,6 +16,7 @@ jobs:
include:
- triple: x86_64-unknown-linux-gnu
on: ubuntu-22.04
bundles: appimage,appimage-updater
setup: |
sudo apt update && sudo apt install -y lld
ld.lld --version
@ -28,12 +26,14 @@ jobs:
- triple: x86_64-pc-windows-msvc
on: windows-latest
bundles: setup-exe,setup-exe-zip,exe-updater
- triple: universal-apple-darwin
on: macos-14
setup: |
rustup target add aarch64-apple-darwin
rustup target add x86_64-apple-darwin
bundles: app,dmg,app-updater
triple:
- x86_64-unknown-linux-gnu
#- aarch64-unknown-linux-gnu
@ -46,7 +46,22 @@ jobs:
RUSTFLAGS: ${{ matrix.rustflags }}
steps:
- uses: actions/checkout@v4
- uses: samypr100/setup-dev-drive@v4
with:
drive-size: 12GB # github actions grantees 14 GB of disk space. we have few GB for action environment
drive-path: "/dev_drive.vhdx"
mount-path: ${{ github.workspace }}
trusted-dev-drive: true
- name: Preinitialize git repository
shell: bash
run: |
# hopefully for non-cleaning environments, actions/checkout will tries to clean existing repository
# if existing dir is not git repository nor for specified repository.
# this step creates git directory to workaround the behavior
git init
git remote add origin "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY"
- uses: actions/checkout@v6
with:
submodules: recursive
- run: rustup update stable
@ -59,7 +74,7 @@ jobs:
with:
key: ci-build-gui-${{ matrix.triple }}
- name: Cache javascript essentials
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.npm
@ -87,20 +102,16 @@ jobs:
cp vrc-get-gui/Tauri.toml vrc-get-gui/Tauri.toml.bak
grep -v "remove if ci" < vrc-get-gui/Tauri.toml.bak > vrc-get-gui/Tauri.toml
- name: Enable Devtools Feature
shell: bash
run: |
cargo add --package vrc-get-gui tauri --features devtools
- name: Build ALCOM binary
run:
cargo xtask build-alcom --release --target ${{ matrix.triple }} --devtools ${{ (secrets.ACTIONS_STEP_DEBUG || vars.ACTIONS_STEP_DEBUG) == 'true' && '--verbose' || '' }}
- uses: tauri-apps/tauri-action@v0
with:
projectPath: vrc-get-gui
tauriScript: npm run tauri
args: |
--target ${{ matrix.triple }} -c '{"version":"${{ steps.version.outputs.version }}", "bundle":{"windows":{"certificateThumbprint": null}}}' ${{ (secrets.ACTIONS_STEP_DEBUG || vars.ACTIONS_STEP_DEBUG) == 'true' && '--verbose' || '' }}
- name: Build installer
shell: bash
run: cargo xtask bundle-alcom --release --target ${{ matrix.triple }} --bundles ${{ matrix.bundles }}
- name: Upload built binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.triple }}
path: |
@ -111,6 +122,195 @@ jobs:
target/${{ matrix.triple }}/release/bundle/*/ALCOM*
target/${{ matrix.triple }}/release/bundle/*/alcom*
build-rpm:
strategy:
fail-fast: false
matrix:
include:
- install_rust: false
- no_dist: false
- mock-env: fedora-40-x86_64
install_rust: true
no_dist: true
mock-env:
- fedora-40-x86_64
- fedora-rawhide-x86_64
runs-on: ubuntu-latest
container:
image: 'fedora:latest'
options: --privileged
env:
MOCK_ENV: ${{ matrix.mock-env }}
RPMBUILD_OPTS: ${{ case(matrix.no_dist, '-D "dist %{nil}"', '') }} ${{ case(matrix.install_rust, '-D "install_rust 1"', '') }}
steps:
- name: Install CI dependencies
run: dnf install -y git tar curl
- uses: actions/checkout@v6
with:
submodules: recursive
# https://github.com/actions/checkout/issues/1169
- run: git config --system --add safe.directory $GITHUB_WORKSPACE
- name: install dependencies
run: dnf install -y mock rpmbuild
- name: prepare rpm build environment
run: mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
- name: update version name in spec file
run: |
COMMIT_HASH="$(git rev-parse HEAD)"
SHORT_HASH="$(git rev-parse --short HEAD)"
PKG_VERSION="$(<vrc-get-gui/Cargo.toml sed -En -e '/^version/{s/.*"(.*)".*/\1/p;}')+${SHORT_HASH}"
echo "PKG_VERSION=$PKG_VERSION" >> $GITHUB_ENV
cp vrc-get-gui/Cargo.toml vrc-get-gui/Cargo.toml.bak
sed -E "/^version/s/\"$/+$(git rev-parse --short HEAD)\"/" < vrc-get-gui/Cargo.toml.bak > vrc-get-gui/Cargo.toml
rm vrc-get-gui/Cargo.toml.bak
git add vrc-get-gui/Cargo.toml
sed -i vrc-get-gui/bundle/alcom.spec -e "/^Version:/c\Version: ${PKG_VERSION//-/\~}"
- name: build source rpm package
run: |
git archive --format=tar --prefix=vrc-get-gui-v$PKG_VERSION/ $(git write-tree) | gzip > ~/rpmbuild/SOURCES/gui-v$PKG_VERSION.tar.gz
eval "rpmbuild -bs vrc-get-gui/bundle/alcom.spec $RPMBUILD_OPTS"
- name: build rpm package
run: eval "mock -v -r '$(ls -1 /etc/mock{/eol,}/$MOCK_ENV.cfg 2>/dev/null)' --enable-network $RPMBUILD_OPTS rebuild ~/rpmbuild/SRPMS/alcom-${PKG_VERSION//-/\~}-1*.src.rpm"
- name: copy built binaries
run: |
mkdir -p artifacts
cp ~/rpmbuild/SRPMS/alcom-${PKG_VERSION//-/\~}-1*.src.rpm artifacts/
cp /var/lib/mock/$MOCK_ENV/result/alcom-${PKG_VERSION//-/\~}-1*.${MOCK_ENV##*-}.rpm artifacts/
- name: Upload built binary
uses: actions/upload-artifact@v7
with:
name: rpm-${{ matrix.mock-env }}
path: artifacts/*
build-deb:
strategy:
fail-fast: false
matrix:
include:
- install_rust: false
- install_nodejs: false
- apt-components: main
- apt-with-updates: false
# Old distributions have older tools than we need. Download tools in build process
- pbuilder-distribution: bookworm
install_rust: true
install_nodejs: true
- pbuilder-distribution: jammy
install_rust: true
install_nodejs: true
# Debian uses mirror from debian-archive.trafficmanager.net which is managed by microsoft on azure
- pbuilder-distribution: bookworm
mirror: http://debian-archive.trafficmanager.net/debian/
keyring: /usr/share/keyrings/debian-archive-keyring.gpg
- pbuilder-distribution: sid
mirror: http://debian-archive.trafficmanager.net/debian/
keyring: /usr/share/keyrings/debian-archive-keyring.gpg
# Ubuntu legacy release
- pbuilder-distribution: jammy
mirror: http://archive.ubuntu.com/ubuntu/
apt-components: main universe
apt-with-updates: true
keyring: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# For note,
# bookworm: libc6@2.36
# sid: libc6@2.39 as of 2026/06/14
# jammy: libc6@2.35
pbuilder-distribution:
# debian distribution
- bookworm
- sid
# ubuntu distribution
- jammy # jammy is the oldest ubuntu release with libwebkit2gtk-4.1 >= 2.41 (but requires -updates and universe)
target-arch:
- amd64
runs-on: ubuntu-latest
env:
TARGET_ARCH: ${{ matrix.target-arch }}
PBUILDER_DISTRIBUTION: ${{ matrix.pbuilder-distribution }}
PBUILDER_MIRROR: ${{ matrix.mirror }}
PBUILDER_KEYRING: ${{ matrix.keyring }}
PBUILDER_COMPONENTS: ${{ matrix.apt-components }}
PBUILDER_OTHERMIRROR: ${{ case(matrix.apt-with-updates, format('deb {0} {1}-updates {2}', matrix.mirror, matrix.pbuilder-distribution, matrix.apt-components), '') }}
INSTALL_RUST: ${{ case(matrix.install_rust, '1', '0') }}
INSTALL_NODEJS: ${{ case(matrix.install_nodejs, '1', '0') }}
steps:
- uses: actions/checkout@v6
with:
path: vrc-get
submodules: recursive
- name: install dependencies
run: sudo apt update && sudo apt install -y pbuilder debian-archive-keyring debhelper-compat=13
- name: prepare deb build environment
working-directory: vrc-get
run: |
cp -r vrc-get-gui/bundle/debian debian
sudo pbuilder create \
--architecture "$TARGET_ARCH" \
--keyring "$PBUILDER_KEYRING" \
--mirror "$PBUILDER_MIRROR" \
--distribution "$PBUILDER_DISTRIBUTION" \
--components "$PBUILDER_COMPONENTS" \
--othermirror "$PBUILDER_OTHERMIRROR"
- name: update changelog
working-directory: vrc-get
run: |
COMMIT_HASH="$(git rev-parse HEAD)"
SHORT_HASH="$(git rev-parse --short HEAD)"
PKG_VERSION="$(<vrc-get-gui/Cargo.toml sed -En -e '/^version/{s/.*"(.*)".*/\1/p;}')+${SHORT_HASH}"
echo "PKG_VERSION=$PKG_VERSION" >> $GITHUB_ENV
cp debian/changelog debian/changelog.bak
cat - debian/changelog.bak <<CHANGELOG > debian/changelog
alcom (${PKG_VERSION//-/\~}-1) experimental;
* Upgraded version to ${PKG_VERSION}
-- anatawa12 <i@anatawa12.com> $(date -u +"%a, %d %b %Y %H:%M:%S +0000")
CHANGELOG
rm debian/changelog.bak
cp vrc-get-gui/Cargo.toml vrc-get-gui/Cargo.toml.bak
sed -E "/^version/s/\"$/+$(git rev-parse --short HEAD)\"/" < vrc-get-gui/Cargo.toml.bak > vrc-get-gui/Cargo.toml
rm vrc-get-gui/Cargo.toml.bak
git add vrc-get-gui/Cargo.toml
echo cat debian/changelog
cat debian/changelog
dpkg-parsechangelog
- name: build source deb package
working-directory: vrc-get
run: |
git archive --format=tar $(git write-tree) | xz > ../alcom_${PKG_VERSION//-/\~}.orig.tar.xz
dpkg-buildpackage -d -S
- name: build deb package
working-directory: vrc-get
run: |
sudo --preserve-env=INSTALL_RUST,INSTALL_NODEJS pbuilder build --use-network yes ../alcom_${PKG_VERSION//-/\~}-1.dsc
- name: copy built binaries
run: |
mkdir -p artifacts
cp vrc-get/debian/changelog artifacts/
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}* artifacts/
ls artifacts
- name: Print information about built package
run: dpkg-deb -I artifacts/alcom_${PKG_VERSION//-/\~}-1_$TARGET_ARCH.deb
- name: Upload built binary
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
with:
name: deb-${{ matrix.pbuilder-distribution }}-${{ matrix.target-arch }}
path: artifacts/*
conclude-gui:
runs-on: ubuntu-latest
if: ${{ always() }}

View file

@ -4,7 +4,6 @@ on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
CARGO_TERM_COLOR: always
@ -72,11 +71,9 @@ jobs:
runs-on: ${{ matrix.on }}
env:
RUSTFLAGS: ${{ matrix.rustflags }}
# workaround of https://github.com/tauri-apps/tauri-action/issues/1091
TAURI_BUNDLER_DMG_IGNORE_CI: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: dtolnay/rust-toolchain@stable
@ -102,7 +99,7 @@ jobs:
- name: Build
run: cargo build --verbose --target ${{ matrix.triple }}
- name: Upload built binary
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.triple }}
path: |
@ -116,10 +113,10 @@ jobs:
- name: Check binary is statically linked
shell: bash
if: ${{ matrix.static-linked }}
env:
RUSTFLAGS: ''
run: |
# https://github.com/taiki-e/setup-cross-toolchain-action/issues/18
unset CARGO_BUILD_TARGET
cargo run -p build-check-static-link target/${{ matrix.triple }}/debug/vrc-get*
cargo xtask check-static-link target/${{ matrix.triple }}/debug/vrc-get${WINDIR:+.exe}
conclude:
runs-on: ubuntu-latest

View file

@ -9,11 +9,11 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/create-github-app-token@v2
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/labeler@v5
- uses: actions/labeler@v6
with:
repo-token: ${{ steps.app-token.outputs.token }}

View file

@ -17,7 +17,7 @@ jobs:
fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- run: cargo fmt --all -- --check
@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: recursive
@ -40,7 +40,7 @@ jobs:
run:
sudo apt update && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
- uses: actions/cache@v4
- uses: actions/cache@v5
with:
path: |
~/.cargo/bin/
@ -50,10 +50,10 @@ jobs:
target/
key: lints-${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- uses: auguwu/clippy-action@1.4.0
- uses: auguwu/clippy-action@1.5.0
with:
token: ${{secrets.GITHUB_TOKEN}}
check-args: --all --all-targets --all-features
check-args: --all --all-targets --all-features --exclude windows-installer-wrapper
args: -Dclippy::todo -Dwarnings
biome:
@ -63,7 +63,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: run Biome
working-directory: vrc-get-gui
run: npm run biome -- ci
@ -75,7 +75,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: run Type Check
working-directory: vrc-get-gui
run: npm ci && npx tsc

View file

@ -12,13 +12,13 @@ jobs:
contents: read
discussions: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: '20.x'
- run: npm i --omit=dev
working-directory: .github/scripts
- uses: actions/github-script@v7
- uses: actions/github-script@v9
with:
script: |
const script = require('./.github/scripts/localization-updates.js')

View file

@ -18,6 +18,9 @@ on:
default: true
required: false
concurrency:
group: releasing
jobs:
pre-build:
name: Update version name
@ -28,7 +31,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: anatawa12/something-releaser@v3
@ -64,6 +67,21 @@ jobs:
;;
esac
GUI_VERSION="$(get-version -t gui)"
# update debian package
cp vrc-get-gui/bundle/debian/changelog vrc-get-gui/bundle/debian/changelog.bak
cat - vrc-get-gui/bundle/debian/changelog.bak <<CHANGELOG > vrc-get-gui/bundle/debian/changelog
alcom (${GUI_VERSION//-/\~}-1) stable;
* Upgraded version to ${GUI_VERSION}
-- anatawa12 <i@anatawa12.com> $(date -u +"%a, %d %b %Y %H:%M:%S +0000")
CHANGELOG
rm vrc-get-gui/bundle/debian/changelog.bak
# update rpm package
sed -i vrc-get-gui/bundle/alcom.spec -e "/^Version:/c\Version: ${GUI_VERSION//-/\~}"
case "$GITHUB_REF_NAME" in
master | master-* )
echo "head is master or master-*"
@ -78,7 +96,7 @@ jobs:
;;
esac
gh-export-variable GUI_VERSION "$(get-version -t gui)"
gh-export-variable GUI_VERSION "${GUI_VERSION}"
env:
RELEASE_KIND_IN: ${{ inputs.release_kind }}
DRY_RUN: ${{ inputs.dry-run }}
@ -99,14 +117,14 @@ jobs:
Version ${{ env.GUI_VERSION }}
---
- name: Upload CHANGELOG.md
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: CHANGELOG
path: CHANGELOG.md
- name: copy release note
run: cp "${{ steps.changelog.outputs.release-note }}" release-note.md
- name: Upload release note
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: release-note-for-release
path: release-note.md
@ -122,24 +140,6 @@ jobs:
git branch releasing
git push -f -u origin releasing
build-web:
name: Build gui web
runs-on: ubuntu-latest
needs: [ pre-build ]
steps:
- uses: actions/checkout@v4
with:
ref: 'releasing'
submodules: recursive
- run: npm run build
working-directory: vrc-get-gui
- uses: actions/upload-artifact@v4
with:
name: vrc-get-gui-web
path: vrc-get-gui/out
build-rust:
name: Build rust
environment:
@ -150,7 +150,8 @@ jobs:
include:
# note: when you changed paths for tauri updater (which are files with .sig),
# remember keep in sync with build-updater-json
- triple: x86_64-unknown-linux-gnu
- name: x86_64-linux-appimage
triple: x86_64-unknown-linux-gnu
on: ubuntu-22.04
setup: |
sudo apt update && sudo apt install -y lld
@ -158,51 +159,54 @@ jobs:
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
rustflags: "-C link-arg=-fuse-ld=lld"
last-bundles: appimage,appimage-updater
updater-bundle: bundle/appimage/ALCOM_${GUI_VERSION}_x86_64.AppImage.tar.gz
dist-path: |
bundle/appimage/ALCOM_${GUI_VERSION}_amd64.AppImage:alcom-${GUI_VERSION}-x86_64.AppImage
bundle/appimage/ALCOM_${GUI_VERSION}_x86_64.AppImage:alcom-${GUI_VERSION}-x86_64.AppImage
bundle/appimage/ALCOM_${GUI_VERSION}_amd64.AppImage.tar.gz:alcom-${GUI_VERSION}-x86_64.AppImage.tar.gz
bundle/appimage/ALCOM_${GUI_VERSION}_amd64.AppImage.tar.gz.sig:alcom-${GUI_VERSION}-x86_64.AppImage.tar.gz.sig
bundle/appimage/ALCOM_${GUI_VERSION}_x86_64.AppImage.tar.gz:alcom-${GUI_VERSION}-x86_64.AppImage.tar.gz
bundle/appimage/ALCOM_${GUI_VERSION}_x86_64.AppImage.tar.gz.sig:alcom-${GUI_VERSION}-x86_64.AppImage.tar.gz.sig
bundle/deb/ALCOM_${GUI_VERSION}_amd64.deb:alcom_${GUI_VERSION}_amd64.deb
bundle/rpm/ALCOM-${GUI_VERSION}-1.x86_64.rpm:alcom-${GUI_VERSION}-1.x86_64.rpm
- triple: x86_64-pc-windows-msvc
on: windows-latest
esigner: true
- name: x86_64-windows-all
triple: x86_64-pc-windows-msvc
on: windows-2022
last-bundles: setup-exe-zip,exe-updater
updater-bundle: bundle/setup/alcom-updater.exe
dist-path: |
ALCOM.exe:ALCOM-${GUI_VERSION}-x86_64.exe
bundle/nsis/ALCOM_${GUI_VERSION}_x64-setup.exe:ALCOM-${GUI_VERSION}-x86_64-setup.exe
bundle/nsis/ALCOM_${GUI_VERSION}_x64-setup.nsis.zip:ALCOM-${GUI_VERSION}-x86_64-setup.nsis.zip
bundle/nsis/ALCOM_${GUI_VERSION}_x64-setup.nsis.zip.sig:ALCOM-${GUI_VERSION}-x86_64-setup.nsis.zip.sig
bundle/setup/alcom-setup.exe:ALCOM-${GUI_VERSION}-x86_64-setup.exe
bundle/setup/alcom-setup.exe.zip:ALCOM-${GUI_VERSION}-x86_64-setup.exe.zip
bundle/setup/alcom-updater.exe:ALCOM-${GUI_VERSION}-x86_64-updater.exe
bundle/setup/alcom-updater.exe.sig:ALCOM-${GUI_VERSION}-x86_64-updater.exe.sig
- triple: universal-apple-darwin
- name: universal-macos-all
triple: universal-apple-darwin
on: macos-14
setup: |
rustup target add aarch64-apple-darwin
rustup target add x86_64-apple-darwin
last-bundles: dmg,app-updater
updater-bundle: bundle/macos/ALCOM.app.tar.gz
dist-path: |
bundle/dmg/ALCOM_${GUI_VERSION}_universal.dmg:ALCOM-${GUI_VERSION}-universal.dmg
bundle/macos/ALCOM.app.tar.gz:ALCOM-${GUI_VERSION}-universal.app.tar.gz
bundle/macos/ALCOM.app.tar.gz.sig:ALCOM-${GUI_VERSION}-universal.app.tar.gz.sig
triple:
- x86_64-unknown-linux-gnu
name:
- x86_64-linux-appimage
#- aarch64-unknown-linux-musl
- x86_64-pc-windows-msvc
#- aarch64-pc-windows-msvc
- universal-apple-darwin
- x86_64-windows-all
#- aarch64-windows-all
- universal-macos-all
runs-on: ${{ matrix.on }}
env:
RUSTFLAGS: ${{ matrix.rustflags }}
# workaround of https://github.com/tauri-apps/tauri-action/issues/1091
TAURI_BUNDLER_DMG_IGNORE_CI: false
needs: [ pre-build, build-web ]
needs: [ pre-build ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
submodules: recursive
@ -220,45 +224,68 @@ jobs:
- name: Setup
run: ${{ matrix.setup }}
- uses: anatawa12/setup-eSigner-CKA@v1
if: ${{ matrix.esigner }}
with:
mode: ${{ vars.WIN_ESIGNER_MODE }}
username: ${{ secrets.WIN_ESIGNER_USERNAME }}
password: ${{ secrets.WIN_ESIGNER_PASSWORD }}
totp-secret: ${{ secrets.WIN_ESIGNER_TOTP_SECRET }}
- name: Build ALCOM binary
run: |
cargo xtask build-alcom --target ${{ matrix.triple }} --release ${{ matrix.alcom-build-options }}
- name: Download Web Artifact
uses: actions/download-artifact@v4
with:
name: vrc-get-gui-web
path: vrc-get-gui/out
- name: pre-sign Bundle ALCOM app (macOS)
if: ${{ contains(matrix.name, 'macos') }}
run: cargo xtask bundle-alcom --target ${{ matrix.triple }} --release --bundles app
- uses: tauri-apps/tauri-action@v0
- name: Sign ALCOM app (macOS)
if: ${{ contains(matrix.name, 'macos') }}
env:
# apple code signing
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: cargo xtask sign-alcom-app --target ${{ matrix.triple }}
# tauri updater signing
- name: Sign ALCOM exe (Windows)
if: ${{ contains(matrix.name, 'windows') }}
uses: ./.github/actions/sign-windows
with:
artifact-name: alcom-exe-unsigned
path: target/${{ matrix.triple }}/release/ALCOM.exe
signpath-api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
signing-policy-slug: ${{ case(inputs.dry-run, 'test-signing', 'release-signing') }}
version: ${{ needs.pre-build.outputs.gui-version }}
- name: Bundle Setup exe (Windows)
if: ${{ contains(matrix.name, 'windows') }}
run: cargo xtask bundle-alcom --target ${{ matrix.triple }} --release --bundles setup-exe
- name: Sign Setup exe (Windows)
if: ${{ contains(matrix.name, 'windows') }}
uses: ./.github/actions/sign-windows
with:
artifact-name: alcom-setup-exe-unsigned
path: target/${{ matrix.triple }}/release/bundle/setup/alcom-setup.exe
signpath-api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
signing-policy-slug: ${{ case(inputs.dry-run, 'test-signing', 'release-signing') }}
version: ${{ needs.pre-build.outputs.gui-version }}
- name: Bundle ALCOM (${{ matrix.last-bundles }})
run: cargo xtask bundle-alcom --target ${{ matrix.triple }} --release --bundles ${{ matrix.last-bundles }}
- name: Sign updater artifacts (All Platforms)
shell: bash
if: ${{ matrix.updater-bundle }}
env:
GUI_VERSION: ${{ needs.pre-build.outputs.gui-version }}
UPDATER_BUNDLE: ${{ matrix.updater-bundle }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
# we have to use x86 version of signtool since eSignerCKA does not work with x64 version
TAURI_WINDOWS_SIGNTOOL_PATH: C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe
with:
projectPath: vrc-get-gui
tauriScript: npm run tauri
# disable beforeBuildCommand since we already build web
args: |
--target ${{ matrix.triple }} -c '{"build":{"beforeBuildCommand":null}}'
run: |
UPDATER_BUNDLE="${UPDATER_BUNDLE//\$\{GUI_VERSION\}/$GUI_VERSION}"
cargo xtask sign-alcom-updater "target/${{ matrix.triple }}/release/${UPDATER_BUNDLE}"
- name: Move artifacts
if: ${{ !cancelled() }}
shell: bash
env:
GUI_VERSION: ${{ needs.pre-build.outputs.gui-version }}
@ -276,9 +303,153 @@ jobs:
mv "target/${{ matrix.triple }}/release/$src" "artifacts/$dst"
done
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: artifacts-${{ matrix.triple }}
name: artifacts-${{ matrix.name }}
path: artifacts/*
build-rpm:
needs: [ pre-build ]
strategy:
fail-fast: false
matrix:
include:
- install_rust: false
- no_dist: false
- mock-env: fedora-40-x86_64
install_rust: true
no_dist: true
mock-env:
- fedora-40-x86_64
runs-on: ubuntu-latest
container:
image: 'fedora:latest'
options: --privileged
env:
MOCK_ENV: ${{ matrix.mock-env }}
RPMBUILD_OPTS: ${{ case(matrix.no_dist, '-D "dist %{nil}"', '') }} ${{ case(matrix.install_rust, '-D "install_rust 1"', '') }}
PKG_VERSION: ${{ needs.pre-build.outputs.gui-version }}
steps:
- name: Install CI dependencies
run: dnf install -y git tar curl
- uses: actions/checkout@v6
with:
ref: 'releasing'
submodules: recursive
# https://github.com/actions/checkout/issues/1169
- run: git config --system --add safe.directory $GITHUB_WORKSPACE
- name: install dependencies
run: dnf install -y mock rpmbuild
- name: prepare rpm build environment
run: mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
- name: build source rpm package
run: |
git archive --format=tar --prefix=vrc-get-gui-v$PKG_VERSION/ $(git write-tree) | gzip > ~/rpmbuild/SOURCES/gui-v$PKG_VERSION.tar.gz
eval "rpmbuild -bs vrc-get-gui/bundle/alcom.spec $RPMBUILD_OPTS"
- name: build rpm package
run: eval "mock -v -r '$(ls -1 /etc/mock{/eol,}/$MOCK_ENV.cfg 2>/dev/null)' --enable-network $RPMBUILD_OPTS rebuild ~/rpmbuild/SRPMS/alcom-${PKG_VERSION//-/\~}-1*.src.rpm"
- name: copy built binaries
run: |
mkdir -p artifacts
cp ~/rpmbuild/SRPMS/alcom-${PKG_VERSION//-/\~}-1*.src.rpm artifacts/
cp /var/lib/mock/$MOCK_ENV/result/alcom-${PKG_VERSION//-/\~}-1*.${MOCK_ENV##*-}.rpm artifacts/
- name: Upload built binary
uses: actions/upload-artifact@v7
with:
name: artifacts-rpm-${{ matrix.mock-env }}
path: artifacts/*
build-deb:
needs: [ pre-build ]
strategy:
fail-fast: false
matrix:
include:
- install_rust: false
- install_nodejs: false
- apt-components: main
- apt-with-updates: false
# Old distributions have older tools than we need. Download tools in build process
- pbuilder-distribution: jammy
install_rust: true
install_nodejs: true
# Debian uses mirror from debian-archive.trafficmanager.net which is managed by microsoft on azure
- pbuilder-distribution: jammy
mirror: http://archive.ubuntu.com/ubuntu/
apt-components: main universe
apt-with-updates: true
keyring: /usr/share/keyrings/ubuntu-archive-keyring.gpg
# We build on jammy since it's the distribution with a) libwebkit2gtk-4.1 >= 2.41 and 2) oldest libc version required.
# bookworm: libc6@2.36
# sid: libc6@2.39 as of 2026/06/14
# jammy: libc6@2.35
pbuilder-distribution:
- jammy # jammy is the oldest ubuntu release with libwebkit2gtk-4.1 >= 2.41 (but requires -updates and universe)
target-arch:
- amd64
runs-on: ubuntu-latest
env:
TARGET_ARCH: ${{ matrix.target-arch }}
PBUILDER_DISTRIBUTION: ${{ matrix.pbuilder-distribution }}
PBUILDER_MIRROR: ${{ matrix.mirror }}
PBUILDER_KEYRING: ${{ matrix.keyring }}
PBUILDER_COMPONENTS: ${{ matrix.apt-components }}
PBUILDER_OTHERMIRROR: ${{ case(matrix.apt-with-updates, format('deb {0} {1}-updates {2}', matrix.mirror, matrix.pbuilder-distribution, matrix.apt-components), '') }}
INSTALL_RUST: ${{ case(matrix.install_rust, '1', '0') }}
INSTALL_NODEJS: ${{ case(matrix.install_nodejs, '1', '0') }}
PKG_VERSION: ${{ needs.pre-build.outputs.gui-version }}
steps:
- uses: actions/checkout@v6
with:
ref: 'releasing'
path: vrc-get
submodules: recursive
- name: install dependencies
run: sudo apt update && sudo apt install -y pbuilder debian-archive-keyring debhelper-compat=13
- name: prepare deb build environment
working-directory: vrc-get
run: |
( mkdir debian && cd debian && ln -s ../vrc-get-gui/bundle/debian/* . )
sudo pbuilder create \
--architecture "$TARGET_ARCH" \
--keyring "$PBUILDER_KEYRING" \
--mirror "$PBUILDER_MIRROR" \
--distribution "$PBUILDER_DISTRIBUTION" \
--components "$PBUILDER_COMPONENTS" \
--othermirror "$PBUILDER_OTHERMIRROR"
- name: build source deb package
working-directory: vrc-get
run: |
git archive --format=tar HEAD | xz > ../alcom_${PKG_VERSION//-/\~}.orig.tar.xz
dpkg-buildpackage -d -S
- name: build deb package
working-directory: vrc-get
run: |
sudo --preserve-env=INSTALL_RUST,INSTALL_NODEJS pbuilder build --use-network yes ../alcom_${PKG_VERSION//-/\~}-1.dsc
- name: copy built binaries
run: |
mkdir -p artifacts
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}-1_$TARGET_ARCH.deb artifacts/
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}-1_$TARGET_ARCH.buildinfo artifacts/
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}-1_$TARGET_ARCH.changes artifacts/
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}-1.debian.tar.xz artifacts/
cp /var/cache/pbuilder/result/alcom_${PKG_VERSION//-/\~}-1.dsc artifacts/
ls artifacts
- name: Print information about built package
run: dpkg-deb -I artifacts/alcom_${PKG_VERSION//-/\~}-1_$TARGET_ARCH.deb
- name: Upload built binary
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v7
with:
name: artifacts-deb-${{ matrix.pbuilder-distribution }}-${{ matrix.target-arch }}
path: artifacts/*
build-updater-json:
@ -286,11 +457,11 @@ jobs:
needs: [ pre-build, build-rust ]
steps:
# use release
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
- name: Download All Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: assets
pattern: artifacts-*
@ -299,15 +470,14 @@ jobs:
- name: Run updater-json
env:
GUI_VERSION: ${{ needs.pre-build.outputs.gui-version }}
run: cargo run -p build-updater-json
run: cargo xtask alcom-updater-json --version "$GUI_VERSION" --assets assets updater.json
- name: Upload updater-json
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: updater.json
path: |
updater.json
updater-beta.json
publish-to-github:
name: Publish to GitHub
@ -318,16 +488,16 @@ jobs:
permissions:
contents: write
runs-on: ubuntu-latest
needs: [ pre-build, build-rust, build-updater-json ]
needs: [ pre-build, build-rust, build-rpm, build-deb, build-updater-json ]
env:
GUI_VERSION: ${{ needs.pre-build.outputs.gui-version }}
steps:
- uses: actions/create-github-app-token@v2
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
fetch-depth: 2
@ -340,7 +510,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- name: Download All Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: assets
pattern: artifacts-*
@ -348,7 +518,7 @@ jobs:
- name: Download changelog
# if: ${{ !needs.pre-build.outputs.prerelease }}
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: release-note-for-release
path: changelog
@ -401,7 +571,7 @@ jobs:
- build-rust
- publish-to-github
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
fetch-depth: 2
@ -418,14 +588,14 @@ jobs:
env:
GUI_VERSION: ${{ needs.pre-build.outputs.gui-version }}
steps:
- uses: actions/create-github-app-token@v2
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
owner: vrc-get
repositories: vrc-get.anatawa12.com
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
repository: 'vrc-get/vrc-get.anatawa12.com'
ref: 'master'
@ -434,7 +604,7 @@ jobs:
- uses: snow-actions/git-config-user@v1.0.0
- name: Download updater.json
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: updater.json
path: .
@ -448,7 +618,7 @@ jobs:
mv updater.json public/api/gui/tauri-updater.json
fi
rm public/api/gui/tauri-updater-beta.json || true
mv updater-beta.json public/api/gui/tauri-updater-beta.json
mv updater.json public/api/gui/tauri-updater-beta.json
- name: Commit
run: |-

View file

@ -12,6 +12,14 @@ on:
- prerelease
- start-rc
- stable
dry-run:
type: boolean
description: Dry Run, If true, do not publish release to GitHub.
default: true
required: false
concurrency:
group: releasing
jobs:
pre-build:
@ -24,7 +32,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
submodules: recursive
- uses: anatawa12/something-releaser@v3
@ -67,8 +75,12 @@ jobs:
echo "head is master, master-*, or hotfix-*"
;;
* )
echo "invalid release kind: $RELEASE_KIND_IN is not allowd for $GITHUB_REF_NAME"
exit 255
if [ "$DRY_RUN" = "true" ]; then
echo "head is not master, but DRY_RUN is true"
else
echo "head is not master, but DRY_RUN is false"
exit 255
fi
;;
esac
@ -76,6 +88,7 @@ jobs:
gh-export-variable VPM_VERSION "$(get-version -t vpm)"
env:
RELEASE_KIND_IN: ${{ github.event.inputs.release_kind }}
DRY_RUN: ${{ inputs.dry-run }}
# region changelog
- name: Create Changelog
@ -94,7 +107,7 @@ jobs:
---
- name: Upload CHANGELOG.md
if: ${{ !steps.update-version.outputs.prerelease }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: CHANGELOG
path: CHANGELOG.md
@ -103,7 +116,7 @@ jobs:
run: cp "${{ steps.changelog.outputs.release-note }}" release-note.md
- name: Upload release note
if: ${{ !steps.update-version.outputs.prerelease }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: release-note-for-release
path: release-note.md
@ -164,7 +177,7 @@ jobs:
needs: [ pre-build ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
submodules: recursive
@ -186,12 +199,13 @@ jobs:
run: cargo build --target ${{ matrix.triple }} --release --verbose
- name: Check binary is statically linked
shell: bash
env:
RUSTFLAGS: ''
run: |
# https://github.com/taiki-e/setup-cross-toolchain-action/issues/18
unset CARGO_BUILD_TARGET
cargo run -p build-check-static-link target/${{ matrix.triple }}/release/vrc-get*
cargo xtask check-static-link target/${{ matrix.triple }}/release/vrc-get${WINDIR:+.exe}
- name: Move artifacts
if: ${{ !cancelled() }}
shell: bash
run: |-
mkdir artifacts
@ -201,20 +215,22 @@ jobs:
done
popd
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
if: ${{ !cancelled() }}
with:
name: artifacts-${{ matrix.triple }}
path: artifacts/*
publish-crates-io:
name: Publish to crates.io
if: ${{ !inputs.dry-run }}
environment:
name: crates.io
url: https://crates.io/crates/vrc-get
runs-on: ubuntu-latest
needs: [ pre-build, build-rust ]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
fetch-depth: 1
@ -232,6 +248,7 @@ jobs:
publish-to-github:
name: Publish to GitHub
if: ${{ !inputs.dry-run }}
environment:
name: actions-github-app
url: https://github.com/anatawa12/vrc-get/releases/v${{ needs.pre-build.outputs.cli-version }}
@ -243,12 +260,12 @@ jobs:
CLI_VERSION: ${{ needs.pre-build.outputs.cli-version }}
VPM_VERSION: ${{ needs.pre-build.outputs.vpm-version }}
steps:
- uses: actions/create-github-app-token@v2
- uses: actions/create-github-app-token@v3
id: app-token
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
fetch-depth: 2
@ -261,7 +278,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- name: Download All Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: assets
pattern: artifacts-*
@ -269,7 +286,7 @@ jobs:
- name: Download changelog
if: ${{ !needs.pre-build.outputs.prerelease }}
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: release-note-for-release
path: changelog
@ -326,7 +343,7 @@ jobs:
CLI_VERSION: ${{ needs.pre-build.outputs.cli-version }}
VPM_VERSION: ${{ needs.pre-build.outputs.vpm-version }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
ref: 'releasing'
fetch-depth: 2
@ -336,7 +353,7 @@ jobs:
publish-to-homebrew:
name: Publish to homebrew
# vrc-get is on autobump list https://github.com/Homebrew/homebrew-core/blame/master/.github/autobump.txt
if: false # ${{ !needs.pre-build.outputs.prerelease }}
if: false # ${{ !inputs.dry-run && !needs.pre-build.outputs.prerelease }}
environment:
name: homebrew-core
url: https://github.com/homebrew/homebrew-core
@ -350,7 +367,7 @@ jobs:
publish-to-winget:
name: Publish to winget
if: ${{ !needs.pre-build.outputs.prerelease }}
if: ${{ !inputs.dry-run && !needs.pre-build.outputs.prerelease }}
needs: [ pre-build, publish-to-github ]
uses: vrc-get/vrc-get/.github/workflows/publish-cli-winget.yml@master

View file

@ -8,6 +8,7 @@ The format is based on [Keep a Changelog].
## [Unreleased]
### Added
- Implement project sorting by creation date `#2941`
### Changed
@ -16,10 +17,127 @@ The format is based on [Keep a Changelog].
### Removed
### Fixed
- Unity can be duplicated `#2321`
### Security
## [1.1.6] - 2026-06-02
### Added
- The package list can show hidden packages. [`#2731`](https://github.com/vrc-get/vrc-get/pull/2731)
- Build-time option to disable auto updater [`#2759`](https://github.com/vrc-get/vrc-get/pull/2759)
- Please read README for new build instruction.
- User repositories can now be reordered by drag and drop [`#2935`](https://github.com/vrc-get/vrc-get/pull/2935)
### Changed
- The "Clear Selection" button in the package management screen is now red (destructive style) to distinguish it from the "Install Selected" button [`#2803`](https://github.com/vrc-get/vrc-get/pull/2803)
- File filled with '\0' or whitespace will be treated as empty file [`#2710`](https://github.com/vrc-get/vrc-get/pull/2710)
- This should prevent `syntax error loading settings.json: expected value at line 1 column 1` if settings.json is broken
- We also added a backup file to recover from settings.json corruption [`#2933`](https://github.com/vrc-get/vrc-get/pull/2933)
- Completely changed how do we build ALCOM and how do we self-update ALCOM [`#2759`](https://github.com/vrc-get/vrc-get/pull/2759) [`#2828`](https://github.com/vrc-get/vrc-get/pull/2828) [`#2881`](https://github.com/vrc-get/vrc-get/pull/2881) [`#2882`](https://github.com/vrc-get/vrc-get/pull/2882) [`#2885`](https://github.com/vrc-get/vrc-get/pull/2885)
- This fixes few problems relates to auto update
- Please read README for new build instruction.
- Improved backup speed by parallelizing the process [`#2746`](https://github.com/vrc-get/vrc-get/pull/2746)
- Along with this change, the default compression level has been changed to `zip-fast`
- We added dialog on enabling "Show Prerelease Packages" [`#2795`](https://github.com/vrc-get/vrc-get/pull/2795)
- I hope this prevents users unexpectedly adding prerelease packages
- Path for unitypackage on Template Editor now can be reselected [`#2635`](https://github.com/vrc-get/vrc-get/pull/2635)
- ALCOM now refuses launching project if project is on noexec mount points [`#2814`](https://github.com/vrc-get/vrc-get/pull/2814)
- This would cause problems with several native plugins
- Already-added packages are now excluded from the package name suggestions in the Template Editor [`#2828`](https://github.com/vrc-get/vrc-get/pull/2828)
- Extended some timeouts to 1 minute [`#2826`](https://github.com/vrc-get/vrc-get/pull/2826)
- Prevents timeouts in slow DNS environments
- Improved robustness for package installation errors [`#2844`](https://github.com/vrc-get/vrc-get/pull/2844)
- It is now unlikely that vrc-get will leave the project directory corrupted if an I/O error occurs while installing a package
- Backslashes in path in zip file are now treated as path separator on unix [`#2845`](https://github.com/vrc-get/vrc-get/pull/2845)
- This fixes problem with Gesture Manager 3.9.7
- Empty string for `documentationUrl` and `changelogUrl` are now allowed and ignored [`#2930`](https://github.com/vrc-get/vrc-get/pull/2930)
- They are formerly rejected as invalid url
### Fixed
- Fixed an issue where the progress bar flickered and did not display correct progress in environments using WebKit as the renderer. [`#2641`](https://github.com/vrc-get/vrc-get/pull/2641)
- Fails to import UnityPackages with files in `Packages` directory [`#2679`](https://github.com/vrc-get/vrc-get/pull/2679)
- null as vpmDependencies value is not allowed [`#2709`](https://github.com/vrc-get/vrc-get/pull/2709)
- It's not recommended, but we allow null for `vpmDependencies` as a alias of `{}`
- ALCOM cannot detect per-user flatpak installation of unity hub [`#2812`](https://github.com/vrc-get/vrc-get/pull/2812)
- Unabled to import some untypackages [`#2821`](https://github.com/vrc-get/vrc-get/pull/2821)
- It's hard to say but some older unitypackages ware unsupported.
- Panic when resolving projects where dependency packages depend on newer versions of locked packages [`#2822`](https://github.com/vrc-get/vrc-get/pull/2822)
- Missing glibc and libgcc_s dependency notation in .deb / .rpm distributon [`#2828`](https://github.com/vrc-get/vrc-get/pull/2828)
- Unclear error message for invalid version name or version range [`#2842`](https://github.com/vrc-get/vrc-get/pull/2842)
- Default file names in save dialogs now include the appropriate file extension [`#2846`](https://github.com/vrc-get/vrc-get/pull/2846)
- Template export now defaults to `{template name}.alcomtemplate`
- Repository list export now defaults to `repositories.txt`
- Uninformative `[object Object]` appearing as an error message [`#2848`](https://github.com/vrc-get/vrc-get/pull/2848)
- New Unity Hub loading method may not load manually added Unity Editors [`#2850`](https://github.com/vrc-get/vrc-get/pull/2850)
- New Unity Hub loading method does load unity hub configuration on Linux [`#2850`](https://github.com/vrc-get/vrc-get/pull/2850)
- Too many open files when copying project `#2867
- Added workaround for VRCDefaultWorldScene generation issue in SDK 3.10.2 or later [`#2916`](https://github.com/vrc-get/vrc-get/pull/2916)
- See [this][default-scene-canny] canny for bug in VRCSDK and issue [#2913][issue-2913] for our decision.
### Security
- Package hash checks are now enforced when installing packages [`#2849`](https://github.com/vrc-get/vrc-get/pull/2849)
- It has been about two years since the error message for package hash mismatches was introduced.
- It is now enforced for security.
[default-scene-canny]: https://feedback.vrchat.com/sdk-bug-reports/p/3102-3103-vrcscenetemplateinitializer-does-not-create-sample-scene-if-udon-prepr
[issue-2913]: https://github.com/vrc-get/vrc-get/issues/2913
## [1.1.5] - 2025-11-16
- Fix package version selector dropdown exceeding window height [`#2589`](https://github.com/vrc-get/vrc-get/pull/2589)
- The dropdown list now has a maximum height of 50% of the viewport or 24rem, whichever is smaller
- This prevents the version selector from overflowing the window on small screens
- Fix muted-foreground color [`#2516`](https://github.com/vrc-get/vrc-get/pull/2516) [`#2517`](https://github.com/vrc-get/vrc-get/pull/2517)
- Remove `DialogDescription` not in `DialogHeader` to fix text color
- Fix 'Detected Loop' panic with valid database file [`#2607`](https://github.com/vrc-get/vrc-get/pull/2607)
## [1.1.4] - 2025-09-02
### Added
- Add compact gui option [`#2436`](https://github.com/vrc-get/vrc-get/pull/2436) [`#2450`](https://github.com/vrc-get/vrc-get/pull/2450) [`#2470`](https://github.com/vrc-get/vrc-get/pull/2470)
### Changed
- Improved saving interacting with setting files [`#2485`](https://github.com/vrc-get/vrc-get/pull/2485)
- This should reduce "EOF while parsing a value at line 1 column 0" error on launch.
- This should reduce losing settings after crashing ALCOM or PC.
### Fixed
- Specifying a single unityversion doesn't work properly in alcomtemplate [`#2452`](https://github.com/vrc-get/vrc-get/pull/2452)
- For example, if you'd like to specify `2022.3.22f1`, you need to set `2022.3.22`, not `2022.3.22f1`
- You can now see correct validation and suggestions for this.
- Home/End and Up/Down keys now consistently control cursor position in autocomplete fields [`#2466`](https://github.com/vrc-get/vrc-get/pull/2466)
- Home/End keys now always move the text cursor regardless of autocomplete state
- Up/Down keys move the text cursor when suggestions are not visible, and navigate suggestions when they are visible
- Previously, these keys would sometimes be captured for suggestion navigation when autocomplete was open
## [1.1.3] - 2025-07-28
### Added
- Add support for `keywords` UPM manifest field [`#2375`](https://github.com/vrc-get/vrc-get/pull/2375)
- You now can specifiy search keywords for package with `keywords` UPM manifest field
- Favorites for templates [`#2376`](https://github.com/vrc-get/vrc-get/pull/2376)
- It's much easier to select project templates you likely to use.
### Changed
- Improved the Template Editor with AutoComplete [`#2371`](https://github.com/vrc-get/vrc-get/pull/2371)
- You no longer need to remember the package name (id) and version associated with the package.
- You now can search package by display name, name (id), aliases to enter package name, and ALCOM shows common version range for you.
- Updated project settings of templates to include Item layer [`#2373`](https://github.com/vrc-get/vrc-get/pull/2373)
- You should no longer need to update layers and collision matrix before uploading world
- Improved behavior about `settings.json` to `vcc.litedb` migration [`#2327`](https://github.com/vrc-get/vrc-get/pull/2327)
- See [`vrchat-community/creator-companion#492`](https://github.com/vrchat-community/creator-companion/issues/492) and the PR for details
- Last used template is now preserved [`#2376`](https://github.com/vrc-get/vrc-get/pull/2376)
- When you generally create project with custom template, you no longer need to change template every time.
### Fixed
- Packages are not deselected after installing packages [`#2372`](https://github.com/vrc-get/vrc-get/pull/2372)
## [1.1.2] - 2025-06-30
### Fixed
- Fixed `a - b` version range is not correctly serialized on the `vpm-manifest.json`
- Frontend error on package list update [`#2341`](https://github.com/vrc-get/vrc-get/pull/2341)
## [1.1.1] - 2025-06-21
### Fixed
- Unity can be duplicated [`#2321`](https://github.com/vrc-get/vrc-get/pull/2321)
- Crash on creating a new project on Windows [`#2326`](https://github.com/vrc-get/vrc-get/pull/2326)
## [1.1.0] - 2025-06-19
### Added
- Support for Projects with Unity 2018 or older [`#2106`](https://github.com/vrc-get/vrc-get/pull/2106)
@ -585,7 +703,13 @@ Release pipeline fixes
- Apple code signing [`#422`](https://github.com/anatawa12/vrc-get/pull/422)
- Migrate vpm 2019 project to 2022 [`#435`](https://github.com/anatawa12/vrc-get/pull/435)
[Unreleased]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.0...HEAD
[Unreleased]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.6...HEAD
[1.1.6]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.5...gui-v1.1.6
[1.1.5]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.4...gui-v1.1.5
[1.1.4]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.3...gui-v1.1.4
[1.1.3]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.2...gui-v1.1.3
[1.1.2]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.1...gui-v1.1.2
[1.1.1]: https://github.com/vrc-get/vrc-get/compare/gui-v1.1.0...gui-v1.1.1
[1.1.0]: https://github.com/vrc-get/vrc-get/compare/gui-v1.0.1...gui-v1.1.0
[1.0.1]: https://github.com/vrc-get/vrc-get/compare/gui-v1.0.0...gui-v1.0.1
[1.0.0]: https://github.com/vrc-get/vrc-get/compare/gui-v0.1.17...gui-v1.0.0

View file

@ -10,28 +10,52 @@ The format is based on [Keep a Changelog].
### Added
### Changed
- Changed how we read VCC's project information `#1997`
- Along with this, building this project no longer needs dotnet SDK to build.
- Migrated the project to Rust 2024 `#1956`
- This is internal changes should not cause behavior changes
- This would require Rust 1.85 for building this project
- Removed `cargo-about` from build-time dependency `#1961`
- This is internal changes should not cause behavior changes
- I listed here since this may need update on package metadata of some package managers
- The method to retrieve the list of Unity from Unity Hub `#1808` `#1971`
- You now can select multiple folders at once to adding project `#2018`
- I didn't know official VCC had such a feature. Sorry for lack of feature!
- The requirements for unity project `#2106`
- Since this version, `Projectsettings/ProjectVersion.txt` is required.
- Improved saving interacting with setting files `#2485` `#2710`
- This should reduce "EOF while parsing a value at line 1 column 0" error on launch.
- This should reduce losing settings after crashing ALCOM or PC.
- null as vpmDependencies value is not allowed `#2709`
- It's not recommended, but we allow null for `vpmDependencies` as a alias of `{}`
- Improved robustness for package installation errors `#2844`
- It is now unlikely that vrc-get will leave the project directory corrupted if an I/O error occurs while installing a package
- Backslashes in path in zip file are now treated as path separator on unix `#2845`
- This fixes problem with Gesture Manager 3.9.7
### Deprecated
### Removed
### Fixed
- Uninstall package is not reverted successfully if removing package is prevented by `ERROR_SHARING_VIOLATION` `#2209`
- Fix 'Detected Loop' panic with valid database file `#2607`
- Panic when resolving projects where dependency packages depend on newer versions of locked packages `#2822`
- Warning for backup/project path in AppData folder not shown when path is in Roaming or LocalLow [`#2827`](https://github.com/vrc-get/vrc-get/pull/2827)
- Unclear error message for invalid version name or version range `#2842`
- Empty string for `documentationUrl` and `changelogUrl` are now allowed and ignored `#2930`
- They are formerly rejected as invalid url
### Security
- Package hash checks are now enforced when installing packages `#2849`
- It has been about two years since the error message for package hash mismatches was introduced.
- It is now enforced for security.
## [1.9.1] - 2025-07-28
### Changed
- Changed how we read VCC's project information [`#1997`](https://github.com/vrc-get/vrc-get/pull/1997)
- Along with this, building this project no longer needs dotnet SDK to build.
- Migrated the project to Rust 2024 [`#1956`](https://github.com/vrc-get/vrc-get/pull/1956)
- This is internal changes should not cause behavior changes
- This would require Rust 1.85 for building this project
- Removed `cargo-about` from build-time dependency [`#1961`](https://github.com/vrc-get/vrc-get/pull/1961)
- This is internal changes should not cause behavior changes
- I listed here since this may need update on package metadata of some package managers
- The method to retrieve the list of Unity from Unity Hub [`#1808`](https://github.com/vrc-get/vrc-get/pull/1808) [`#1971`](https://github.com/vrc-get/vrc-get/pull/1971)
- You now can select multiple folders at once to adding project [`#2018`](https://github.com/vrc-get/vrc-get/pull/2018)
- I didn't know official VCC had such a feature. Sorry for lack of feature!
- The requirements for unity project [`#2106`](https://github.com/vrc-get/vrc-get/pull/2106)
- Since this version, `Projectsettings/ProjectVersion.txt` is required.
### Fixed
- Uninstall package is not reverted successfully if removing package is prevented by `ERROR_SHARING_VIOLATION` [`#2209`](https://github.com/vrc-get/vrc-get/pull/2209)
- Fixed `a - b` version range is not correctly serialized on the `vpm-manifest.json`
## [1.9.0] - 2025-01-01
### Added
@ -482,7 +506,8 @@ The format is based on [Keep a Changelog].
## [0.1.0] - 2023-01-25
Initial Release
[Unreleased]: https://github.com/vrc-get/vrc-get/compare/v1.9.0...HEAD
[Unreleased]: https://github.com/vrc-get/vrc-get/compare/v1.9.1...HEAD
[1.9.1]: https://github.com/vrc-get/vrc-get/compare/v1.9.0...v1.9.1
[1.9.0]: https://github.com/vrc-get/vrc-get/compare/v1.8.2...v1.9.0
[1.8.2]: https://github.com/vrc-get/vrc-get/compare/v1.8.1...v1.8.2
[1.8.1]: https://github.com/vrc-get/vrc-get/compare/v1.8.0...v1.8.1

3627
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,10 @@
resolver = "2"
members = [
"build-check-static-link",
"build-updater-json",
"xtask",
"vrc-get",
"vrc-get-gui",
"vrc-get-gui/windows-installer-wrapper",
"vrc-get-vpm",
]
@ -24,3 +24,10 @@ authors = ["anatawa12 <anatawa12@icloud.com>"]
homepage = "https://github.com/anatawa12/vrc-get#readme"
repository = "https://github.com/anatawa12/vrc-get"
readme = "README.md"
[profile.xtask]
inherits = "dev"
incremental = false
debug = 1
opt-level = 0
lto = "off"

View file

@ -1 +0,0 @@
/*

View file

@ -1,23 +0,0 @@
[package]
name = "build-check-static-link"
version = "0.1.0"
edition.workspace = true
license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.object]
version = "0.37"
default-features = false
features = [
"read_core",
"macho",
"pe",
"elf",
]

View file

@ -1,11 +0,0 @@
This crate is to ensure built binary is statically linked or dynamically linked to the system libraries.
this crate use `object` crate to read the binary file.
## Usage
```
cargo run -p build-check-static-link <path/to/binary>
```
exits with zero if statically linked or linked with allowed dynamic libraries, otherwise exits with non-zero.

View file

@ -1,132 +0,0 @@
use object::{Endian, Endianness, FileKind, Object};
use std::fs;
use std::process::exit;
fn main() {
let mut args = std::env::args();
let _ = args.next();
let mut success = true;
for arg in args {
if arg.ends_with(".d") {
println!("skipping .d file: {}", arg);
continue;
}
let binary = std::path::Path::new(&arg);
let binary = fs::read(binary).unwrap();
success |= match FileKind::parse(binary.as_slice()).expect("detecting type") {
FileKind::MachO64 => process_mach_64::<Endianness>(&binary),
FileKind::Pe64 => process_pe_64(&binary),
FileKind::Elf64 => process_elf_64::<Endianness>(&binary),
unknown => panic!("unknown file type: {:?}", unknown),
};
}
if success { exit(0) } else { exit(1) }
}
fn process_mach_64<E: Endian>(binary: &[u8]) -> bool {
use object::macho::*;
use object::read::macho::*;
let mut success = true;
let parsed = MachHeader64::<E>::parse(binary, 0).expect("failed to parse binary");
let endian = parsed.endian().unwrap();
let mut commands = parsed
.load_commands(endian, binary, 0)
.expect("parsing binary");
while let Some(command) = commands.next().expect("reading binary") {
if let Some(dylib) = command.dylib().unwrap() {
let dylib = command.string(endian, dylib.dylib.name).unwrap();
match dylib {
| b"/System/Library/Frameworks/Security.framework/Versions/A/Security"
| b"/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration"
| b"/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation"
| b"/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation"
| b"/usr/lib/libobjc.A.dylib"
| b"/usr/lib/libiconv.2.dylib"
| b"/usr/lib/libSystem.B.dylib"
=> {
// known system library
println!("system dylib: {}", std::str::from_utf8(dylib).unwrap());
}
unknown => {
println!("ERROR: unknown dylib: {:?}", std::str::from_utf8(unknown).unwrap_or("unable to parse with utf8"));
success = false;
},
}
} else if command.cmd() == LC_LOAD_DYLINKER {
let data: &DylinkerCommand<E> = command.data().expect("parse LC_LOAD_DYLINKER");
if command.string(endian, data.name).unwrap() != b"/usr/lib/dyld" {
println!("ERROR: dylinker is not /usr/lib/dyld");
success = false;
} else {
println!("dylinker: /usr/lib/dyld");
}
}
}
success
}
fn process_pe_64(binary: &[u8]) -> bool {
use object::LittleEndian as LE;
use object::read::pe::*;
let mut success = true;
let parsed = PeFile64::parse(binary).expect("failed to parse binary");
let table = parsed.import_table().unwrap().unwrap();
let mut iter = table.descriptors().unwrap();
while let Some(x) = iter.next().unwrap() {
let dll = table.name(x.name.get(LE)).unwrap();
match dll.to_ascii_lowercase().as_slice() {
| b"advapi32.dll"
| b"kernel32.dll"
| b"bcrypt.dll" // TODO: check if this is a system library
| b"ntdll.dll"
| b"shell32.dll"
| b"ole32.dll"
| b"ws2_32.dll"
| b"crypt32.dll"
=> {
println!("system dll: {}", std::str::from_utf8(dll).unwrap());
// known system library
}
unknown => {
println!("ERROR: unknown dll: {:?}", std::str::from_utf8(unknown).unwrap_or("unable to parse with utf8"));
success = false;
},
}
}
success
}
fn process_elf_64<E: Endian>(binary: &[u8]) -> bool {
use object::elf::*;
use object::read::elf::*;
let mut success = true;
let parsed = ElfFile64::<E>::parse(binary).expect("failed to parse binary");
for x in parsed.imports().unwrap() {
println!(
"dynamic importing symbol: {}",
std::str::from_utf8(x.name()).unwrap()
);
success = false;
}
for segment in parsed.elf_program_headers() {
if segment.p_type.get(parsed.endian()) == PT_INTERP {
let data = segment.data(parsed.endian(), parsed.data()).unwrap();
println!("interpreter: {:?}", std::str::from_utf8(data).unwrap());
success = false;
}
}
success
}

View file

@ -1 +0,0 @@
/*

View file

@ -1,17 +0,0 @@
[package]
name = "build-updater-json"
version = "0.1.0"
edition.workspace = true
license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = { version = "0.4", default-features = false, features = ["now", "serde"] }
indexmap = { version = "2", features = ["serde"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View file

@ -1,85 +0,0 @@
// see https://tauri.app/v1/guides/distribution/updater/ for json format
use chrono::{Timelike, Utc};
use indexmap::IndexMap;
use serde::Serialize;
use std::path::Path;
#[derive(Serialize)]
struct UpdaterJson {
version: String,
notes: String,
pub_date: chrono::DateTime<Utc>,
platforms: IndexMap<String, Platform>,
}
#[derive(Serialize)]
struct Platform {
signature: String,
url: String,
}
fn main() {
// consts
const DOWNLOAD_URL_BASE: &str =
"https://github.com/vrc-get/vrc-get/releases/download/gui-v{version}";
let platform_file_name = [
("darwin-x86_64", "ALCOM-{version}-universal.app.tar.gz"),
("darwin-aarch64", "ALCOM-{version}-universal.app.tar.gz"),
("linux-x86_64", "alcom-{version}-x86_64.AppImage.tar.gz"),
//("linux-aarch64", "alcom-{version}-aarch64.AppImage.tar.gz"),
("windows-x86_64", "ALCOM-{version}-x86_64-setup.nsis.zip"),
//("windows-aarch64", "ALCOM-{version}-aarch64-setup.nsis.zip"),
]
.into_iter()
.collect::<IndexMap<_, _>>();
let version = std::env::var("GUI_VERSION").expect("GUI_VERSION not set");
let base_url = DOWNLOAD_URL_BASE.replace("{version}", &version);
// create platforms info
let mut platforms = IndexMap::new();
for (platform, file_name) in platform_file_name {
let file_name = file_name.replace("{version}", &version);
std::fs::metadata(format!("assets/{file_name}"))
.unwrap_or_else(|e| panic!("{}: {}", file_name, e));
let signature = std::fs::read_to_string(format!("assets/{file_name}.sig"))
.unwrap_or_else(|e| panic!("{}.sig: {}", file_name, e));
let url = format!("{}/{}", base_url, file_name);
platforms.insert(platform.to_string(), Platform { signature, url });
}
let is_beta = version.contains('-');
let notes = if is_beta {
// https://github.com/vrc-get/vrc-get/blob/master/CHANGELOG-gui.md#unreleased
"Please read changelog at https://github.com/vrc-get/vrc-get/blob/master/CHANGELOG-gui.md#unreleased".into()
} else {
// https://github.com/vrc-get/vrc-get/blob/master/CHANGELOG-gui.md#101---2025-02-05
let version = version.replace('.', "");
let date = Utc::now().format("%Y-%m-%d").to_string();
format!(
"Please read changelog at https://github.com/vrc-get/vrc-get/blob/master/CHANGELOG-gui.md#{version}---{date}"
)
};
let updater = UpdaterJson {
version,
notes,
pub_date: Utc::now().with_nanosecond(0).unwrap(),
platforms,
};
if !is_beta {
write_json("updater.json", &updater);
}
write_json("updater-beta.json", &updater);
}
fn write_json(path: impl AsRef<Path>, json: impl Serialize) {
let json = serde_json::to_string_pretty(&json).unwrap();
std::fs::write(path, json).expect("write updater.json");
}

1
vrc-get-gui/.npmrc Normal file
View file

@ -0,0 +1 @@
ignore-scripts=true

View file

@ -1,6 +1,6 @@
[package]
name = "vrc-get-gui"
version = "1.1.1-rc.0"
version = "1.1.7-beta.0"
description = "A fast open-source alternative of VRChat Creator Companion"
homepage.workspace = true
@ -22,17 +22,17 @@ tauri-build = { version = "2", features = [ "config-toml" ] }
serde_json = "1"
serde = { version = "1", features = ["derive"] }
serde_with = { version = "3", features = ["base64"] }
tauri = { version = "2", features = [ "config-toml" ] }
tauri = { version = "=2.11.2", features = [ "config-toml" ] } # = for sync version between npm and cargo
vrc-get-vpm = { path = "../vrc-get-vpm", features = ["experimental-project-management", "experimental-unity-management"] }
reqwest = { version = "0.12", features = ["gzip", "brotli"] }
specta = { version = "2.0.0-rc.20", features = [ "chrono", "url", "indexmap" ] }
tauri-specta = { version = "2.0.0-rc.20", features = ["typescript"] }
specta-typescript = "0.0.7"
reqwest = { version = "0.13", features = ["gzip", "brotli", "json"] }
specta = { version = "2.0.0-rc.24", features = [ "chrono", "url", "indexmap" ] }
tauri-specta = { version = "2.0.0-rc.24", features = ["typescript"] }
specta-typescript = "0.0.11"
open = "5"
arc-swap = "1"
log = { version = "0.4", features = [ "std", "kv" ] }
chrono = { version = "0.4", features = [ "serde" ] }
ringbuffer = "0.15"
ringbuffer = "0.16"
tokio = { version = "1", features = ["process"] }
tokio-util = "0.7"
fs_extra = "1"
@ -42,12 +42,17 @@ tar = "0.4"
flate2 = "1"
uuid = { version = "1", features = ["v4"] }
trash = "5"
async_zip = { version = "0.0.17", features = ["deflate", "tokio"] }
async_zip = { version = "0.0.18", features = ["tokio", "deflate"] }
async-compression = { version = "0.4", features = ["gzip", "futures-io"] }
async-stream = "0.3"
tauri-plugin-single-instance = "2"
tauri-plugin-updater = "2"
tauri-plugin-dialog = "2"
minisign-verify = "0.2"
base64 = "0.22"
semver = "1"
tempfile = "3"
sha2 = "0.11"
hex = "0.4"
sys-locale = "0.3"
log-panics = { version = "2", features = ["with-backtrace"] }
url = "2"
@ -56,11 +61,12 @@ yoke = { version = "0.8", features = ["derive"] }
atomicbox = "0.4"
stable_deref_trait = "1"
itertools = "0.14"
sysinfo = "0.39.3"
[target.'cfg(windows)'.dependencies]
windows = { version = "0.61", features = ["Win32_Storage_FileSystem", "Win32_System_IO", "Win32_NetworkManagement_IpHelper", "Wdk_System_SystemServices", "Win32_System_SystemInformation"] }
winreg = "0.55"
wmi = "0.17"
windows = { version = "0.62", features = ["Win32_Storage_FileSystem", "Win32_System_IO", "Win32_NetworkManagement_IpHelper", "Wdk_System_SystemServices", "Win32_System_SystemInformation", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
winreg = "0.56"
wmi = "0.18"
[target.'cfg(target_os = "macos")'.dependencies]
plist = { version = "1" }
@ -69,12 +75,22 @@ objc2-foundation = "0.3.0"
block2 = "0.6.0"
objc2 = "0.6.0"
dispatch2 = "0.3.0"
rlimit = "0.11.0"
[target.'cfg(unix)'.dependencies]
nix = { version = "0.30", features = ["fs"] }
nix = { version = "0.31", features = ["fs", "mount"] }
[features]
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
# DO NOT REMOVE!!
custom-protocol = [ "tauri/custom-protocol" ]
no-self-updater = []
# Devtools
#
# Enables browser devtools for debugging javascript part.
# It's not recommended to enable this for production builds,
# development use only!
devtools = ["tauri/devtools"]

View file

@ -75,9 +75,9 @@ To build ALCOM, you need to have the following installed:
- [cargo] latest — to build the most part of the project
- And other requirements for tauri, see [tauri requirements](https://v2.tauri.app/start/prerequisites/#system-dependencies)
Please note that ALCOM requires the latest version of cargo at that time.
Please note that ALCOM requires the latest version of rust toolchain at that time.
We update the required version of cargo without notice.
Therefore, you may need to update them before building the project.
Therefore, It's recommended to update rust toolchain before building the project.
[Node.js]: https://nodejs.org/en
[npm]: https://www.npmjs.com
@ -88,9 +88,27 @@ Therefore, you may need to update them before building the project.
To build the project, run the following command:
```bash
npm run tauri build
cargo xtask build-alcom --release
```
This command builds the main ALCOM executable for the current platform.
For cross-compilation, add the `--target` command-line parameter.
The executable will be created in the `target/release` directory.
There are a few build options available when building ALCOM.
Most notably, you can disable the self-updater with the `--no-self-updater` option.
Note that this does not disable update checks.
ALCOM will show a message when a newer release is available instead of offering a self-update.
Directly distributing the executable may be suitable for some environments, but we also provide bundled distributions.
To bundle ALCOM, run the following command after building it.
```bash
cargo xtask bundle-alcom --release --bundles <bundles>
```
Check `--help` for the list of supported bundle types.
## Development
ALCOM is currently based on tauri and next.js.

View file

@ -6,65 +6,3 @@ beforeBuildCommand = "npm run build"
beforeDevCommand = "npm run dev"
devUrl = "http://localhost:3030"
frontendDist = "out"
[bundle]
active = true
targets = [
"appimage",
"deb",
"rpm",
"nsis", #-setup.exe
"app", # needs for dmg
"dmg",
]
longDescription = "ALCOM is a fast and open-source alternative VCC (VRChat Creator Companion) written in rust and tauri."
shortDescription = "ALCOM - Alternative Creator Companion"
category = "DeveloperTool"
copyright = "(c) anatawa12 and other contributors"
externalBin = []
icon = [
"icons/32x32.png",
"icons/64x64.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico",
]
resources = []
publisher = "anatawa12"
createUpdaterArtifacts = "v1Compatible" # remove if ci # we do not generate updater artifacts in CI
[[bundle.fileAssociations]]
# note: for macOS we directory use info.plist for registering file association.
description = "ALCOM Project Template"
ext = ['alcomtemplate']
mimeType = "application/x-alcom-template+json"
name = "ALCOM Project Template"
[bundle.linux.deb]
desktopTemplate = "alcom.desktop"
[bundle.linux.rpm]
desktopTemplate = "alcom.desktop"
[bundle.macOS]
exceptionDomain = ""
frameworks = []
providerShortName = "anatawa12"
[bundle.windows]
nsis.template = "installer.nsi"
# signing
certificateThumbprint = "0D17F6395EC64A2B1D341BB7AC5B3163EB148BB7"
timestampUrl = "http://ts.ssl.com"
digestAlgorithm = "sha256"
tsp = true
[plugins.updater]
endpoints = []
pubkey = "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDkyMjAzMkU2Q0ZGQjQ0MjYKUldRbVJQdlA1aklna2d2NnRoM3ZsT3lzWEQ3MC9zTGpaWVR4NGdQOXR0UGJaOHBlY2xCcFY5bHcK"
[app.security]

View file

@ -1,11 +0,0 @@
[Desktop Entry]
Categories={{categories}}
{{#if comment}}
Comment={{comment}}
{{/if}}
Exec={{exec}} %u
Icon={{icon}}
Name={{name}}
Terminal=false
Type=Application
MimeType=x-scheme-handler/vcc

View file

@ -1,20 +1,25 @@
"use client"; // Error components must be Client Components
import { useEffect } from "react";
import { commands } from "@/lib/bindings";
import globalInfo from "@/lib/global-info";
import { useEffect } from "react";
export default function ErrorPage({
error,
}: {
error: Error;
error: object;
reset?: () => void;
}) {
useEffect(() => {
console.error(error);
}, [error]);
const errorMessage = `${error}`;
const errorStack = `${error.stack}`;
// When there is overridden toString, use it. if not, use stringify
const errorMessage =
error.toString === Object.prototype.toString
? JSON.stringify(error)
: error.toString();
const errorStack =
"stack" in error ? `${error.stack}` : "No stacktrace provided";
const openIssue = () => {
try {

View file

@ -2,7 +2,9 @@ import { LoaderCircle } from "lucide-react";
export default function Loading({
loadingText = "Loading...",
}: { loadingText?: React.ReactNode }) {
}: {
loadingText?: React.ReactNode;
}) {
return (
<div className="flex flex-col items-center justify-center h-full w-full space-y-4">
<LoaderCircle className="h-10 w-10 animate-spin" />

View file

@ -1,6 +1,6 @@
import { createRootRoute, Outlet } from "@tanstack/react-router";
import ErrorPage from "@/app/-error";
import { Providers } from "@/components/providers";
import { Outlet, createRootRoute } from "@tanstack/react-router";
import "./globals.css";
import React, { Suspense } from "react";

View file

@ -1,8 +1,9 @@
"use client";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { createFileRoute } from "@tanstack/react-router";
import { HNavBar, HNavBarText, VStack } from "@/components/layout";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { HNavBar, VStack } from "@/components/layout";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
@ -17,8 +18,13 @@ import {
SelectValue,
} from "@/components/ui/select";
import { tc } from "@/lib/i18n";
import { toastError, toastInfo, toastNormal, toastSuccess } from "@/lib/toast";
import { createFileRoute } from "@tanstack/react-router";
import {
toastError,
toastInfo,
toastNormal,
toastSuccess,
toastWarning,
} from "@/lib/toast";
export const Route = createFileRoute("/_main/dev-palette/")({
component: Page,
@ -28,12 +34,8 @@ function Page() {
return (
<VStack>
<HNavBar
className={"shrink-0"}
leading={
<p className="cursor-pointer py-1.5 font-bold grow-0">
UI Palette (dev only)
</p>
}
className="shrink-0"
leading={<HNavBarText>UI Palette (dev only)</HNavBarText>}
/>
<ScrollPageContainer>
<main className="flex flex-col gap-2 shrink grow">
@ -117,6 +119,12 @@ function Page() {
>
Error
</Button>
<Button
variant={"warning"}
onClick={() => toastWarning("Warning Toast Body")}
>
Warning
</Button>
<Button
variant={"success"}
onClick={() => toastSuccess("Success Toast Body")}
@ -177,7 +185,7 @@ function UnityTableBody() {
</tr>
</thead>
<tbody>
{unityPaths.map(([path, version, isFromHub]) => (
{unityPaths.map(([path, version, _isFromHub]) => (
<tr key={path} className="even:bg-secondary/30">
<td className={"p-2.5"}>{version}</td>
<td className={"p-2.5"}>{path}</td>

View file

@ -1,8 +1,8 @@
import { BugOff, CircleX, Info, OctagonAlert } from "lucide-react";
import { memo, useEffect, useMemo, useRef } from "react";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import type { LogEntry, LogLevel } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { BugOff, CircleX, Info, OctagonAlert } from "lucide-react";
import { memo, useEffect, useMemo, useRef } from "react";
export const LogsListCard = memo(function LogsListCard({
logEntry,
@ -81,12 +81,8 @@ export const LogsListCard = memo(function LogsListCard({
);
});
const LogRow = memo(function LogRow({
log,
}: {
log: LogEntry;
}) {
const cellClass = "p-2.5";
const LogRow = memo(function LogRow({ log }: { log: LogEntry }) {
const cellClass = "p-2.5 compact:py-1";
const formatDate = (dateString: string) => {
const date = new Date(dateString);

View file

@ -1,7 +1,16 @@
"use client";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ArrowDownFromLine } from "lucide-react";
import { useRef, useState } from "react";
import { HNavBar, HNavBarText, VStack } from "@/components/layout";
import { SearchBox } from "@/components/SearchBox";
import { HNavBar, VStack } from "@/components/layout";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
@ -23,15 +32,6 @@ import { tc } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import { useTauriListen } from "@/lib/use-tauri-listen";
import { useSessionStorage } from "@/lib/useSessionStorage";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ArrowDownFromLine } from "lucide-react";
import { useRef, useState } from "react";
import { LogsListCard } from "./-logs-list-card";
export const Route = createFileRoute("/_main/log/")({
@ -152,10 +152,10 @@ function ManageLogsHeading({
return (
<HNavBar
className={"shrink-0"}
className="shrink-0"
leading={
<>
<p className="cursor-pointer py-1.5 font-bold grow-0">{tc("logs")}</p>
<HNavBarText>{tc("logs")}</HNavBarText>
<SearchBox
className={"w-max grow"}
@ -169,7 +169,7 @@ function ManageLogsHeading({
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className={"shrink-0 p-3"}>
<Button className={"shrink-0 p-3 compact:h-10"}>
{tc("logs:manage:select logs level")}
</Button>
</DropdownMenuTrigger>
@ -207,6 +207,7 @@ function ManageLogsHeading({
</DropdownMenu>
<Button
className={"compact:h-10"}
onClick={() =>
commands.utilOpen(
`${globalInfo.vpmHomeFolder}/vrc-get/gui-logs`,
@ -222,11 +223,11 @@ function ManageLogsHeading({
<Button
variant={"ghost"}
onClick={() => handleLogAutoScrollChange(!autoScroll)}
className={
className={`compact:h-10 ${
autoScroll
? "bg-secondary border border-primary"
: "bg-transparent"
}
}`}
>
<ArrowDownFromLine className={"w-5 h-5"} />
</Button>

View file

@ -1,5 +1,5 @@
import { tc } from "@/lib/i18n";
import { Link } from "@tanstack/react-router";
import { tc } from "@/lib/i18n";
type PageType =
| "/packages/user-packages"
@ -8,15 +8,17 @@ type PageType =
// Note: For historical reasons, templates page are under packages in route.
export function HeadingPageName({
pageType,
}: {
pageType: PageType;
}) {
export function HeadingPageName({ pageType }: { pageType: PageType }) {
// Note for p-1 rounded-md -m-1 compact:m-0
// For normal mode, we use 1-unit of the outer padding for selector rectangle, so we use negative margin to eat padding.
// For compact mode, the height of the button is 2 units shorter than normal with the height of the navbar is remaining.
// Therefore we use the 1 unit space for outer padding for selector rectangle.
return (
<div className={"-ml-1.5"}>
<div className={"flex compact:h-10 items-center"}>
<div
className={"grid grid-cols-3 gap-1.5 bg-secondary p-1 -m-1 rounded-md"}
className={
"grid grid-cols-3 gap-1.5 bg-secondary p-1 rounded-md -m-1 compact:m-0"
}
>
<HeadingButton
currentPage={pageType}
@ -51,7 +53,7 @@ function HeadingButton({
children: React.ReactNode;
}) {
const button =
"cursor-pointer px-3 py-2 font-bold grow-0 hover:bg-background rounded-sm text-center p-2";
"cursor-pointer px-3 py-2 font-bold grow-0 hover:bg-background rounded-sm text-center p-2 compact:h-8 compact:py-1";
if (currentPage === targetPage) {
return <div className={`${button} bg-background`}>{children}</div>;

View file

@ -1,9 +1,12 @@
import { queryOptions } from "@tanstack/react-query";
import type React from "react";
import { useState } from "react";
import {
ReorderableList,
useReorderableList,
} from "@/components/ReorderableList";
import { Button } from "@/components/ui/button";
import { DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { DialogFooter } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { assertNever } from "@/lib/assert-never";
import type {
@ -15,41 +18,6 @@ import { type DialogApi, type DialogContext, showDialog } from "@/lib/dialog";
import { tc, tt } from "@/lib/i18n";
import { queryClient } from "@/lib/query-client";
import { toastError, toastSuccess } from "@/lib/toast";
import { queryOptions } from "@tanstack/react-query";
import type React from "react";
import { useState } from "react";
type State =
| {
type: "normal";
}
| {
type: "enteringRepositoryInfo";
}
| {
type: "loadingRepository";
}
| {
type: "duplicated";
reason: TauriDuplicatedReason;
duplicatedName: string;
}
| {
type: "confirming";
repo: TauriRemoteRepositoryInfo;
url: string;
headers: { [key: string]: string };
};
interface AddRepository {
dialog: React.ReactNode;
openAddDialog: () => void;
inProgress: boolean;
addRepository: (
url: string,
headers: { [p: string]: string },
) => Promise<void>;
}
const environmentRepositoriesInfo = queryOptions({
queryKey: ["environmentRepositoriesInfo"],
@ -188,7 +156,7 @@ function EnteringRepositoryInfo({
return (
<>
<DialogDescription>
<div>
<p className={"font-normal"}>
{tc("vpm repositories:dialog:enter repository info")}
</p>
@ -274,7 +242,7 @@ function EnteringRepositoryInfo({
{tc("vpm repositories:hint:duplicate headers")}
</p>
)}
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -291,16 +259,12 @@ function EnteringRepositoryInfo({
);
}
function LoadingRepository({
cancel,
}: {
cancel: () => void;
}) {
function LoadingRepository({ cancel }: { cancel: () => void }) {
return (
<>
<DialogDescription>
<div>
<p>{tc("vpm repositories:dialog:downloading...")}</p>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={cancel}>{tc("general:button:cancel")}</Button>
</DialogFooter>
@ -339,10 +303,10 @@ function Duplicated({
return (
<>
<DialogDescription>
<div>
<p>{tc("vpm repositories:dialog:already added")}</p>
<p>{message}</p>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close()}>
{tc("general:button:ok")}
@ -364,7 +328,7 @@ function Confirming({
return (
<>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
<DialogDescription className={"max-h-[50vh] overflow-y-auto font-normal"}>
<div className={"max-h-[50vh] overflow-y-auto font-normal"}>
<p className={"font-normal"}>
{tc("vpm repositories:dialog:name", { name: repo.display_name })}
</p>
@ -377,7 +341,7 @@ function Confirming({
{tc("vpm repositories:dialog:headers")}
</p>
<ul className={"list-disc pl-6"}>
{Object.entries(headers).map(([key, value], idx) => (
{Object.entries(headers).map(([key, value]) => (
<li key={key}>
{key}: {value}
</li>
@ -389,11 +353,11 @@ function Confirming({
{tc("vpm repositories:dialog:packages")}
</p>
<ul className={"list-disc pl-6"}>
{repo.packages.map((info, idx) => (
{repo.packages.map((info) => (
<li key={info.name}>{info.display_name ?? info.name}</li>
))}
</ul>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(false)}>
{tc("general:button:cancel")}

View file

@ -1,3 +1,6 @@
import { queryOptions } from "@tanstack/react-query";
import type React from "react";
import { useEffect, useRef, useState } from "react";
import {
Accordion,
AccordionContent,
@ -5,7 +8,7 @@ import {
AccordionTrigger,
} from "@/components/ui/accordion";
import { Button } from "@/components/ui/button";
import { DialogDescription, DialogFooter } from "@/components/ui/dialog";
import { DialogFooter } from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import { assertNever } from "@/lib/assert-never";
import type {
@ -19,10 +22,6 @@ import { tc, tt } from "@/lib/i18n";
import { queryClient } from "@/lib/query-client";
import { toastSuccess } from "@/lib/toast";
import { useEffectEvent } from "@/lib/use-effect-event";
import { queryOptions } from "@tanstack/react-query";
import type React from "react";
import { useEffect, useRef } from "react";
import { useState } from "react";
type ParsedRepositories = {
repositories: TauriRepositoryDescriptor[];
@ -94,7 +93,7 @@ function ConfirmingRepositoryList({
return (
<>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
<DialogDescription className={"max-h-[50vh] overflow-y-auto font-normal"}>
<div className={"max-h-[50vh] overflow-y-auto font-normal"}>
<p className={"font-normal whitespace-normal"}>
{tc("vpm repositories:dialog:confirm repository list")}
</p>
@ -120,7 +119,7 @@ function ConfirmingRepositoryList({
</ul>
</>
)}
</DialogDescription>
</div>
<DialogFooter className={"gap-2"}>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -160,7 +159,7 @@ function LoadingRepositories({
return (
<>
<DialogDescription>
<div>
<p>{tc("vpm repositories:dialog:downloading repositories...")}</p>
<Progress value={downloaded} max={totalCount} />
<div className={"text-center"}>
@ -169,7 +168,7 @@ function LoadingRepositories({
totalCount,
})}
</div>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => cancelRef.current?.()}>
{tc("general:button:cancel")}
@ -197,7 +196,7 @@ function ConfirmingPackages({
return (
<>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
<DialogDescription className={"font-normal"}>
<div className={"font-normal"}>
<p className={"whitespace-normal"}>
{tc("vpm repositories:dialog:confirm packages list")}
</p>
@ -228,7 +227,7 @@ function ConfirmingPackages({
error = false;
content = (
<ul className={"list-disc pl-6"}>
{download.value.packages.map((info, idx) => (
{download.value.packages.map((info) => (
<li key={info.name}>{info.display_name ?? info.name}</li>
))}
</ul>
@ -250,7 +249,7 @@ function ConfirmingPackages({
);
})}
</Accordion>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -265,10 +264,8 @@ function ConfirmingPackages({
function AddingRepositories() {
return (
<>
<DialogDescription>
<p>{tc("vpm repositories:dialog:adding repositories...")}</p>
</DialogDescription>
</>
<div>
<p>{tc("vpm repositories:dialog:adding repositories...")}</p>
</div>
);
}

View file

@ -1,14 +1,48 @@
"use client";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import {
type CollisionDetection,
closestCenter,
DndContext,
type DragEndEvent,
type DragOverEvent,
DragOverlay,
type DragStartEvent,
defaultDropAnimation,
defaultDropAnimationSideEffects,
type Modifier,
PointerSensor,
useSensor,
useSensors,
} from "@dnd-kit/core";
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy,
} from "@dnd-kit/sortable";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, CircleX, GripVertical } from "lucide-react";
import {
Suspense,
useCallback,
useEffect,
useId,
useMemo,
useRef,
useState,
} from "react";
import { HNavBar, VStack } from "@/components/layout";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
@ -28,15 +62,6 @@ import { usePrevPathName } from "@/lib/prev-page";
import { toastThrownError } from "@/lib/toast";
import { useTauriListen } from "@/lib/use-tauri-listen";
import { cn } from "@/lib/utils";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, CircleX } from "lucide-react";
import { Suspense, useCallback, useEffect, useId, useMemo } from "react";
import { HeadingPageName } from "../-tab-selector";
import { addRepository, openAddRepositoryDialog } from "./-use-add-repository";
import { importRepositories } from "./-use-import-repositories";
@ -45,6 +70,8 @@ export const Route = createFileRoute("/_main/packages/repositories/")({
component: Page,
});
type UserRepoWithListId = TauriUserRepository & { listId: string };
function Page() {
return (
<Suspense>
@ -53,11 +80,99 @@ function Page() {
);
}
const restrictToVerticalAxis: Modifier = ({ transform }) => ({
...transform,
x: 0,
});
const DRAG_OVERLAY_MODIFIERS = [restrictToVerticalAxis];
const customDropAnimation: typeof defaultDropAnimation = {
...defaultDropAnimation,
sideEffects: defaultDropAnimationSideEffects({
styles: {
active: { opacity: "0" },
},
}),
};
const TABLE_HEAD = [
"", // checkbox
"general:name",
"vpm repositories:url",
"", // actions
"", // grip handle
] as const;
const environmentRepositoriesInfo = queryOptions({
queryKey: ["environmentRepositoriesInfo"],
queryFn: commands.environmentRepositoriesInfo,
});
// Scrolls the given viewport element when the pointer is near the top or bottom
// edge during drag. dnd-kit's built-in autoscroll is disabled because it causes
// jitter with Radix UI ScrollArea (wrong container detection + double-smoothing).
function useDragAutoScroll(
viewportRef: React.RefObject<HTMLElement | null>,
isActive: boolean,
): void {
useEffect(() => {
if (!isActive) return;
const THRESHOLD = 80; // px from edge to begin scrolling
const MAX_SPEED = 15; // px/frame at the very edge
let pointerY = 0;
const onPointerMove = (e: PointerEvent) => {
pointerY = e.clientY;
};
window.addEventListener("pointermove", onPointerMove, { passive: true });
let rafId: number;
const tick = () => {
const viewport = viewportRef.current;
if (viewport) {
const { top, bottom } = viewport.getBoundingClientRect();
const distFromTop = pointerY - top;
const distFromBottom = bottom - pointerY;
let delta = 0;
if (distFromTop >= 0 && distFromTop < THRESHOLD) {
delta = -MAX_SPEED * (1 - distFromTop / THRESHOLD);
} else if (distFromBottom >= 0 && distFromBottom < THRESHOLD) {
delta = MAX_SPEED * (1 - distFromBottom / THRESHOLD);
}
if (delta !== 0) {
viewport.scrollTo({
top: viewport.scrollTop + delta,
behavior: "instant",
});
}
}
rafId = requestAnimationFrame(tick);
};
rafId = requestAnimationFrame(tick);
return () => {
window.removeEventListener("pointermove", onPointerMove);
cancelAnimationFrame(rafId);
};
}, [isActive, viewportRef]);
}
function computeSlotKey(repo: TauriUserRepository, used: Set<string>): string {
const base = `${repo.id} ${repo.url ?? ""}`;
let key = base;
let counter = 0;
while (used.has(key)) {
counter++;
key = `${base} ${counter}`;
}
used.add(key);
return key;
}
function PageBody() {
const result = useQuery(environmentRepositoriesInfo);
@ -99,140 +214,110 @@ function PageBody() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const bodyAnimation = usePrevPathName().startsWith("/packages")
? "slide-right"
: "";
const guiAnimation = useQuery({
queryKey: ["environmentGuiAnimation"],
queryFn: commands.environmentGuiAnimation,
initialData: true,
}).data;
return (
<VStack>
<HNavBar
className={"shrink-0"}
leading={<HeadingPageName pageType={"/packages/repositories"} />}
trailing={
<DropdownMenu>
<div className={"flex divide-x"}>
<Button
className={"rounded-r-none"}
onClick={() => openAddRepositoryDialog()}
>
{tc("vpm repositories:button:add repository")}
</Button>
<DropdownMenuTrigger
asChild
className={"rounded-l-none pl-2 pr-2"}
>
<Button>
<ChevronDown className={"w-4 h-4"} />
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent>
<DropdownMenuItem
onClick={() => importRepositoriesMutation.mutate()}
>
{tc("vpm repositories:button:import repositories")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => exportRepositories.mutate()}>
{tc("vpm repositories:button:export repositories")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
}
/>
<main
className={`shrink overflow-hidden flex w-full h-full ${bodyAnimation}`}
>
<ScrollableCardTable className={"h-full w-full"}>
<RepositoryTableBody
userRepos={result.data?.user_repositories || []}
hiddenUserRepos={hiddenUserRepos}
/>
</ScrollableCardTable>
</main>
</VStack>
const userRepos = result.data?.user_repositories;
const listIdMapRef = useRef<Map<string, string>>(new Map());
const augmentedUserRepos = useMemo<UserRepoWithListId[]>(() => {
if (!userRepos) {
listIdMapRef.current = new Map();
return [];
}
const prev = listIdMapRef.current;
const next = new Map<string, string>();
const usedKeys = new Set<string>();
const result: UserRepoWithListId[] = [];
for (const r of userRepos) {
const key = computeSlotKey(r, usedKeys);
const listId = prev.get(key) ?? crypto.randomUUID();
next.set(key, listId);
result.push({ ...r, listId });
}
listIdMapRef.current = next;
return result;
}, [userRepos]);
const [orderedListIds, setOrderedListIds] = useState<string[]>(() =>
augmentedUserRepos.map((r) => r.listId),
);
}
function RepositoryTableBody({
userRepos,
hiddenUserRepos,
}: {
userRepos: TauriUserRepository[];
hiddenUserRepos: Set<string>;
}) {
const TABLE_HEAD = [
"", // checkbox
"general:name",
"vpm repositories:url",
"", // actions
];
useEffect(() => {
setOrderedListIds(augmentedUserRepos.map((r) => r.listId));
}, [augmentedUserRepos]);
return (
<>
<thead>
<tr>
{TABLE_HEAD.map((head, index) => (
<th
// biome-ignore lint/suspicious/noArrayIndexKey: static array
key={index}
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground p-2.5"
}
>
<small className="font-normal leading-none">{tc(head)}</small>
</th>
))}
</tr>
</thead>
<tbody>
<RepositoryRow
repoId={"com.vrchat.repos.official"}
url={"https://packages.vrchat.com/official?download"}
displayName={tt("vpm repositories:source:official")}
hiddenUserRepos={hiddenUserRepos}
canRemove={false}
/>
<RepositoryRow
repoId={"com.vrchat.repos.curated"}
url={"https://packages.vrchat.com/curated?download"}
displayName={tt("vpm repositories:source:curated")}
hiddenUserRepos={hiddenUserRepos}
className={"border-b border-primary/10"}
canRemove={false}
/>
{userRepos.map((repo) => (
<RepositoryRow
key={repo.id}
repoId={repo.id}
displayName={repo.display_name}
url={repo.url}
hiddenUserRepos={hiddenUserRepos}
/>
))}
</tbody>
</>
const userRepoByListId = useMemo(
() => new Map(augmentedUserRepos.map((r) => [r.listId, r])),
[augmentedUserRepos],
);
}
function RepositoryRow({
repoId,
displayName,
url,
hiddenUserRepos,
className,
canRemove = true,
}: {
repoId: TauriUserRepository["id"];
displayName: TauriUserRepository["display_name"];
url: TauriUserRepository["url"];
hiddenUserRepos: Set<string>;
className?: string;
canRemove?: boolean;
}) {
const cellClass = "p-2.5";
const id = useId();
const userRepoByListIdRef =
useRef<Map<string, UserRepoWithListId>>(userRepoByListId);
useEffect(() => {
userRepoByListIdRef.current = userRepoByListId;
}, [userRepoByListId]);
const [activeId, setActiveId] = useState<string | null>(null);
const [overId, setOverId] = useState<string | null>(null);
const [columnWidths, setColumnWidths] = useState<number[]>([]);
const theadRowRef = useRef<HTMLTableRowElement>(null);
const scrollViewportRef = useRef<HTMLDivElement>(null);
const sensors = useSensors(useSensor(PointerSensor));
const orderedListIdsSet = useMemo(
() => new Set(orderedListIds),
[orderedListIds],
);
const collisionDetection = useCallback<CollisionDetection>(
(args) =>
closestCenter({
...args,
droppableContainers: args.droppableContainers.filter((c) =>
orderedListIdsSet.has(c.id as string),
),
}),
[orderedListIdsSet],
);
const queryClient = useQueryClient();
const reorderMutation = useMutation({
mutationFn: (listIds: string[]) => {
const repos = listIds
.map((lid) => userRepoByListId.get(lid))
.filter((r): r is UserRepoWithListId => r !== undefined)
.map((r) => ({ index: r.index, id: r.id }));
return commands.environmentReorderRepositories(repos);
},
// Pin listIds to the new positions so duplicate-keyed rows don't swap their listIds on refetch.
onMutate: (newListIds: string[]) => {
const prevMap = new Map(listIdMapRef.current);
const rebuilt = new Map<string, string>();
const usedKeys = new Set<string>();
for (const lid of newListIds) {
const repo = userRepoByListIdRef.current.get(lid);
if (!repo) continue;
const key = computeSlotKey(repo, usedKeys);
rebuilt.set(key, lid);
}
listIdMapRef.current = rebuilt;
return { prevMap };
},
onSettled: () => queryClient.invalidateQueries(environmentRepositoriesInfo),
onError: (e, _newListIds, ctx) => {
if (ctx?.prevMap) listIdMapRef.current = ctx.prevMap;
toastThrownError(e);
},
});
const setHideRepository = useMutation({
mutationFn: async ({ id, shown }: { id: string; shown: boolean }) => {
if (shown) {
@ -277,68 +362,483 @@ function RepositoryRow({
},
});
const activeVisualIndex = useMemo(() => {
if (!activeId) return 0;
const effectiveId = overId ?? activeId;
return orderedListIds.indexOf(effectiveId) + 2; // +2 for the 2 fixed rows
}, [activeId, overId, orderedListIds]);
function handleDragStart(event: DragStartEvent) {
setActiveId(event.active.id as string);
if (theadRowRef.current) {
const widths = Array.from(
theadRowRef.current.querySelectorAll("th"),
(th) => th.getBoundingClientRect().width,
);
setColumnWidths(widths);
}
}
function handleDragOver(event: DragOverEvent) {
setOverId((event.over?.id as string | null) ?? null);
}
function handleDragEnd(event: DragEndEvent) {
setActiveId(null);
setOverId(null);
const { active, over } = event;
if (over && active.id !== over.id) {
const oldIndex = orderedListIds.indexOf(active.id as string);
const newIndex = orderedListIds.indexOf(over.id as string);
const newListIds = arrayMove(orderedListIds, oldIndex, newIndex);
setOrderedListIds(newListIds);
reorderMutation.mutate(newListIds);
}
}
function handleDragCancel() {
setActiveId(null);
setOverId(null);
}
useDragAutoScroll(scrollViewportRef, activeId !== null);
const bodyAnimation = usePrevPathName().startsWith("/packages")
? "slide-right"
: "";
return (
<DndContext
sensors={sensors}
collisionDetection={collisionDetection}
autoScroll={false}
onDragStart={handleDragStart}
onDragOver={handleDragOver}
onDragEnd={handleDragEnd}
onDragCancel={handleDragCancel}
>
<VStack>
<div style={activeId !== null ? { pointerEvents: "none" } : undefined}>
<HNavBar
className="shrink-0"
leading={<HeadingPageName pageType={"/packages/repositories"} />}
trailing={
<DropdownMenu>
<div className={"flex divide-x"}>
<Button
className={"rounded-r-none compact:h-10"}
onClick={() => openAddRepositoryDialog()}
>
{tc("vpm repositories:button:add repository")}
</Button>
<DropdownMenuTrigger
asChild
className={"rounded-l-none pl-2 pr-2 compact:h-10"}
>
<Button>
<ChevronDown className={"w-4 h-4"} />
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent>
<DropdownMenuItem
onClick={() => importRepositoriesMutation.mutate()}
>
{tc("vpm repositories:button:import repositories")}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => exportRepositories.mutate()}>
{tc("vpm repositories:button:export repositories")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
}
/>
</div>
<main
className={`shrink overflow-hidden flex w-full h-full ${bodyAnimation}`}
>
<ScrollableCardTable
className={"h-full w-full"}
viewportRef={scrollViewportRef}
>
<RepositoryTableBody
orderedListIds={orderedListIds}
userRepoByListId={userRepoByListId}
hiddenUserRepos={hiddenUserRepos}
theadRowRef={theadRowRef}
guiAnimation={guiAnimation}
onToggleVisibility={(id, shown) =>
setHideRepository.mutate({ id, shown })
}
isDragActive={activeId !== null}
/>
</ScrollableCardTable>
</main>
</VStack>
<DragOverlay
modifiers={DRAG_OVERLAY_MODIFIERS}
dropAnimation={guiAnimation ? customDropAnimation : null}
>
{activeId ? (
<RepositoryDragOverlay
repo={userRepoByListId.get(activeId)}
selected={
!hiddenUserRepos.has(userRepoByListId.get(activeId)?.id ?? "")
}
columnWidths={columnWidths}
visualIndex={activeVisualIndex}
guiAnimation={guiAnimation}
/>
) : null}
</DragOverlay>
</DndContext>
);
}
function RepositoryTableBody({
orderedListIds,
userRepoByListId,
hiddenUserRepos,
theadRowRef,
guiAnimation,
onToggleVisibility,
isDragActive,
}: {
orderedListIds: string[];
userRepoByListId: Map<string, UserRepoWithListId>;
hiddenUserRepos: Set<string>;
theadRowRef: React.RefObject<HTMLTableRowElement | null>;
guiAnimation: boolean;
onToggleVisibility: (id: string, shown: boolean) => void;
isDragActive: boolean;
}) {
return (
<>
<thead>
<tr ref={theadRowRef}>
{TABLE_HEAD.map((head, index) => (
<th
// biome-ignore lint/suspicious/noArrayIndexKey: static array
key={index}
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5"
}
>
<small className="font-normal leading-none">{tc(head)}</small>
</th>
))}
</tr>
</thead>
<tbody>
<RepositoryRow
repoId={"com.vrchat.repos.official"}
url={"https://packages.vrchat.com/official?download"}
displayName={tt("vpm repositories:source:official")}
hiddenUserRepos={hiddenUserRepos}
canRemove={false}
rowIndex={0}
guiAnimation={guiAnimation}
onToggleVisibility={onToggleVisibility}
isDragActive={isDragActive}
/>
<RepositoryRow
repoId={"com.vrchat.repos.curated"}
url={"https://packages.vrchat.com/curated?download"}
displayName={tt("vpm repositories:source:curated")}
hiddenUserRepos={hiddenUserRepos}
className={"border-b border-primary/10"}
canRemove={false}
rowIndex={1}
guiAnimation={guiAnimation}
onToggleVisibility={onToggleVisibility}
isDragActive={isDragActive}
/>
<SortableContext
items={orderedListIds}
strategy={verticalListSortingStrategy}
>
{orderedListIds.map((listId, index) => {
const repo = userRepoByListId.get(listId);
if (!repo) return null;
return (
<RepositoryRow
key={listId}
listId={listId}
repoId={repo.id}
repoIndex={repo.index}
displayName={repo.display_name}
url={repo.url}
hiddenUserRepos={hiddenUserRepos}
rowIndex={2 + index}
guiAnimation={guiAnimation}
onToggleVisibility={onToggleVisibility}
isDragActive={isDragActive}
/>
);
})}
</SortableContext>
</tbody>
</>
);
}
const CELL_CLASS = "p-2.5 compact:py-1 align-middle";
function RepositoryRowCells({
labelId,
displayName,
url,
canRemove,
selected,
onCheckedChange,
onRemove,
dragListeners,
dragAttributes,
}: {
labelId?: string;
displayName: string;
url: string | null | undefined;
canRemove: boolean;
selected: boolean;
onCheckedChange?: (shown: boolean) => void;
onRemove?: () => void;
dragListeners?: ReturnType<typeof useSortable>["listeners"];
dragAttributes?: ReturnType<typeof useSortable>["attributes"];
}) {
const interactive = onCheckedChange !== undefined;
return (
<>
<td className={CELL_CLASS}>
{interactive ? (
<div className="flex">
<Checkbox
id={labelId}
checked={selected}
onCheckedChange={(x) => onCheckedChange(x === true)}
/>
</div>
) : (
<div className="pointer-events-none flex">
<Checkbox checked={selected} />
</div>
)}
</td>
<td className={CELL_CLASS}>
{interactive ? (
<label htmlFor={labelId}>
<p className="font-normal">{displayName}</p>
</label>
) : (
<p className="font-normal">{displayName}</p>
)}
</td>
<td className={CELL_CLASS}>
<p className="font-normal">{url}</p>
</td>
<td className={`${CELL_CLASS} w-0`}>
{interactive ? (
<Tooltip>
<TooltipTrigger asChild={canRemove}>
<Button
disabled={!canRemove}
onClick={onRemove}
variant={"ghost"}
size={"icon"}
>
<CircleX className={"size-5 text-destructive"} />
</Button>
</TooltipTrigger>
<TooltipContent>
{canRemove
? tc("vpm repositories:remove repository")
: tc(
"vpm repositories:tooltip:remove curated or official repository",
)}
</TooltipContent>
</Tooltip>
) : (
<Button variant={"ghost"} size={"icon"} disabled>
<CircleX className={"size-5 text-destructive"} />
</Button>
)}
</td>
<td
className={cn(
CELL_CLASS,
"w-0",
canRemove ? "cursor-move" : "cursor-not-allowed",
)}
{...(canRemove ? dragListeners : undefined)}
{...(canRemove ? dragAttributes : undefined)}
>
<GripVertical
className={cn(
"size-5 text-muted-foreground",
!canRemove && "opacity-50",
)}
/>
</td>
</>
);
}
function RepositoryRow({
listId,
repoId,
repoIndex,
displayName,
url,
hiddenUserRepos,
className,
canRemove = true,
rowIndex,
guiAnimation,
onToggleVisibility,
isDragActive,
}: {
listId?: string;
repoId: TauriUserRepository["id"];
repoIndex?: number;
displayName: TauriUserRepository["display_name"];
url: TauriUserRepository["url"];
hiddenUserRepos: Set<string>;
className?: string;
canRemove?: boolean;
rowIndex: number;
guiAnimation: boolean;
onToggleVisibility: (id: string, shown: boolean) => void;
isDragActive: boolean;
}) {
const labelId = useId();
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({ id: listId ?? repoId, disabled: !canRemove });
const visualIndex = useMemo(() => {
if (isDragging) return rowIndex;
const dy = transform?.y ?? 0;
if (dy < 0) return rowIndex - 1;
if (dy > 0) return rowIndex + 1;
return rowIndex;
}, [rowIndex, transform?.y, isDragging]);
const dragStyle = useMemo<React.CSSProperties>(
() => ({
transform: transform ? `translateY(${transform.y}px)` : undefined,
transition: guiAnimation
? [transition, isDragActive ? undefined : "background-color 200ms ease"]
.filter(Boolean)
.join(", ") || undefined
: undefined,
opacity: isDragging ? 0 : 1,
position: "relative",
}),
[transform, transition, isDragging, guiAnimation, isDragActive],
);
const selected = !hiddenUserRepos.has(repoId);
return (
<tr className={cn("even:bg-secondary/30", className)}>
<td className={cellClass}>
<Checkbox
id={id}
checked={selected}
onCheckedChange={(x) =>
setHideRepository.mutate({ id: repoId, shown: x === true })
}
/>
</td>
<td className={cellClass}>
<label htmlFor={id}>
<p className="font-normal">{displayName}</p>
</label>
</td>
<td className={cellClass}>
<p className="font-normal">{url}</p>
</td>
<td className={`${cellClass} w-0`}>
<Tooltip>
<TooltipTrigger asChild={canRemove}>
<Button
disabled={!canRemove}
onClick={() => {
void openSingleDialog(RemoveRepositoryDialog, {
displayName,
id: repoId,
});
}}
variant={"ghost"}
size={"icon"}
>
<CircleX className={"size-5 text-destructive"} />
</Button>
</TooltipTrigger>
<TooltipContent>
{canRemove
? tc("vpm repositories:remove repository")
: tc(
"vpm repositories:tooltip:remove curated or official repository",
)}
</TooltipContent>
</Tooltip>
</td>
<tr
ref={setNodeRef}
style={dragStyle}
className={cn(visualIndex % 2 === 1 ? "bg-secondary/30" : "", className)}
>
<RepositoryRowCells
labelId={labelId}
displayName={displayName}
url={url}
canRemove={canRemove}
selected={selected}
onCheckedChange={(shown) => onToggleVisibility(repoId, shown)}
onRemove={() =>
void openSingleDialog(RemoveRepositoryDialog, {
displayName,
index: repoIndex ?? 0,
id: repoId,
})
}
dragListeners={listeners}
dragAttributes={attributes}
/>
</tr>
);
}
function RepositoryDragOverlay({
repo,
selected,
columnWidths,
visualIndex,
guiAnimation,
}: {
repo: TauriUserRepository | undefined;
selected: boolean;
columnWidths: number[];
visualIndex: number;
guiAnimation: boolean;
}) {
const style = useMemo<React.CSSProperties>(
() => ({
transition: guiAnimation ? "background-color 200ms ease" : undefined,
}),
[guiAnimation],
);
if (!repo) return null;
return (
<table
className={cn(
"w-full table-fixed text-left",
visualIndex % 2 === 1 ? "bg-secondary/30" : "",
)}
style={style}
>
{columnWidths.length > 0 && (
<colgroup>
{columnWidths.map((w, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: fixed column order
<col key={i} style={{ width: w }} />
))}
</colgroup>
)}
<tbody>
<tr>
<RepositoryRowCells
displayName={repo.display_name}
url={repo.url}
canRemove={true}
selected={selected}
/>
</tr>
</tbody>
</table>
);
}
function RemoveRepositoryDialog({
dialog,
displayName,
index,
id,
}: { dialog: DialogContext<void>; displayName: string; id: string }) {
}: {
dialog: DialogContext<void>;
displayName: string;
index: number;
id: string;
}) {
const queryClient = useQueryClient();
const removeRepository = useMutation({
mutationFn: async (id: string) =>
await commands.environmentRemoveRepository(id),
onMutate: async (id) => {
mutationFn: async (args: { index: number; id: string }) =>
await commands.environmentRemoveRepository(args.index, args.id),
onMutate: async ({ index }) => {
await queryClient.cancelQueries(environmentRepositoriesInfo);
const data = queryClient.getQueryData(
environmentRepositoriesInfo.queryKey,
@ -346,22 +846,30 @@ function RemoveRepositoryDialog({
if (data !== undefined) {
queryClient.setQueryData(environmentRepositoriesInfo.queryKey, {
...data,
user_repositories: data.user_repositories.filter((x) => x.id !== id),
user_repositories: data.user_repositories.filter(
(x) => x.index !== index,
),
});
}
return data;
},
onError: (e, _args, ctx) => {
queryClient.setQueryData(environmentRepositoriesInfo.queryKey, ctx);
toastThrownError(e);
},
onSettled: () => queryClient.invalidateQueries(environmentRepositoriesInfo),
});
return (
<>
<DialogTitle>{tc("vpm repositories:remove repository")}</DialogTitle>
<DialogDescription>
<div>
<p className={"whitespace-normal font-normal"}>
{tc("vpm repositories:dialog:confirm remove description", {
name: displayName,
})}
</p>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close()}>
{tc("general:button:cancel")}
@ -369,7 +877,7 @@ function RemoveRepositoryDialog({
<Button
onClick={() => {
dialog.close();
removeRepository.mutate(id);
removeRepository.mutate({ index, id });
}}
className={"ml-2"}
>

View file

@ -1,18 +1,33 @@
import Loading from "@/app/-loading";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
useSuspenseQuery,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, CircleX, Ellipsis, Star } from "lucide-react";
import type React from "react";
import { Suspense, useId, useMemo, useState } from "react";
import { HeadingPageName } from "@/app/_main/packages/-tab-selector";
import Loading from "@/app/-loading";
import { FilePathRow } from "@/components/common-setting-parts";
import { FavoriteStarToggleButton } from "@/components/FavoriteStarButton";
import { HNavBar, VStack } from "@/components/layout";
import { Overlay } from "@/components/Overlay";
import {
ReorderableList,
type ReorderableListId,
useReorderableList,
} from "@/components/ReorderableList";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { HNavBar, VStack } from "@/components/layout";
import { Button } from "@/components/ui/button";
import { TemplateSelect } from "@/components/TemplateSelect";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
type AutoCompleteOption,
Autocomplete,
} from "@/components/ui/autocomplete";
import { Button } from "@/components/ui/button";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
@ -20,45 +35,32 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { assertNever } from "@/lib/assert-never";
import {
commands,
type TauriAlcomTemplate,
type TauriProjectTemplateInfo,
commands,
type TauriVersion,
} from "@/lib/bindings";
import { dateToString, formatDateOffset } from "@/lib/dateToString";
import { type DialogContext, openSingleDialog } from "@/lib/dialog";
import { tc } from "@/lib/i18n";
import { tc, tt } from "@/lib/i18n";
import { processResult } from "@/lib/import-templates";
import { usePrevPathName } from "@/lib/prev-page";
import {
type ProjectTemplateCategory,
projectTemplateCategory,
projectTemplateDisplayId,
projectTemplateName,
} from "@/lib/project-template";
import { toastSuccess, toastThrownError } from "@/lib/toast";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { cn } from "@/lib/utils";
import {
queryOptions,
useQuery,
useQueryClient,
useSuspenseQuery,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, CircleX, Ellipsis } from "lucide-react";
import type React from "react";
import { Suspense, useId, useState } from "react";
import { compareVersion } from "@/lib/version";
export const Route = createFileRoute("/_main/packages/templates/")({
component: RouteComponent,
@ -81,15 +83,15 @@ function RouteComponent() {
return (
<VStack>
<HNavBar
className={"shrink-0"}
className="shrink-0"
leading={<HeadingPageName pageType={"/packages/templates"} />}
trailing={
<DropdownMenu>
<div className={"flex divide-x"}>
<CreateTemplateButton className={"rounded-r-none"} />
<CreateTemplateButton className={"rounded-r-none compact:h-10"} />
<DropdownMenuTrigger
asChild
className={"rounded-l-none pl-2 pr-2"}
className={"rounded-l-none pl-2 pr-2 compact:h-10"}
>
<Button>
<ChevronDown className={"w-4 h-4"} />
@ -139,6 +141,7 @@ function TemplatesTableBody() {
await openSingleDialog(TemplateEditor, {
templates: information.data.templates,
template: { ...alcomTemplate, id },
favoriteTemplates: information.data.favorite_templates,
});
} catch (e) {
console.error(e);
@ -161,16 +164,45 @@ function TemplatesTableBody() {
}
};
const templatesOrdered = useMemo(() => {
const perCategoryFav: {
[K in `${boolean}-${ProjectTemplateCategory}`]: TauriProjectTemplateInfo[];
} = {
"true-builtin": [],
"false-builtin": [],
"true-alcom": [],
"false-alcom": [],
"true-vcc": [],
"false-vcc": [],
};
for (const template of information.data.templates) {
const category = projectTemplateCategory(template.id);
const favorite = information.data.favorite_templates.includes(
template.id,
);
perCategoryFav[`${favorite}-${category}`].push(template);
}
return (["builtin", "alcom", "vcc"] as const).flatMap((category) => [
...perCategoryFav[`true-${category}`],
...perCategoryFav[`false-${category}`],
]);
}, [information.data.templates, information.data.favorite_templates]);
return (
<>
<thead>
<tr>
<th
className={`sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5`}
>
<Star className={"size-4"} />
</th>
{TABLE_HEAD.map((head, index) => (
<th
// biome-ignore lint/suspicious/noArrayIndexKey: static array
key={index}
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground p-2.5"
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5"
}
>
<small className="font-normal leading-none">{tc(head)}</small>
@ -179,12 +211,13 @@ function TemplatesTableBody() {
</tr>
</thead>
<tbody>
{information.data.templates.map((template) => (
{templatesOrdered.map((template) => (
<TemplateRow
key={template.id}
template={template}
remove={removeTemplate}
edit={editTemplate}
favorite={information.data.favorite_templates.includes(template.id)}
/>
))}
</tbody>
@ -196,12 +229,14 @@ function TemplateRow({
template,
remove,
edit,
favorite,
}: {
template: TauriProjectTemplateInfo;
remove?: (id: string) => void;
edit?: (id: string) => void;
favorite: boolean;
}) {
const cellClass = "p-2.5";
const cellClass = "p-2.5 compact:py-1";
const id = useId();
const category = projectTemplateCategory(template.id);
@ -218,8 +253,64 @@ function TemplateRow({
}
};
const queryClient = useQueryClient();
const setTemplateFavorite = useMutation({
mutationFn: (params: { id: string; favorite: boolean }) =>
commands.environmentSetTemplateFavorite(params.id, params.favorite),
onMutate: async (params) => {
await queryClient.cancelQueries(environmentProjectCreationInformation);
const previousData = queryClient.getQueryData(
environmentProjectCreationInformation.queryKey,
);
if (previousData !== undefined) {
queryClient.setQueryData(
environmentProjectCreationInformation.queryKey,
{
...previousData,
favorite_templates: params.favorite
? previousData.favorite_templates.includes(params.id)
? previousData.favorite_templates
: [...previousData.favorite_templates, params.id]
: previousData.favorite_templates.filter((x) => x !== params.id),
},
);
}
return previousData;
},
onError: (error, _, context) => {
console.error("Error favoriting project", error);
toastThrownError(error);
if (context) {
queryClient.setQueryData(
environmentProjectCreationInformation.queryKey,
context,
);
}
},
});
return (
<tr className="even:bg-secondary/30">
<tr className="even:bg-secondary/30 group">
<td className={`${cellClass} w-3`}>
<div className={"relative flex"}>
<FavoriteStarToggleButton
favorite={favorite}
disabled={category === "vcc"}
onToggle={() =>
setTemplateFavorite.mutate({
id: template.id,
favorite: !favorite,
})
}
/>
</div>
</td>
<td className={`${cellClass} w-full`}>
<label htmlFor={id}>
<p className="font-normal">{projectTemplateName(template)}</p>
@ -286,13 +377,16 @@ function TemplateRow({
function RemoveTemplateConfirmDialog({
dialog,
displayName,
}: { dialog: DialogContext<boolean>; displayName: string }) {
}: {
dialog: DialogContext<boolean>;
displayName: string;
}) {
return (
<>
<DialogTitle>{tc("templates:dialog:remove template")}</DialogTitle>
<DialogDescription>
<div>
{tc("templates:dialog:confirm remove template", { displayName })}
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(false)}>
{tc("general:button:cancel")}
@ -413,6 +507,7 @@ function CreateTemplateButton({ className }: { className: string }) {
void openSingleDialog(TemplateEditor, {
templates: information.data.templates,
template: null,
favoriteTemplates: information.data.favorite_templates,
});
}
}}
@ -428,18 +523,25 @@ const prereleaseSegment = regexp`(?:0|[1-9]\d*|[0-9a-z-]*[a-z-][0-9a-z-]*)`;
const prerelease = regexp`(?:-?${prereleaseSegment}(?:\.${prereleaseSegment})*)`;
const buildSegment = regexp`(?:[0-9a-z-]+)`;
const build = regexp`(?:${buildSegment}(?:\.${buildSegment})*)`;
const rangeRegex = new RegExp(
const packageRangeRegex = new RegExp(
regexp`^\s*(?:(?:>|<|>=|<=|=|\^|~)\s*)?v?${versionSegment}(?:\.${versionSegment}(?:\.${versionSegment}${prerelease}?${build}?)?)?\s*$`,
"i",
);
// Currently, the unity version channel part and increment part is ignored and not allowed to include
const unityRangeRegex = new RegExp(
regexp`^\s*(?:(?:>|<|>=|<=|=|\^|~)\s*)?v?${versionSegment}(?:\.${versionSegment}(?:\.${versionSegment})?)?\s*$`,
"i",
);
function TemplateEditor({
templates,
template,
favoriteTemplates,
dialog,
}: {
templates: TauriProjectTemplateInfo[];
template: (TauriAlcomTemplate & { id: string }) | null;
favoriteTemplates: string[];
dialog: DialogContext<boolean>;
}) {
const [baseTemplate, setBaseTemplate] = useState<string>(
@ -448,6 +550,183 @@ function TemplateEditor({
const [name, setName] = useState(template?.display_name ?? "");
const [unityRange, setUnityRange] = useState(template?.unity_version ?? "");
const allPackages = useQuery({
queryKey: ["environmentPackages"],
queryFn: () => commands.environmentPackages(),
});
const { packageCandidates, versionCandidatePerPackage } = useMemo(() => {
type PackageInfo = {
dataSourceVersion: TauriVersion;
displayName: string | null;
keywords: string[];
versions: TauriVersion[];
};
const packages = new Map<string, PackageInfo>();
for (const pkg of allPackages.data ?? []) {
if (pkg.is_yanked) continue;
let rowInfo = packages.get(pkg.name);
if (
rowInfo == null ||
compareVersion(pkg.version, rowInfo.dataSourceVersion) > 0
) {
packages.set(
pkg.name,
(rowInfo = {
dataSourceVersion: pkg.version,
displayName: pkg.display_name,
keywords: pkg.keywords,
versions: rowInfo?.versions ?? [],
}),
);
}
rowInfo.versions.push(pkg.version);
}
return {
packageCandidates: Array.from(packages.entries()).map(
([id, pkg]) =>
({
value: id,
label: (
<AutocompletePackageLabel displayName={pkg.displayName} id={id} />
),
keywords: [pkg.displayName, ...pkg.keywords].filter(
(x) => x != null,
),
}) satisfies AutoCompleteOption,
),
versionCandidatePerPackage: new Map(
Array.from(packages.entries()).map(([id, pkg]) => {
// we generate few candidates for version per package
// - '*' for any version
// - '>=latestStable' and '>=latestPrerelease'
// - '^latestStable' and '^latestPrerelease'
// - '1.x' '1.2.x' (or something like this) for stable release
const latestStable = pkg.versions
.filter((x) => x.pre === "")
.sort(compareVersion)
.at(-1);
const latestPrerelease = pkg.versions.sort(compareVersion).at(-1);
const candidates: AutoCompleteOption[] = [];
function addCandidate(value: string, description: React.ReactNode) {
candidates.push({
value,
label: (
<AutocompleteVersionLabel
value={value}
description={description}
/>
),
});
}
addCandidate("*", tc("templates:dialog:any version"));
if (latestStable != null) {
addCandidate(
`${latestStable.major}.x`,
`${latestStable.major}.0.0 ≤ v < ${latestStable.major + 1}.0.0`,
);
addCandidate(
`${latestStable.major}.${latestStable.minor}.x`,
`${latestStable.major}.${latestStable.minor}.0 ≤ v < ${latestStable.major}.${latestStable.minor + 1}.0`,
);
addCandidate(
`${latestStable.major}.${latestStable.minor}.${latestStable.patch}`,
`v = ${latestStable.major}.${latestStable.minor}.${latestStable.patch}`,
);
addCandidate(
`>=${latestStable.major}.${latestStable.minor}.${latestStable.patch}`,
`v ≥ ${latestStable.major}.${latestStable.minor}.${latestStable.patch}`,
);
addCandidate(
`^${latestStable.major}.${latestStable.minor}.${latestStable.patch}`,
`${latestStable.major}.${latestStable.minor}.${latestStable.patch} ≤ v < ${hatEndVersion(latestStable)}`,
);
}
if (latestPrerelease != null && latestPrerelease !== latestStable) {
addCandidate(
`${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre}`,
`v = ${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre}`,
);
addCandidate(
`>=${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre}`,
`v ≥ ${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre}`,
);
addCandidate(
`^${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre}`,
`${latestPrerelease.major}.${latestPrerelease.minor}.${latestPrerelease.patch}-${latestPrerelease.pre} ≤ v < ${hatEndVersion(latestPrerelease)}`,
);
}
function hatEndVersion(version: TauriVersion): string {
return version.major === 0 && version.minor === 0
? `${version.major}.${version.minor}.${version.patch + 1}`
: version.major === 0
? `${version.major}.${version.minor + 1}.0`
: `${version.major + 1}.0.0`;
}
return [id, candidates];
}),
),
};
}, [allPackages.data]);
const unityCandidates = useMemo(() => {
const templateInfo = templates.find((x) => x.id === baseTemplate);
if (templateInfo == null) return [];
// unityVersions is in order
// currently, ignore the unity version channel part and increment part
const unityVersions = templateInfo.unity_versions.map(
(x) => x.split(/[^\d.]/, 2)[0],
);
const candidates: AutoCompleteOption[] = [];
function addCandidate(value: string, description: React.ReactNode) {
candidates.push({
value,
label: (
<AutocompleteVersionLabel value={value} description={description} />
),
});
}
candidates.push(...unityVersions);
addCandidate("*", tc("templates:dialog:any version"));
// create something like 2022.x and 2022.3.x
const addedRange = new Set<string>();
for (const unityVersion of unityVersions) {
const majorOnly = unityVersion.match(/^\d+/)?.[0];
const minor = unityVersion.match(/^\d+\.\d+/)?.[0];
if (majorOnly && !addedRange.has(majorOnly)) {
addedRange.add(majorOnly);
addCandidate(
`${majorOnly}.x`,
tc("templates:dialog:any unity specified version", {
version: majorOnly,
}),
);
}
if (minor && !addedRange.has(minor)) {
addedRange.add(minor);
addCandidate(
`${minor}.x`,
tc("templates:dialog:any unity specified version", {
version: minor,
}),
);
}
}
return candidates;
}, [templates, baseTemplate]);
type Package = { name: string; range: string };
const packagesListContext = useReorderableList<Package>({
defaultValue: { name: "", range: "" },
@ -462,6 +741,11 @@ function TemplateEditor({
reorderable: false,
});
const addedPackageNames = useMemo(
() => new Set(packagesListContext.value.map((p) => p.name)),
[packagesListContext.value],
);
const unityPackagesListContext = useReorderableList<string>({
defaultValue: "",
defaultArray: template?.unity_packages ?? [],
@ -472,7 +756,7 @@ function TemplateEditor({
const addUnityPackages = async () => {
try {
const packages = await commands.environmentPickUnityPackage();
const packages = await commands.environmentPickUnityPackages();
for (const pkg of packages) {
unityPackagesListContext.add(pkg);
}
@ -482,6 +766,31 @@ function TemplateEditor({
}
};
const pickUnityPackage = async (
currentValue: string,
currentId: ReorderableListId,
) => {
try {
const result = await commands.environmentPickUnityPackage(currentValue);
switch (result.type) {
case "NoFolderSelected":
// no-op
break;
case "InvalidSelection":
toastError(tt("general:toast:invalid file"));
break;
case "Successful":
unityPackagesListContext.update(currentId, result.new_path);
break;
default:
assertNever(result);
}
} catch (e) {
console.error(e);
toastThrownError(e);
}
};
const queryClient = useQueryClient();
const saveTemplate = async () => {
try {
@ -507,10 +816,10 @@ function TemplateEditor({
const validVersion = (p: Package) =>
(p.name === "" && p.range === "") || // the empty (non-set) row
(p.name !== "" && p.range.match(rangeRegex)); // ready to create
(p.name !== "" && p.range.match(packageRangeRegex)); // ready to create
const readyToCreate =
packagesListContext.value.every(validVersion) &&
unityRange.match(rangeRegex) &&
unityRange.match(unityRangeRegex) &&
name.length !== 0;
return (
@ -520,182 +829,170 @@ function TemplateEditor({
? tc("templates:dialog:edit template")
: tc("templates:dialog:create template")}
</DialogTitle>
<DialogDescription asChild>
<div className={"flex flex-col gap-4 shrink min-h-0"}>
<section>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("templates:dialog:general information")}
</h3>
<table
className={"grid grid-cols-[min-content_1fr] gap-x-4 gap-y-1"}
>
<tbody className={"contents"}>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("general:name")}:
</th>
<td className={"flex"}>
<Input
className={cn(
"grow",
name.length === 0 &&
"border-destructive ring-destructive text-destructive",
)}
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={"Your New Template"}
/>
</td>
</tr>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("templates:dialog:base template")}:
</th>
<td className={"flex"}>
<Select
value={baseTemplate}
onValueChange={setBaseTemplate}
>
<SelectTrigger>
<SelectValue className={"grow"} />
</SelectTrigger>
<SelectContent>
{templates.map((template) => {
const id = projectTemplateDisplayId(template.id);
if (id == null) return null;
return (
<SelectItem key={id} value={id}>
{projectTemplateName(template)}
</SelectItem>
);
})}
</SelectContent>
</Select>
</td>
</tr>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("templates:dialog:unity version")}:
</th>
<td className={"flex"}>
<Input
className={cn(
"grow",
unityRange.match(rangeRegex) ||
"border-destructive ring-destructive text-destructive",
)}
value={unityRange}
onChange={(e) => setUnityRange(e.target.value)}
placeholder={">=2022 * =2022.3.22"}
/>
</td>
</tr>
</tbody>
</table>
</section>
<section className={"shrink overflow-hidden flex flex-col"}>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("general:packages")}
</h3>
<div className={"w-full max-h-[30vh] overflow-y-auto shrink"}>
<table className={"w-full"}>
<thead>
<tr>
<th className={"sticky top-0 z-10 bg-background"}>
{tc("general:name")}
</th>
<th className={"sticky top-0 z-10 bg-background"}>
{tc("general:version")}
</th>
<th className={"sticky top-0 z-10 bg-background"} />
</tr>
</thead>
<tbody>
<ReorderableList
context={packagesListContext}
renderItem={(value, id) => (
<>
<td>
<div className={"flex"}>
<Input
type={"text"}
value={value.name}
className={"grow"}
onChange={(e) =>
packagesListContext.update(id, (old) => ({
...old,
name: e.target.value,
}))
}
/>
</div>
</td>
<td>
<div className={"flex"}>
<Input
type={"text"}
value={value.range}
className={cn(
"grow",
validVersion(value) ||
"border-destructive ring-destructive text-destructive",
)}
onChange={(e) =>
packagesListContext.update(id, (old) => ({
...old,
range: e.target.value,
}))
}
/>
</div>
</td>
</>
<div className={"flex flex-col gap-4 shrink min-h-0"}>
<section>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("templates:dialog:general information")}
</h3>
<table className={"grid grid-cols-[min-content_1fr] gap-x-4 gap-y-1"}>
<tbody className={"contents"}>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("general:name")}:
</th>
<td className={"flex"}>
<Input
className={cn(
"grow",
name.length === 0 &&
"border-destructive ring-destructive text-destructive",
)}
value={name}
onChange={(e) => setName(e.target.value)}
placeholder={"Your New Template"}
/>
</tbody>
</table>
</div>
</section>
<section className={"shrink overflow-hidden flex flex-col"}>
<Overlay>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("templates:dialog:unitypackages")}
</h3>
<div className={"text-right mb-2"}>
<Button onClick={addUnityPackages}>
{tc("general:button:add")}
</Button>
</div>
</Overlay>
<div className={"w-full max-h-[30vh] overflow-y-auto shrink"}>
<table className={"w-full"}>
<tbody>
<ReorderableList
context={unityPackagesListContext}
ifEmpty={() => (
<td className={"text-center"}>
{tc("templates:dialog:no unitypackages")}
</td>
</td>
</tr>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("templates:dialog:base template")}:
</th>
<td className={"flex"}>
<TemplateSelect
value={baseTemplate}
onValueChange={setBaseTemplate}
templates={templates}
favoriteTemplates={favoriteTemplates}
className={"grow"}
excludeNoIdTemplates
/>
</td>
</tr>
<tr className={"contents"}>
<th className={"content-center text-start whitespace-nowrap"}>
{tc("templates:dialog:unity version")}:
</th>
<td className={"flex"}>
<Autocomplete
className={cn(
"grow",
unityRange.match(unityRangeRegex) ||
"border-destructive ring-destructive text-destructive",
)}
renderItem={(value) => (
value={unityRange}
onChange={(value) => setUnityRange(value)}
options={unityCandidates}
/>
</td>
</tr>
</tbody>
</table>
</section>
<section className={"shrink overflow-hidden flex flex-col"}>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("general:packages")}
</h3>
<div className={"w-full max-h-[30vh] overflow-y-auto shrink"}>
<table className={"w-full"}>
<thead>
<tr>
<th className={"sticky top-0 z-10 bg-background"}>
{tc("general:name")}
</th>
<th className={"sticky top-0 z-10 bg-background"}>
{tc("general:version")}
</th>
<th className={"sticky top-0 z-10 bg-background"} />
</tr>
</thead>
<tbody>
<ReorderableList
context={packagesListContext}
renderItem={(value, id) => (
<>
<td>
<div className={"flex"}>
<Input
type={"text"}
value={value}
<Autocomplete
value={value.name}
className={"grow"}
disabled
options={packageCandidates.filter(
(c) =>
c.value === value.name ||
!addedPackageNames.has(c.value),
)}
onChange={(value) =>
packagesListContext.update(id, (old) => ({
...old,
name: value,
}))
}
/>
</div>
</td>
)}
/>
</tbody>
</table>
<td>
<div className={"flex"}>
<Autocomplete
value={value.range}
className={cn(
"grow",
validVersion(value) ||
"border-destructive ring-destructive text-destructive",
)}
options={
versionCandidatePerPackage.get(value.name) ?? []
}
onChange={(value) =>
packagesListContext.update(id, (old) => ({
...old,
range: value,
}))
}
/>
</div>
</td>
</>
)}
/>
</tbody>
</table>
</div>
</section>
<section className={"shrink overflow-hidden flex flex-col"}>
<Overlay>
<h3 className={"font-bold w-full text-center content-center"}>
{tc("templates:dialog:unitypackages")}
</h3>
<div className={"text-right mb-2"}>
<Button onClick={addUnityPackages}>
{tc("general:button:add")}
</Button>
</div>
</section>
</div>
</DialogDescription>
</Overlay>
<div className={"w-full max-h-[30vh] overflow-y-auto shrink"}>
<table className={"w-full"}>
<tbody>
<ReorderableList
context={unityPackagesListContext}
ifEmpty={() => (
<td className={"text-center"}>
{tc("templates:dialog:no unitypackages")}
</td>
)}
renderItem={(value, id) => (
<td>
<FilePathRow
path={value}
pick={() => pickUnityPackage(value, id).finally()}
withOpen={false}
/>
</td>
)}
/>
</tbody>
</table>
</div>
</section>
</div>
<DialogFooter className={"mt-2"}>
<Button onClick={() => dialog.close(false)}>
{tc("general:button:cancel")}
@ -711,3 +1008,34 @@ function TemplateEditor({
</div>
);
}
function AutocompletePackageLabel({
displayName,
id,
}: {
displayName: string | null;
id: string;
}) {
if (displayName == null) return id;
return (
<div className={"flex flex-col"}>
<div>{displayName}</div>
<div className={"text-xs text-muted-foreground"}>{id}</div>
</div>
);
}
function AutocompleteVersionLabel({
value,
description,
}: {
value: string;
description: React.ReactNode;
}) {
return (
<div className={"flex flex-row justify-between w-full"}>
<div>{value}</div>
<div className={"text-xs text-muted-foreground"}>{description}</div>
</div>
);
}

View file

@ -1,13 +1,21 @@
"use client";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { CircleX } from "lucide-react";
import { Suspense, useId } from "react";
import { HNavBar, VStack } from "@/components/layout";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogTitle,
DialogTrigger,
@ -23,15 +31,6 @@ import { tc } from "@/lib/i18n";
import { usePrevPathName } from "@/lib/prev-page";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { toVersionString } from "@/lib/version";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { CircleX } from "lucide-react";
import { Suspense, useId } from "react";
import { HeadingPageName } from "../-tab-selector";
export const Route = createFileRoute("/_main/packages/user-packages/")({
@ -87,10 +86,13 @@ function PageBody() {
return (
<VStack>
<HNavBar
className={"shrink-0"}
className="shrink-0"
leading={<HeadingPageName pageType={"/packages/user-packages"} />}
trailing={
<Button onClick={() => addUserPackageWithPicker.mutate()}>
<Button
className={"compact:h-10"}
onClick={() => addUserPackageWithPicker.mutate()}
>
{tc("user packages:button:add package")}
</Button>
}
@ -154,7 +156,7 @@ function RepositoryTableBody({
// biome-ignore lint/suspicious/noArrayIndexKey: static array
key={index}
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground p-2.5"
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5"
}
>
<small className="font-normal leading-none">{tc(head)}</small>
@ -182,7 +184,7 @@ function PackageRow({
pkg: TauriUserPackage;
remove: () => void;
}) {
const cellClass = "p-2.5";
const cellClass = "p-2.5 compact:py-1";
const id = useId();
const pkgDisplayNames = pkg.package.display_name ?? pkg.package.name;
@ -217,14 +219,14 @@ function PackageRow({
<DialogTitle>
{tc("user packages:dialog:remove package")}
</DialogTitle>
<DialogDescription>
<div>
<p className={"whitespace-normal font-normal"}>
{tc("user packages:dialog:confirm remove description", {
name: pkgDisplayNames,
path: pkg.path,
})}
</p>
</DialogDescription>
</div>
<DialogFooter>
<DialogClose asChild>
<Button>{tc("general:button:cancel")}</Button>

View file

@ -1,26 +1,19 @@
import { useMutation } from "@tanstack/react-query";
import { RefreshCw } from "lucide-react";
import type React from "react";
import { useEffect, useId, useMemo, useState } from "react";
import { VStack } from "@/components/layout";
import { TemplateSelect } from "@/components/TemplateSelect";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { assertNever } from "@/lib/assert-never";
import type { TauriProjectTemplateInfo } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
@ -32,20 +25,8 @@ import {
ProjectNameCheckResult,
useProjectNameCheck,
} from "@/lib/project-name-check";
import {
type ProjectTemplateCategory,
projectTemplateCategory,
projectTemplateName,
} from "@/lib/project-template";
import { queryClient } from "@/lib/query-client";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation } from "@tanstack/react-query";
import { RefreshCw } from "lucide-react";
import type React from "react";
import { useEffect } from "react";
import { useMemo } from "react";
import { useId } from "react";
import { useState } from "react";
export async function createProject() {
const information = await commands.environmentProjectCreationInformation();
@ -53,6 +34,8 @@ export async function createProject() {
using dialog = showDialog();
const result = await dialog.ask(EnteringInformation, {
templates: information.templates,
favoriteTemplates: information.favorite_templates,
lastUsedTemplate: information.last_used_template,
projectLocation: information.default_path,
recentProjectLocations: information.recent_project_locations,
});
@ -70,7 +53,6 @@ export async function createProject() {
);
dialog.close();
toastSuccess(tt("projects:toast:project created"));
close?.();
await queryClient.invalidateQueries({
queryKey: ["environmentProjects"],
});
@ -93,7 +75,7 @@ function DialogBase({
return (
<>
<DialogTitle>{tc("projects:create new project")}</DialogTitle>
<DialogDescription>{children}</DialogDescription>
<div>{children}</div>
<DialogFooter className={"gap-2"}>
<Button onClick={close} disabled={!close}>
{tc("general:button:cancel")}
@ -117,23 +99,39 @@ function EnteringInformation({
templates,
projectLocation: projectLocationFirst,
recentProjectLocations: recentProjectLocationsReversed,
favoriteTemplates,
lastUsedTemplate,
dialog,
}: {
templates: TauriProjectTemplateInfo[];
projectLocation: string;
favoriteTemplates: string[];
lastUsedTemplate: string | null;
recentProjectLocations: string[];
dialog: DialogContext<null | ProjectCreationInformation>;
}) {
const [unityVersion, setUnityVersion] = useState<string>(
templates[0].unity_versions[0],
);
const [templateId, setTemplateId] = useState<string>(templates[0].id);
const templateById = useMemo(
() => new Map(templates.map((t) => [t.id, t])),
[templates],
);
const [templateId, setTemplateId] = useState<string>(() => {
const template = lastUsedTemplate
? templateById.get(lastUsedTemplate)
: undefined;
return template?.available &&
template.unity_versions.length !== 0 &&
lastUsedTemplate != null
? lastUsedTemplate
: templates[0].id;
});
const [unityVersion, setUnityVersion] = useState<string>(
() =>
templateById.get(templateId)?.unity_versions?.[0] ??
templates[0].unity_versions[0],
);
const [projectNameRaw, setProjectName] = useState("New Project");
const projectName = projectNameRaw.trim();
const [projectLocation, setProjectLocation] = useState(projectLocationFirst);
@ -180,28 +178,6 @@ function EnteringInformation({
const templateInputId = useId();
const unityInputId = useId();
const templatesByCategory = useMemo(() => {
const byCategory: {
[k in ProjectTemplateCategory]: TauriProjectTemplateInfo[];
} = {
builtin: [],
alcom: [],
vcc: [],
};
for (const template of templates) {
byCategory[projectTemplateCategory(template.id)].push(template);
}
return (
[
["builtin", byCategory.builtin],
["alcom", byCategory.alcom],
["vcc", byCategory.vcc],
] satisfies [ProjectTemplateCategory, TauriProjectTemplateInfo[]][]
).filter((x) => x[1].length > 0);
}, [templates]);
const unityVersions = templateById.get(templateId)?.unity_versions ?? [];
const badProjectName = ["AlreadyExists", "InvalidNameForFolderName"].includes(
@ -231,59 +207,13 @@ function EnteringInformation({
<div className={"flex items-center whitespace-nowrap"}>
<label htmlFor={templateInputId}>{tc("projects:template")}</label>
</div>
<Select
<TemplateSelect
value={templateId}
onValueChange={(value) => setTemplateId(value)}
>
<SelectTrigger id={templateInputId}>
<SelectValue />
</SelectTrigger>
<SelectContent>
{templatesByCategory.map(([category, templates], index) => (
<SelectGroup key={category}>
{index !== 0 && <SelectSeparator />}
<SelectLabel>
{tc(`projects:template-category:${category}`)}
</SelectLabel>
{templates.map((template) => {
const disabled =
!template.available ||
template.unity_versions.length === 0;
const contents = (
<SelectItem
value={template.id}
disabled={disabled}
key={template.id}
>
{projectTemplateName(template)}
</SelectItem>
);
if (!template.available) {
return (
<Tooltip key={template.id}>
<TooltipTrigger>{contents}</TooltipTrigger>
<TooltipContent>
{tc("projects:tooltip:template-unavailable")}
</TooltipContent>
</Tooltip>
);
} else if (template.unity_versions.length === 0) {
return (
<Tooltip key={template.id}>
<TooltipTrigger>{contents}</TooltipTrigger>
<TooltipContent>
{tc("projects:tooltip:template-no-unity")}
</TooltipContent>
</Tooltip>
);
} else {
return contents;
}
})}
</SelectGroup>
))}
</SelectContent>
</Select>
onValueChange={setTemplateId}
templates={templates}
favoriteTemplates={favoriteTemplates}
selectTriggerId={templateInputId}
/>
</div>
<div className={"flex items-center gap-1 whitespace-nowrap"}>
<label htmlFor={unityInputId}>
@ -386,8 +316,10 @@ function UnityVersion({
function CreatingProject() {
return (
<DialogBase>
<RefreshCw className={"w-5 h-5 animate-spin"} />
<p>{tc("projects:creating project...")}</p>
<div className={"flex items-center gap-2"}>
<RefreshCw className={"w-5 h-5 animate-spin"} />
<p>{tc("projects:creating project...")}</p>
</div>
</DialogBase>
);
}

View file

@ -1,15 +1,16 @@
import { CircleHelp, CircleUserRound, Ellipsis, Globe } from "lucide-react";
import {
ButtonDisabledIfInvalid,
FavoriteToggleButton,
getProjectDisplayInfo,
ManageOrMigrateButton,
ProjectContext,
TooltipTriggerIfInvalid,
TooltipTriggerIfValid,
getProjectDisplayInfo,
useSetProjectFavoriteMutation,
} from "@/app/_main/projects/-project-row";
import { copyProject } from "@/app/_main/projects/manage/-copy-project";
import { BackupProjectDialog } from "@/components/BackupProjectDialog";
import { FavoriteStarToggleButton } from "@/components/FavoriteStarButton";
import { OpenUnityButton } from "@/components/OpenUnityButton";
import { RemoveProjectDialog } from "@/components/RemoveProjectDialog";
import { Button } from "@/components/ui/button";
@ -28,17 +29,14 @@ import {
} from "@/components/ui/tooltip";
import type { TauriProject } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
import { dateToString, formatDateOffset } from "@/lib/dateToString";
import {
dateToString,
dayToString,
formatDateOffset,
} from "@/lib/dateToString";
import { openSingleDialog } from "@/lib/dialog";
import { tc } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import { queryOptions } from "@tanstack/react-query";
import { CircleHelp, CircleUserRound, Ellipsis, Globe } from "lucide-react";
const environmentProjects = queryOptions({
queryKey: ["environmentProjects"],
queryFn: commands.environmentProjects,
});
export function ProjectGridItem({
project,
@ -51,7 +49,7 @@ export function ProjectGridItem({
const typeIconClass = "w-5 h-5";
const { projectTypeKind, displayType, isLegacy, lastModified } =
const { projectTypeKind, displayType, isLegacy, createdAt, lastModified } =
getProjectDisplayInfo(project);
const removed = !project.is_exists;
@ -61,11 +59,11 @@ export function ProjectGridItem({
<ProjectContext.Provider
value={{ removed, is_valid, loading: Boolean(loading) }}
>
<Card className="relative p-4 bg-card flex flex-col gap-2 group">
<Card className="relative p-4 bg-card flex flex-col gap-2 group compact:p-2 compact:pl-3 compact:gap-1">
<div className={"absolute top-2 right-2 gap-2 flex"}>
<div className="relative content-center">
<FavoriteToggleButton
project={project}
<FavoriteStarToggleButton
favorite={project.favorite}
disabled={removed || loading}
onToggle={() =>
setProjectFavorite.mutate({
@ -128,14 +126,7 @@ export function ProjectGridItem({
<p className="font-normal whitespace-pre overflow-ellipsis overflow-hidden">
{project.name}
</p>
</TooltipTriggerIfValid>
<TooltipContent>{project.name}</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTriggerIfValid
className={"text-left select-text cursor-auto w-full"}
>
<p className="font-normal opacity-50 text-sm whitespace-pre overflow-ellipsis overflow-hidden">
<p className="font-normal opacity-50 text-sm whitespace-pre overflow-ellipsis overflow-hidden compact:hidden">
{project.path}
</p>
</TooltipTriggerIfValid>
@ -178,25 +169,47 @@ export function ProjectGridItem({
</div>
</div>
<div className="text-xs text-muted-foreground">
{tc("general:last modified")}:{" "}
<Tooltip>
<TooltipTrigger>
<time dateTime={lastModified.toISOString()}>
<time className="font-normal">
{formatDateOffset(project.last_modified)}
<div className="flex flex-row gap-1">
<div className="text-xs text-muted-foreground">
{tc("general:created at")}:{" "}
<Tooltip>
<TooltipTrigger>
<time dateTime={createdAt.toISOString()}>
<time className="font-normal">
{dayToString(project.created_at)}
</time>
</time>
</time>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
{dateToString(project.last_modified)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
{dateToString(project.created_at)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
<p className="text-xs text-muted-foreground">/</p>
<div className="text-xs text-muted-foreground">
{tc("general:last modified")}:{" "}
<Tooltip>
<TooltipTrigger>
<time dateTime={lastModified.toISOString()}>
<time className="font-normal">
{formatDateOffset(project.last_modified)}
</time>
</time>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
{dateToString(project.last_modified)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
</div>
</div>
<div className="mt-2 flex flex-wrap gap-2 justify-end">
<div className="mt-2 flex flex-wrap gap-2 justify-end compact:gap-1">
<ButtonDisabledIfInvalid asChild>
<OpenUnityButton
projectPath={project.path}

View file

@ -1,14 +1,19 @@
import {
queryOptions,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { CircleHelp, CircleUserRound, Ellipsis, Globe } from "lucide-react";
import React, { type ComponentProps, useContext } from "react";
import { copyProject } from "@/app/_main/projects/manage/-copy-project";
import { MigrationCopyingDialog } from "@/app/_main/projects/manage/-unity-migration";
import { BackupProjectDialog } from "@/components/BackupProjectDialog";
import { FavoriteStarToggleButton } from "@/components/FavoriteStarButton";
import { OpenUnityButton } from "@/components/OpenUnityButton";
import { RemoveProjectDialog } from "@/components/RemoveProjectDialog";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
@ -24,28 +29,17 @@ import {
import { assertNever } from "@/lib/assert-never";
import type { TauriProject, TauriProjectType } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
import { dateToString, formatDateOffset } from "@/lib/dateToString";
import {
dateToString,
dayToString,
formatDateOffset,
} from "@/lib/dateToString";
import { type DialogContext, openSingleDialog, showDialog } from "@/lib/dialog";
import { tc, tt } from "@/lib/i18n";
import { router } from "@/lib/main";
import { queryClient } from "@/lib/query-client";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { cn } from "@/lib/utils";
import { compareUnityVersionString } from "@/lib/version";
import {
queryOptions,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import {
CircleHelp,
CircleUserRound,
Ellipsis,
Globe,
Star,
} from "lucide-react";
import React, { type ComponentProps, useContext } from "react";
export const ProjectDisplayType: Record<
TauriProjectType,
@ -84,11 +78,11 @@ export function ProjectRow({
project: TauriProject;
loading?: boolean;
}) {
const cellClass = "p-2.5";
const cellClass = "p-2.5 compact:py-1";
const noGrowCellClass = `${cellClass} w-1`;
const typeIconClass = "w-5 h-5";
const { projectTypeKind, displayType, isLegacy, lastModified } =
const { projectTypeKind, displayType, isLegacy, createdAt, lastModified } =
getProjectDisplayInfo(project);
const openProjectFolder = () =>
@ -115,10 +109,10 @@ export function ProjectRow({
<tr
className={`group even:bg-secondary/30 ${removed || loading || !(project.is_valid ?? true) ? "opacity-50" : ""}`}
>
<td className={`${cellClass} w-3`}>
<td className={noGrowCellClass}>
<div className={"relative flex"}>
<FavoriteToggleButton
project={project}
<FavoriteStarToggleButton
favorite={project.favorite}
disabled={removed || loading}
onToggle={() =>
setProjectFavorite.mutate({
@ -140,14 +134,7 @@ export function ProjectRow({
className={"text-left select-text cursor-auto w-full"}
>
<p className="font-normal whitespace-pre">{project.name}</p>
</TooltipTriggerIfValid>
<TooltipContent>{project.name}</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTriggerIfValid
className={"text-left select-text cursor-auto w-full"}
>
<p className="font-normal opacity-50 text-sm whitespace-pre">
<p className="font-normal opacity-50 text-sm whitespace-pre compact:hidden">
{project.path}
</p>
</TooltipTriggerIfValid>
@ -164,7 +151,7 @@ export function ProjectRow({
</TooltipPortal>
</Tooltip>
</td>
<td className={`${cellClass} w-[8em] min-w-[8em]`}>
<td className={noGrowCellClass}>
<div className="flex flex-row gap-2">
<div className="flex items-center">
{projectTypeKind === "avatars" ? (
@ -188,6 +175,22 @@ export function ProjectRow({
<td className={noGrowCellClass}>
<p className="font-normal">{project.unity}</p>
</td>
<td className={noGrowCellClass}>
<Tooltip>
<TooltipTrigger>
<time dateTime={createdAt.toISOString()}>
<time className="font-normal">
{dayToString(project.created_at)}
</time>
</time>
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
{dateToString(project.created_at)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
</td>
<td className={noGrowCellClass}>
<Tooltip>
<TooltipTrigger>
@ -205,7 +208,7 @@ export function ProjectRow({
</Tooltip>
</td>
<td className={noGrowCellClass}>
<div className="flex flex-row gap-2 max-w-min">
<div className="flex flex-row gap-2 max-w-min items-center">
<ButtonDisabledIfInvalid asChild>
<OpenUnityButton
projectPath={project.path}
@ -272,11 +275,9 @@ export function ProjectRow({
);
}
export function ManageOrMigrateButton({
project,
}: {
project: TauriProject;
}) {
export function ManageOrMigrateButton({ project }: { project: TauriProject }) {
const navigate = useNavigate();
if (compareUnityVersionString(project.unity, "2018.0.0f0") < 0) {
// No UPM is supported in unity 2017 or older
return (
@ -293,7 +294,6 @@ export function ManageOrMigrateButton({
);
}
const navigate = useNavigate();
switch (project.project_type) {
case "LegacySdk2":
return (
@ -415,9 +415,9 @@ function ConfirmVpmMigrationDialog({
return (
<div className={"contents whitespace-normal"}>
<DialogTitle>{tc("projects:dialog:vpm migrate header")}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:dialog:vpm migrate description")}</p>
</DialogDescription>
</div>
<DialogFooter className={"gap-1"}>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -440,9 +440,9 @@ function VpmMigrationUpdating() {
return (
<div className={"contents whitespace-normal"}>
<DialogTitle>{tc("projects:dialog:vpm migrate header")}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:migrating...")}</p>
</DialogDescription>
</div>
</div>
);
}
@ -517,49 +517,18 @@ export const TooltipTriggerIfValid = ({
}
};
export function FavoriteToggleButton({
project,
disabled,
onToggle,
className,
}: {
project: { favorite: boolean };
disabled?: boolean;
onToggle: () => void;
className?: string;
}) {
if (disabled) return null;
return (
<Star
strokeWidth={project.favorite ? 1.5 : 3}
className={cn(
"size-4 transition-colors cursor-pointer",
project.favorite ? "text-foreground" : "text-foreground/30",
!project.favorite && "opacity-0 group-hover:opacity-100",
"hover:text-foreground",
className,
)}
fill={project.favorite ? "currentColor" : "none"}
onClick={() => {
if (!disabled) {
onToggle();
}
}}
/>
);
}
export function getProjectDisplayInfo(project: TauriProject) {
const projectTypeKind = ProjectDisplayType[project.project_type] ?? "unknown";
const displayType = tc(`projects:type:${projectTypeKind}`);
const isLegacy = LegacyProjectTypes.includes(project.project_type);
const createdAt = new Date(project.created_at);
const lastModified = new Date(project.last_modified);
return {
projectTypeKind,
displayType,
isLegacy,
createdAt,
lastModified,
};
}

View file

@ -1,4 +1,7 @@
"use client";
import { useQuery } from "@tanstack/react-query";
import { ArrowDown, ArrowUp } from "lucide-react";
import { useMemo } from "react";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { ScrollArea } from "@/components/ui/scroll-area";
@ -12,14 +15,11 @@ import {
import type { TauriProject } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { useQuery } from "@tanstack/react-query";
import { ArrowDown, ArrowUp } from "lucide-react";
import { useMemo } from "react";
import { ProjectGridItem } from "./-project-grid-item";
import {
isSorting,
sortSearchProjects,
type sortings,
sortSearchProjects,
useSetProjectSortingMutation,
} from "./-projects-list-card";
@ -30,6 +30,7 @@ const sortingOptions: { key: SimpleSorting; label: string }[] = [
{ key: "name", label: "general:name" },
{ key: "type", label: "projects:type" },
{ key: "unity", label: "projects:unity" },
{ key: "createdAt", label: "general:created at" },
{ key: "lastModified", label: "general:last modified" },
];
@ -77,29 +78,27 @@ export function ProjectsGridCard({
return (
<div className="flex flex-col h-full w-full overflow-hidden">
<Card className="flex items-center mb-3 flex-wrap">
<div className="flex items-center gap-1 m-2 ml-4">
<p className="grow-0 whitespace-pre mb-0 leading-tight">
{tc("projects:sort by")}
</p>
<Select
value={currentKey}
onValueChange={(value) =>
handleChangeSortingKey(value as SimpleSorting)
}
>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
<SelectContent>
{sortingOptions.map((option) => (
<SelectItem key={option.key} value={option.key}>
{tc(option.label)}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<Card className="flex items-center mb-3 flex-wrap p-2 gap-2 compact:p-1 compact:gap-1">
<p className="grow-0 whitespace-pre pl-2 leading-tight">
{tc("projects:sort by")}
</p>
<Select
value={currentKey}
onValueChange={(value) =>
handleChangeSortingKey(value as SimpleSorting)
}
>
<SelectTrigger className="w-40">
<SelectValue />
</SelectTrigger>
<SelectContent>
{sortingOptions.map((option) => (
<SelectItem key={option.key} value={option.key}>
{tc(option.label)}
</SelectItem>
))}
</SelectContent>
</Select>
<Button variant="ghost" size="icon" onClick={toggleOrder}>
{isReversed ? (
@ -114,7 +113,10 @@ export function ProjectsGridCard({
className="h-full w-full vrc-get-scrollable-card rounded-l-xl"
scrollBarClassName="bg-background rounded-full border-l-0 p-[1.5px]"
>
<div className="grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-3 gap-3 overflow-x-hidden mr-4">
<div
className="grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-3 gap-3 overflow-x-hidden mr-4
compact:grid-cols-2 compact:lg:grid-cols-3 compact:2xl:grid-cols-4 compact:gap-1.5"
>
{projectsShown.map((project) => (
<ProjectGridItem
key={project.path}

View file

@ -1,4 +1,7 @@
"use client";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ChevronDown, ChevronsUpDown, ChevronUp, Star } from "lucide-react";
import { useMemo } from "react";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { assertNever } from "@/lib/assert-never";
import type { TauriProject, TauriProjectType } from "@/lib/bindings";
@ -6,12 +9,15 @@ import { commands } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import { compareUnityVersionString } from "@/lib/version";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { ChevronDown, ChevronUp, ChevronsUpDown, Star } from "lucide-react";
import { useMemo } from "react";
import { ProjectRow } from "./-project-row";
export const sortings = ["lastModified", "name", "unity", "type"] as const;
export const sortings = [
"createdAt",
"lastModified",
"name",
"unity",
"type",
] as const;
type SimpleSorting = (typeof sortings)[number];
type Sorting = SimpleSorting | `${SimpleSorting}Reversed`;
@ -158,6 +164,18 @@ export function ProjectsTableCard({
</small>
</button>
</th>
<th className={`${thClass} ${headerBg("createdAt")}`}>
<button
type="button"
className={"flex w-full project-table-button"}
onClick={() => setSorting("createdAt")}
>
{icon("createdAt")}
<small className="font-normal leading-none">
{tc("general:created at")}
</small>
</button>
</th>
<th className={`${thClass} ${headerBg("lastModified")}`}>
<button
type="button"
@ -194,6 +212,12 @@ export function sortSearchProjects(
searched.sort((a, b) => b.last_modified - a.last_modified);
switch (sorting) {
case "createdAt":
searched.sort((a, b) => b.created_at - a.created_at);
break;
case "createdAtReversed":
searched.sort((a, b) => a.created_at - b.created_at);
break;
case "lastModified":
searched.sort((a, b) => b.last_modified - a.last_modified);
break;

View file

@ -1,10 +1,19 @@
"use client";
import Loading from "@/app/-loading";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, LayoutGrid, LayoutList, RefreshCw } from "lucide-react";
import { useRef, useState } from "react";
import { createProject } from "@/app/_main/projects/-create-project";
import { ProjectsGridCard } from "@/app/_main/projects/-projects-grid-card";
import Loading from "@/app/-loading";
import { HNavBar, HNavBarText, VStack } from "@/components/layout";
import { SearchBox } from "@/components/SearchBox";
import { HNavBar, VStack } from "@/components/layout";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import {
@ -24,15 +33,6 @@ import { isFindKey, useDocumentEvent } from "@/lib/events";
import { useProjectUpdateInProgress } from "@/lib/global-events";
import { tc, tt } from "@/lib/i18n";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import {
queryOptions,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { ChevronDown, LayoutGrid, LayoutList, RefreshCw } from "lucide-react";
import { useRef, useState } from "react";
import { ProjectsTableCard } from "./-projects-list-card";
export const Route = createFileRoute("/_main/projects/")({
@ -188,15 +188,14 @@ function ProjectViewHeader({
return (
<HNavBar
className={"shrink-0"}
className="shrink-0"
leading={
<>
<p className="cursor-pointer font-bold grow-0 whitespace-pre mb-0 leading-tight">
{tc("projects")}
</p>
<HNavBarText>{tc("projects")}</HNavBarText>
<Tooltip>
<TooltipTrigger asChild>
<Button
className={"compact:h-10 compact:w-10"}
variant={"ghost"}
size={"icon"}
onClick={() =>
@ -215,13 +214,14 @@ function ProjectViewHeader({
</Tooltip>
<SearchBox
className={"w-max grow"}
className={"w-max grow compact:h-10"}
value={search}
onChange={(e) => setSearch(e.target.value)}
ref={searchRef}
/>
<Button
className={"compact:h-10"}
variant={"ghost"}
onClick={() => {
if (viewMode === "List") {
@ -254,12 +254,15 @@ function ProjectViewHeader({
<DropdownMenu>
<div className={"flex divide-x"}>
<Button
className={"rounded-r-none pl-4 pr-3"}
className={"rounded-r-none pl-4 pr-3 compact:h-10"}
onClick={startCreateProject}
>
{tc("projects:create new project")}
</Button>
<DropdownMenuTrigger asChild className={"rounded-l-none pl-2 pr-2"}>
<DropdownMenuTrigger
asChild
className={"rounded-l-none pl-2 pr-2 compact:h-10"}
>
<Button>
<ChevronDown className={"w-4 h-4"} />
</Button>

View file

@ -39,11 +39,12 @@ export interface PackageRowInfo {
infoSource: TauriVersion;
displayName: string;
description: string;
aliases: string[];
keywords: string[];
unityCompatible: Map<string, TauriPackage>;
unityIncompatible: Map<string, TauriPackage>;
sources: Set<string>;
isThereSource: boolean; // this will be true even if all sources are hidden
visibleSources: Set<string>;
installed: null | {
version: TauriVersion;
yanked: boolean;
@ -92,7 +93,9 @@ export function combinePackagesAndProjectDetails(
const yankedVersions = new Set<`${string}:${string}`>();
const knownPackages = new Set<string>();
const packagesPerRepository = new Map<string, TauriPackage[]>();
const hiddenPackagesPerRepository = new Map<string, TauriPackage[]>();
const userPackages: TauriPackage[] = [];
const hiddenUserPackages: TauriPackage[] = [];
for (const pkg of packages) {
if (!showPrereleasePackages && pkg.version.pre) continue;
@ -107,13 +110,19 @@ export function combinePackagesAndProjectDetails(
let packages: TauriPackage[];
// check the repository is visible
if (pkg.source === "LocalUser") {
if (hideLocalUserPackages) continue;
packages = userPackages;
if (hideLocalUserPackages) {
packages = hiddenUserPackages;
} else {
packages = userPackages;
}
} else if ("Remote" in pkg.source) {
if (hiddenRepositoriesSet.has(pkg.source.Remote.id)) continue;
packages = packagesPerRepository.get(pkg.source.Remote.id) ?? [];
packagesPerRepository.set(pkg.source.Remote.id, packages);
if (hiddenRepositoriesSet.has(pkg.source.Remote.id)) {
packages = hiddenPackagesPerRepository.get(pkg.source.Remote.id) ?? [];
hiddenPackagesPerRepository.set(pkg.source.Remote.id, packages);
} else {
packages = packagesPerRepository.get(pkg.source.Remote.id) ?? [];
packagesPerRepository.set(pkg.source.Remote.id, packages);
}
} else {
assertNever(pkg.source);
}
@ -132,12 +141,13 @@ export function combinePackagesAndProjectDetails(
id: pkg.name,
displayName: pkg.display_name ?? pkg.name,
description: pkg.description ?? "",
aliases: pkg.aliases,
keywords: pkg.keywords,
infoSource: pkg.version,
unityCompatible: new Map(),
unityIncompatible: new Map(),
sources: new Set(),
isThereSource: false,
visibleSources: new Set(),
installed: null,
latest: { status: "none" },
stableLatest: { status: "none" },
@ -167,7 +177,7 @@ export function combinePackagesAndProjectDetails(
packageRowInfo.displayName = pkg.display_name ?? pkg.name;
packageRowInfo.description =
pkg.description || packageRowInfo.description;
packageRowInfo.aliases = pkg.aliases;
packageRowInfo.keywords = pkg.keywords;
}
if (project == null || isUnityCompatible(pkg, project.unity)) {
@ -178,8 +188,14 @@ export function combinePackagesAndProjectDetails(
if (pkg.source === "LocalUser") {
packageRowInfo.sources.add("User");
if (!hideLocalUserPackages) {
packageRowInfo.visibleSources.add("User");
}
} else if ("Remote" in pkg.source) {
packageRowInfo.sources.add(pkg.source.Remote.display_name);
if (!hiddenRepositoriesSet.has(pkg.source.Remote.id)) {
packageRowInfo.visibleSources.add(pkg.source.Remote.display_name);
}
}
}
@ -187,6 +203,13 @@ export function combinePackagesAndProjectDetails(
packagesPerRepository.get("com.vrchat.repos.official")?.forEach(addPackage);
packagesPerRepository.get("com.vrchat.repos.curated")?.forEach(addPackage);
userPackages.forEach(addPackage);
hiddenUserPackages.forEach((pkg) => {
const packageRowInfo = getRowInfo(pkg);
packageRowInfo.isThereSource = true;
if (pkg.source === "LocalUser") {
packageRowInfo.sources.add("User");
}
});
packagesPerRepository.delete("com.vrchat.repos.official");
packagesPerRepository.delete("com.vrchat.repos.curated");
@ -201,6 +224,17 @@ export function combinePackagesAndProjectDetails(
packages.forEach(addPackage);
}
// process hidden repositories - only add to sources, not to version calculations
for (const packages of hiddenPackagesPerRepository.values()) {
packages.forEach((pkg) => {
const packageRowInfo = getRowInfo(pkg);
packageRowInfo.isThereSource = true;
if (pkg.source !== "LocalUser") {
packageRowInfo.sources.add(pkg.source.Remote.display_name);
}
});
}
// sort versions
for (const value of packagesTable.values()) {
value.unityCompatible = new Map(
@ -292,14 +326,14 @@ export function combinePackagesAndProjectDetails(
// if installed, use the installed version to get the display name
packageRowInfo.displayName = pkg.display_name ?? pkg.name;
packageRowInfo.aliases = [...pkg.aliases, ...packageRowInfo.aliases];
packageRowInfo.keywords = [...pkg.keywords, ...packageRowInfo.keywords];
packageRowInfo.installed = {
version: pkg.version,
yanked:
pkg.is_yanked ||
yankedVersions.has(`${pkg.name}:${toVersionString(pkg.version)}`),
};
packageRowInfo.isThereSource = knownPackages.has(pkg.name);
packageRowInfo.isThereSource = true;
// if we have the latest version, check if it's upgradable
if (packageRowInfo.latest.status !== "none") {

View file

@ -1,14 +1,13 @@
import { useMutation } from "@tanstack/react-query";
import type { NavigateFn } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { VStack } from "@/components/layout";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Progress } from "@/components/ui/progress";
import { assertNever } from "@/lib/assert-never";
import { type TauriCopyProjectProgress, commands } from "@/lib/bindings";
import { commands, type TauriCopyProjectProgress } from "@/lib/bindings";
import { callAsyncCommand } from "@/lib/call-async-command";
import { type DialogContext, showDialog } from "@/lib/dialog";
import { tc, tt } from "@/lib/i18n";
@ -19,11 +18,6 @@ import {
} from "@/lib/project-name-check";
import { queryClient } from "@/lib/query-client";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation } from "@tanstack/react-query";
import type { NavigateFn } from "@tanstack/react-router";
import type React from "react";
import { useEffect } from "react";
import { useState } from "react";
export async function copyProject(existingPath: string, navigate?: NavigateFn) {
using dialog = showDialog();
@ -58,31 +52,6 @@ export async function copyProject(existingPath: string, navigate?: NavigateFn) {
});
}
function DialogBase({
children,
close,
createProject,
}: {
children: React.ReactNode;
close?: () => void;
createProject?: () => void;
}) {
return (
<>
<DialogTitle>{tc("projects:dialog:copy project")}</DialogTitle>
<DialogDescription>{children}</DialogDescription>
<DialogFooter className={"gap-2"}>
<Button onClick={close} disabled={!close}>
{tc("general:button:cancel")}
</Button>
<Button onClick={createProject} disabled={!createProject}>
{tc("projects:button:create")}
</Button>
</DialogFooter>
</>
);
}
function CopyProjectNameDialog({
dialog,
projectPath,
@ -140,7 +109,7 @@ function CopyProjectNameDialog({
<DialogTitle>
{tc("projects:dialog:copy project", { name: oldName })}
</DialogTitle>
<DialogDescription>
<div>
<VStack>
<Input
value={projectNameRaw}
@ -176,7 +145,7 @@ function CopyProjectNameDialog({
projectNameCheckState={projectNameCheckState}
/>
</VStack>
</DialogDescription>
</div>
<DialogFooter className={"gap-2"}>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -226,7 +195,7 @@ export function CopyingDialog({
<DialogTitle>
{tc("projects:dialog:copy project", { name: oldName })}
</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:dialog:copying...")}</p>
<p>
{tc("projects:dialog:proceed k/n", {
@ -236,7 +205,7 @@ export function CopyingDialog({
</p>
<Progress value={progress.proceed} max={progress.total} />
<p>{tc("projects:do not close")}</p>
</DialogDescription>
</div>
<DialogFooter className={"gap-2"}>
<Button disabled>{tc("general:button:cancel")}</Button>
</DialogFooter>

View file

@ -1,5 +1,28 @@
// noinspection ExceptionCaughtLocallyJS
import {
queryOptions,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import {
ChevronDown,
ChevronRight,
CircleArrowUp,
CircleMinus,
CirclePlus,
Ellipsis,
RefreshCw,
} from "lucide-react";
import type React from "react";
import {
memo,
useCallback,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
import { applyChangesMutation } from "@/app/_main/projects/manage/-use-package-change";
import { Route } from "@/app/_main/projects/manage/index";
import { ExternalLink } from "@/components/ExternalLink";
@ -7,6 +30,7 @@ import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { SearchBox } from "@/components/SearchBox";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
@ -34,27 +58,12 @@ import {
import { assertNever } from "@/lib/assert-never";
import type { TauriPackage, TauriRepositoriesInfo } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
import { type DialogContext, openSingleDialog } from "@/lib/dialog";
import { isFindKey, useDocumentEvent } from "@/lib/events";
import { usePackageUpdateInProgress } from "@/lib/global-events";
import { tc, tt } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import { toVersionString } from "@/lib/version";
import {
queryOptions,
useMutation,
useQueryClient,
} from "@tanstack/react-query";
import {
CircleArrowUp,
CircleMinus,
CirclePlus,
Ellipsis,
RefreshCw,
} from "lucide-react";
import type React from "react";
import { useLayoutEffect } from "react";
import { useRef } from "react";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import type {
PackageLatestInfo,
PackageRowInfo,
@ -81,9 +90,23 @@ export const PackageListCard = memo(function PackageListCard({
onRefresh: () => void;
}) {
const [search, setSearch] = useState("");
const [bulkUpdatePackageIds, setBulkUpdatePackageIds] = useState<string[]>(
const [bulkUpdatePackageIdsRaw, setBulkUpdatePackageIds] = useState<string[]>(
[],
);
const [showHiddenPackages, setShowHiddenPackages] = useState(false);
const bulkUpdatePackageIds = useMemo(() => {
const packageIds = new Set(packageRowsData.map((p) => p.id));
return bulkUpdatePackageIdsRaw.filter((pkgId) => packageIds.has(pkgId));
}, [packageRowsData, bulkUpdatePackageIdsRaw]);
useDocumentEvent(
"post-package-changes",
() => setBulkUpdatePackageIds([]),
[],
);
const bulkUpdateMode = useMemo(() => {
const packageRowByPackageId = new Map(
packageRowsData.map((row) => [row.id, row]),
@ -106,7 +129,7 @@ export const PackageListCard = memo(function PackageListCard({
(row) =>
row.displayName.toLowerCase().includes(searchLower) ||
row.id.toLowerCase().includes(searchLower) ||
row.aliases.some((alias) =>
row.keywords.some((alias) =>
alias.toLowerCase().includes(searchLower),
),
)
@ -114,19 +137,27 @@ export const PackageListCard = memo(function PackageListCard({
);
}, [packageRowsData, search]);
const hiddenPackages = useMemo(() => {
return packageRowsData.filter(
(pkg) =>
pkg.visibleSources.size === 0 && pkg.isThereSource && !pkg.installed,
);
}, [packageRowsData]);
const visibleHiddenPackagesCount = useMemo(() => {
return hiddenPackages.filter((pkg) => filteredPackageIds.has(pkg.id))
.length;
}, [hiddenPackages, filteredPackageIds]);
const toggleShowHiddenPackages = useCallback(() => {
setShowHiddenPackages((prev) => !prev);
}, []);
const hiddenUserRepositories = useMemo(
() => new Set(repositoriesInfo?.hidden_user_repositories ?? []),
[repositoriesInfo],
);
useEffect(() => {
setBulkUpdatePackageIds((ids) => {
if (ids.length === 0) return [];
const packageIds = new Set(packageRowsData.map((p) => p.id));
return ids.filter((x) => packageIds.has(x));
});
}, [packageRowsData]);
const addBulkUpdatePackage = useCallback((row: PackageRowInfo) => {
setBulkUpdatePackageIds((prev) => {
return prev.some((id) => id === row.id) ? prev : [...prev, row.id];
@ -168,7 +199,7 @@ export const PackageListCard = memo(function PackageListCard({
return (
<Card className="grow shrink flex shadow-none w-full">
<CardContent className="w-full p-2 flex flex-col gap-2">
<CardContent className="w-full p-2 flex flex-col gap-2 compact:p-1 compact:gap-1.5">
<ManagePackagesHeading
packageRowsData={packageRowsData}
hiddenUserRepositories={hiddenUserRepositories}
@ -184,7 +215,7 @@ export const PackageListCard = memo(function PackageListCard({
cancel={() => setBulkUpdatePackageIds([])}
/>
<ScrollableCardTable
className={"h-full"}
className={"h-full rounded-md"}
ref={scrollTableOuterRef}
viewportRef={scrollTableScrollAreaRef}
>
@ -200,7 +231,7 @@ export const PackageListCard = memo(function PackageListCard({
// biome-ignore lint/suspicious/noArrayIndexKey: static array
key={index}
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground p-2.5"
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5"
}
>
<small className="font-normal leading-none">{tc(head)}</small>
@ -208,32 +239,85 @@ export const PackageListCard = memo(function PackageListCard({
))}
<th
className={
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground p-2.5"
"sticky top-0 z-10 border-b border-primary bg-secondary text-secondary-foreground px-2.5 py-1.5"
}
/>
</tr>
</thead>
<tbody>
{packageRowsData.map((row) => (
<tr
className="even:bg-secondary/30 anchor-none"
hidden={!filteredPackageIds.has(row.id)}
key={row.id}
>
<PackageRow
pkg={row}
bulkUpdateSelected={bulkUpdatePackageIds.some(
(id) => id === row.id,
)}
bulkUpdateAvailable={canBulkUpdate(
bulkUpdateMode,
bulkUpdateModeForPackage(row),
)}
addBulkUpdatePackage={addBulkUpdatePackage}
removeBulkUpdatePackage={removeBulkUpdatePackage}
/>
</tr>
))}
{packageRowsData.map((row) => {
if (
row.visibleSources.size === 0 &&
row.isThereSource &&
!row.installed
)
return null;
return (
<tr
className="even:bg-secondary/30 anchor-none"
hidden={!filteredPackageIds.has(row.id)}
key={row.id}
>
<PackageRow
pkg={row}
bulkUpdateSelected={bulkUpdatePackageIds.some(
(id) => id === row.id,
)}
bulkUpdateAvailable={canBulkUpdate(
bulkUpdateMode,
bulkUpdateModeForPackage(row),
)}
addBulkUpdatePackage={addBulkUpdatePackage}
removeBulkUpdatePackage={removeBulkUpdatePackage}
/>
</tr>
);
})}
{/* Hidden packages section */}
{hiddenPackages.length > 0 && (
<>
<tr
className="bg-secondary/50 hover:bg-secondary/70 cursor-pointer"
onClick={toggleShowHiddenPackages}
>
<td className="p-3.5 compact:py-1 w-1">
{showHiddenPackages ? (
<ChevronDown className="w-5 h-5" />
) : (
<ChevronRight className="w-5 h-5" />
)}
</td>
<td
colSpan={TABLE_HEAD.length + 1}
className="p-3.5 compact:py-1 font-medium text-sm text-muted-foreground"
>
{tc("projects:manage:hidden packages")} (
{visibleHiddenPackagesCount})
</td>
</tr>
{showHiddenPackages &&
hiddenPackages.map((row) => (
<tr
className="even:bg-secondary/30 anchor-none"
hidden={!filteredPackageIds.has(row.id)}
key={row.id}
>
<PackageRow
pkg={row}
bulkUpdateSelected={bulkUpdatePackageIds.some(
(id) => id === row.id,
)}
bulkUpdateAvailable={canBulkUpdate(
bulkUpdateMode,
bulkUpdateModeForPackage(row),
)}
addBulkUpdatePackage={addBulkUpdatePackage}
removeBulkUpdatePackage={removeBulkUpdatePackage}
/>
</tr>
))}
</>
)}
</tbody>
</ScrollableCardTable>
</CardContent>
@ -242,6 +326,29 @@ export const PackageListCard = memo(function PackageListCard({
);
});
function ShowPrereleaseConfirmDialog({
dialog,
}: {
dialog: DialogContext<boolean>;
}) {
return (
<>
<DialogTitle>
{tc("settings:dialog:show prerelease packages")}
</DialogTitle>
<div>{tc("settings:dialog:show prerelease packages description")}</div>
<DialogFooter>
<Button onClick={() => dialog.close(false)}>
{tc("general:button:cancel")}
</Button>
<Button variant="warning" onClick={() => dialog.close(true)}>
{tc("settings:dialog:enable show prerelease packages")}
</Button>
</DialogFooter>
</>
);
}
function ManagePackagesHeading({
packageRowsData,
hiddenUserRepositories,
@ -336,9 +443,11 @@ function ManagePackagesHeading({
return (
<div
className={"flex flex-wrap shrink-0 grow-0 flex-row gap-2 items-center"}
className={
"flex flex-wrap shrink-0 grow-0 flex-row gap-2 items-center gap-y-1"
}
>
<p className="cursor-pointer font-bold py-1.5 grow-0 shrink-0 pl-2">
<p className="cursor-pointer font-bold grow-0 shrink-0 pl-2">
{tc("projects:manage:manage packages")}
</p>
@ -348,7 +457,7 @@ function ManagePackagesHeading({
variant={"ghost"}
size={"icon"}
onClick={onRefresh}
className={"shrink-0"}
className="shrink-0"
disabled={isLoading || backgroundLoading}
>
{isLoading || backgroundLoading ? (
@ -372,7 +481,7 @@ function ManagePackagesHeading({
{upgradableToLatest && (
<Button
className={"shrink-0"}
className="shrink-0"
onClick={() => onUpgradeAllRequest(false)}
disabled={isLoading}
variant={"success"}
@ -384,7 +493,7 @@ function ManagePackagesHeading({
{/* show this button only if some packages are upgradable to prerelease and there is different stable */}
{upgradableToStable && (
<Button
className={"shrink-0"}
className="shrink-0"
onClick={() => onUpgradeAllRequest(true)}
disabled={isLoading}
variant={"success"}
@ -455,9 +564,21 @@ function ManagePackagesHeading({
checked={repositoriesInfo?.show_prerelease_packages}
onClick={(e) => {
e.preventDefault();
setShowPrereleasePackages.mutate(
!repositoriesInfo?.show_prerelease_packages,
);
const newValue = !repositoriesInfo?.show_prerelease_packages;
if (newValue) {
void openSingleDialog(ShowPrereleaseConfirmDialog, {})
.then((confirmed) => {
if (confirmed) {
setShowPrereleasePackages.mutate(true);
}
})
.catch((e) => {
console.error(e);
toastThrownError(e);
});
} else {
setShowPrereleasePackages.mutate(false);
}
}}
>
{tc("settings:show prerelease")}
@ -530,13 +651,6 @@ function bulkUpdateModeForPackage(pkg: PackageRowInfo): PackageBulkUpdateMode {
};
}
function hasAnyUpdate(pkg: PackageBulkUpdateMode): boolean {
for (const kind of possibleUpdateKind) {
if (pkg[kind]) return true;
}
return false;
}
function canBulkUpdate(
bulkUpdateMode: BulkUpdateMode,
possibleUpdate: PackageBulkUpdateMode,
@ -559,8 +673,6 @@ function BulkUpdateCard({
packageRowsData: PackageRowInfo[];
cancel?: () => void;
}) {
if (!bulkUpdateMode.hasPackages) return null;
const count = bulkUpdatePackageIds.length;
const { projectPath } = Route.useSearch();
const packageChange = useMutation(applyChangesMutation(projectPath));
@ -617,10 +729,11 @@ function BulkUpdateCard({
});
};
if (!bulkUpdateMode.hasPackages) return null;
return (
<Card
className={
"shrink-0 p-2 flex flex-row gap-2 bg-secondary text-secondary-foreground flex-wrap"
"shrink-0 p-2 compact:p-1 flex flex-row gap-2 compact:gap-1 bg-secondary text-secondary-foreground flex-wrap"
}
>
{bulkUpdateMode.canInstallOrUpgrade && (
@ -650,7 +763,7 @@ function BulkUpdateCard({
{tc("projects:manage:button:uninstall selected")}
</ButtonDisabledIfLoading>
)}
<ButtonDisabledIfLoading onClick={cancel}>
<ButtonDisabledIfLoading onClick={cancel} variant={"warning"}>
{tc("projects:manage:button:clear selection")}
{" ("}
{tc("projects:manage:n packages selected", { count })}
@ -792,7 +905,7 @@ const PackageRow = memo(function PackageRow({
addBulkUpdatePackage: (pkg: PackageRowInfo) => void;
removeBulkUpdatePackage: (pkg: PackageRowInfo) => void;
}) {
const cellClass = "p-2.5";
const cellClass = "p-3.5 compact:py-1";
const noGrowCellClass = `${cellClass} w-1`;
const versionNames = [...pkg.unityCompatible.keys()];
const latestVersion: string | undefined = versionNames[0];
@ -841,26 +954,26 @@ const PackageRow = memo(function PackageRow({
return (
<>
<td className={`${cellClass} w-1`}>
<CheckboxDisabledIfLoading
checked={bulkUpdateSelected}
onCheckedChange={onClickBulkUpdate}
disabled={!bulkUpdateAvailable}
className="hover:before:content-none"
/>
<td className={`${cellClass} w-1 compact:px-2`}>
<div className={"flex items-center justify-center aspect-square"}>
<CheckboxDisabledIfLoading
checked={bulkUpdateSelected}
onCheckedChange={onClickBulkUpdate}
disabled={!bulkUpdateAvailable}
className="hover:before:content-none"
/>
</div>
</td>
<td className={`${cellClass} overflow-hidden max-w-80 text-ellipsis`}>
<Tooltip
open={
pkg.description ? undefined /* auto */ : false /* disable tooltip */
}
>
<Tooltip>
<TooltipTrigger asChild>
<div
className={`flex flex-col ${pkg.installed ? "" : "opacity-50"}`}
>
<p className="font-normal">{pkg.displayName}</p>
<p className="font-normal opacity-50 text-sm">{pkg.id}</p>
<p className="font-normal opacity-50 text-sm compact:hidden">
{pkg.id}
</p>
</div>
</TooltipTrigger>
<TooltipContent className={"max-w-[80dvw]"}>
@ -869,6 +982,7 @@ const PackageRow = memo(function PackageRow({
>
{pkg.description}
</p>
<p className="font-normal opacity-50 text-sm">{pkg.id}</p>
</TooltipContent>
</Tooltip>
</td>
@ -879,27 +993,29 @@ const PackageRow = memo(function PackageRow({
<LatestPackageInfo info={pkg.latest} />
</td>
<td className={`${noGrowCellClass} max-w-32 overflow-hidden`}>
{pkg.sources.size === 0 ? (
{pkg.visibleSources.size === 0 ? (
pkg.isThereSource ? (
<p>{tc("projects:manage:source not selected")}</p>
) : (
<p>{tc("projects:manage:none")}</p>
)
) : pkg.sources.size === 1 ? (
) : pkg.visibleSources.size === 1 ? (
<Tooltip>
<TooltipTrigger>
<p className="overflow-hidden text-ellipsis">
{[...pkg.sources][0]}
{[...pkg.visibleSources][0]}
</p>
</TooltipTrigger>
<TooltipContent>{[...pkg.sources][0]}</TooltipContent>
<TooltipContent>{[...pkg.visibleSources][0]}</TooltipContent>
</Tooltip>
) : (
<Tooltip>
<TooltipTrigger>
<p>{tc("projects:manage:multiple sources")}</p>
</TooltipTrigger>
<TooltipContent>{[...pkg.sources].join(", ")}</TooltipContent>
<TooltipContent>
{[...pkg.visibleSources].join(", ")}
</TooltipContent>
</Tooltip>
)}
</td>
@ -936,9 +1052,24 @@ const PackageRow = memo(function PackageRow({
</ButtonDisabledIfLoading>
</TooltipTrigger>
<TooltipContent>
{!latestVersion
? tc("projects:manage:tooltip:incompatible with unity")
: tc("projects:manage:tooltip:add package")}
{pkg.visibleSources.size === 0 && pkg.isThereSource ? (
<div className="flex flex-col gap-1">
<p>
{tc(
"projects:manage:tooltip:select repository to install",
)}
</p>
<p className="text-xs opacity-75">
{[...pkg.sources]
.filter((source) => !pkg.visibleSources.has(source))
.join(", ")}
</p>
</div>
) : !latestVersion ? (
tc("projects:manage:tooltip:incompatible with unity")
) : (
tc("projects:manage:tooltip:add package")
)}
</TooltipContent>
</Tooltip>
)}
@ -1023,7 +1154,7 @@ const PackageVersionSelector = memo(function PackageVersionSelector({
<PackageInstalledInfo pkg={pkg} />
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectContent className="max-h-[min(24rem,45vh)]">
{/* PackageVersionList is extremely heavy */}
{isOpen && (
<PackageVersionList
@ -1065,11 +1196,7 @@ function PackageVersionList({
);
}
function PackageInstalledInfo({
pkg,
}: {
pkg: PackageRowInfo;
}) {
function PackageInstalledInfo({ pkg }: { pkg: PackageRowInfo }) {
if (pkg.installed) {
const version = toVersionString(pkg.installed.version);
if (pkg.installed.yanked) {
@ -1088,11 +1215,7 @@ function PackageInstalledInfo({
}
}
function LatestPackageInfo({
info,
}: {
info: PackageLatestInfo;
}) {
function LatestPackageInfo({ info }: { info: PackageLatestInfo }) {
const { projectPath } = Route.useSearch();
const packageChange = useMutation(applyChangesMutation(projectPath));

View file

@ -1,7 +1,7 @@
import { type ComponentProps, createContext, useContext } from "react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import { type ComponentProps, createContext, useContext } from "react";
interface PageContext {
isLoading: boolean;

View file

@ -1,10 +1,8 @@
import type { NavigateFn } from "@tanstack/react-router";
import React, { Fragment, useEffect, useState } from "react";
import { BackupProjectDialog } from "@/components/BackupProjectDialog";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import { UnitySelectorDialog } from "@/components/unity-selector-dialog";
import { assertNever } from "@/lib/assert-never";
@ -21,8 +19,6 @@ import { tc, tt } from "@/lib/i18n";
import { queryClient } from "@/lib/query-client";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { compareUnityVersionString, parseUnityVersion } from "@/lib/version";
import type { NavigateFn } from "@tanstack/react-router";
import React, { Fragment, useEffect, useState } from "react";
export async function unityVersionChange({
version: targetUnityVersion,
@ -206,14 +202,14 @@ function NoExactUnity2022Dialog({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p>
{tc(
"projects:manage:dialog:exact version unity not found for patch migration description",
{ unity: expectedVersion },
)}
</p>
</DialogDescription>
</div>
<DialogFooter className={"gap-2"}>
{installWithUnityHubLink && (
<Button
@ -242,11 +238,11 @@ function MigrationConfirmMigrationPatchDialog({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p className={"text-destructive"}>
{tc("projects:dialog:migrate unity2022 patch description", { unity })}
</p>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(null)} className="mr-1">
{tc("general:button:cancel")}
@ -269,9 +265,9 @@ function MigrationConfirmMigrationDialog({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:dialog:vpm migrate description")}</p>
</DialogDescription>
</div>
<DialogFooter className={"gap-1"}>
<Button onClick={() => dialog.close(null)}>
{tc("general:button:cancel")}
@ -330,9 +326,9 @@ function UnityVersionChange({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p className={"text-destructive"}>{mainMessage}</p>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(null)} className="mr-1">
{tc("general:button:cancel")}
@ -378,7 +374,7 @@ export function MigrationCopyingDialog({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:pre-migrate copying...")}</p>
<p>
{tc("projects:dialog:proceed k/n", {
@ -388,7 +384,7 @@ export function MigrationCopyingDialog({
</p>
<Progress value={progress.proceed} max={progress.total} />
<p>{tc("projects:do not close")}</p>
</DialogDescription>
</div>
</>
);
}
@ -397,10 +393,10 @@ function MigrationMigratingDialog({ header }: { header: React.ReactNode }) {
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:migrating...")}</p>
<p>{tc("projects:do not close")}</p>
</DialogDescription>
</div>
</>
);
}
@ -564,7 +560,7 @@ function MigrationCallingUnityForMigrationDialog({
return (
<>
<DialogTitle>{header}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:manage:dialog:unity migrate finalizing...")}</p>
<p>{tc("projects:do not close")}</p>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
@ -581,7 +577,7 @@ function MigrationCallingUnityForMigrationDialog({
))}
<div ref={ref} />
</pre>
</DialogDescription>
</div>
</>
);
}

View file

@ -1,3 +1,8 @@
import type { DefaultError } from "@tanstack/query-core";
import { queryOptions, type UseMutationOptions } from "@tanstack/react-query";
import { CircleAlert } from "lucide-react";
import type React from "react";
import { Fragment } from "react";
import { DelayedButton } from "@/components/DelayedButton";
import { ExternalLink } from "@/components/ExternalLink";
import { Button } from "@/components/ui/button";
@ -24,11 +29,6 @@ import { queryClient } from "@/lib/query-client";
import { toastInfo, toastSuccess, toastThrownError } from "@/lib/toast";
import { groupBy, keyComparator } from "@/lib/utils";
import { compareVersion, toVersionString } from "@/lib/version";
import type { DefaultError } from "@tanstack/query-core";
import { type UseMutationOptions, queryOptions } from "@tanstack/react-query";
import { CircleAlert } from "lucide-react";
import type React from "react";
import { Fragment } from "react";
export type RequestedOperation =
| {
@ -96,6 +96,7 @@ export function applyChangesMutation(projectPath: string) {
toastThrownError(e);
},
onSettled: async () => {
document.dispatchEvent(new Event("post-package-changes"));
await queryClient.invalidateQueries({
queryKey: ["projectDetails", projectPath],
});
@ -243,6 +244,12 @@ function showToast(requested: RequestedOperation) {
}
}
const TypographyItem = ({ children }: { children: React.ReactNode }) => (
<div className={"p-3"}>
<p className={"font-normal"}>{children}</p>
</div>
);
function ProjectChangesDialog({
changes,
existingPackages,
@ -260,12 +267,6 @@ function ProjectChangesDialog({
([_, c]) => c.unlocked_names,
);
const TypographyItem = ({ children }: { children: React.ReactNode }) => (
<div className={"p-3"}>
<p className={"font-normal"}>{children}</p>
</div>
);
const existingPackageMap = new Map(existingPackages ?? []);
const categorizedChanges = changes.package_changes.map(([pkgId, change]) =>
@ -615,7 +616,7 @@ function categorizeChange(
change: TauriPackageChange,
installedPackages: Map<string, TauriBasePackageInfo>,
): PackageChangeDisplayInformation {
if ("InstallNew" in change) {
if (change.InstallNew !== undefined) {
const name = change.InstallNew.display_name ?? change.InstallNew.name;
const installed = installedPackages.get(pkgId);
@ -760,13 +761,6 @@ function ChangelogButton({ url }: { url?: string | null }) {
return null;
}
function comparePackageChangeByName(
[aName]: [string, TauriPackageChange],
[bName]: [string, TauriPackageChange],
): number {
return aName.localeCompare(bName);
}
function MissingDependenciesDialog({
dependencies,
dialog,
@ -780,7 +774,7 @@ function MissingDependenciesDialog({
<CircleAlert className="size-6 inline" />{" "}
{tc("projects:manage:dialog:missing dependencies")}
</DialogTitle>
<DialogDescription>
<div>
<p className={"whitespace-normal"}>
{tc("projects:manage:dialog:missing dependencies description")}
</p>
@ -791,7 +785,7 @@ function MissingDependenciesDialog({
</li>
))}
</ul>
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close()}>
{tc("general:button:close")}

View file

@ -1,17 +1,30 @@
"use client";
import {
queryOptions,
type UseQueryResult,
useIsMutating,
useMutation,
useQueries,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import {
createFileRoute,
useNavigate,
useRouter,
} from "@tanstack/react-router";
import { ArrowLeft, ChevronDown } from "lucide-react";
import type React from "react";
import { Suspense, useMemo } from "react";
import { copyProject } from "@/app/_main/projects/manage/-copy-project";
import { BackupProjectDialog } from "@/components/BackupProjectDialog";
import { HNavBar, VStack } from "@/components/layout";
import { OpenUnityButton } from "@/components/OpenUnityButton";
import { RemoveProjectDialog } from "@/components/RemoveProjectDialog";
import { HNavBar, VStack } from "@/components/layout";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import {
DropdownMenu,
DropdownMenuContent,
@ -44,23 +57,6 @@ import { tc } from "@/lib/i18n";
import { nameFromPath } from "@/lib/os";
import { toastSuccess, toastThrownError } from "@/lib/toast";
import { compareUnityVersionString, parseUnityVersion } from "@/lib/version";
import {
type UseQueryResult,
queryOptions,
useIsMutating,
useMutation,
useQueries,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import {
createFileRoute,
useNavigate,
useRouter,
} from "@tanstack/react-router";
import { ArrowLeft, ChevronDown } from "lucide-react";
import type React from "react";
import { Suspense, useMemo } from "react";
import { combinePackagesAndProjectDetails } from "./-collect-package-row-info";
import { PackageListCard } from "./-package-list-card";
import { PageContextProvider } from "./-page-context";
@ -202,7 +198,7 @@ function PageBody() {
<PageContextProvider value={pageContext}>
<VStack>
<ProjectViewHeader
className={"shrink-0"}
className="shrink-0"
isLoading={isLoading}
detailsResult={detailsResult}
unityVersionsResult={unityVersionsResult}
@ -309,7 +305,7 @@ function UnityVersionSelector({
value={detailsResult.data?.unity_str ?? undefined}
onValueChange={requestChangeUnityVersion}
>
<SelectTrigger>
<SelectTrigger className={"compact:h-10"}>
{detailsResult.status === "success" ? (
(detailsResult.data.unity_str ?? "unknown")
) : (
@ -323,17 +319,13 @@ function UnityVersionSelector({
);
}
function SuggestResolveProjectCard({
disabled,
}: {
disabled?: boolean;
}) {
function SuggestResolveProjectCard({ disabled }: { disabled?: boolean }) {
const { projectPath } = Route.useSearch();
const packageChange = useMutation(applyChangesMutation(projectPath));
return (
<Card className={"shrink-0 p-2 flex flex-row items-center"}>
<p className="cursor-pointer py-1.5 font-bold grow-0 shrink overflow-hidden whitespace-normal text-sm">
<Card className={"shrink-0 p-2 flex flex-row items-center compact:p-1"}>
<p className="cursor-pointer py-1.5 font-bold grow-0 shrink overflow-hidden whitespace-normal text-sm pl-2">
{tc("projects:manage:suggest resolve")}
</p>
<div className={"grow shrink-0 w-2"} />
@ -435,7 +427,7 @@ function SuggestMigrateTo2022Card({
onMigrateRequested: () => void;
}) {
return (
<Card className={"shrink-0 p-2 flex flex-row items-center"}>
<Card className={"shrink-0 p-2 flex flex-row items-center compact:p-1"}>
<p className="cursor-pointer py-1.5 font-bold grow-0 shrink overflow-hidden whitespace-normal text-sm pl-2">
{tc("projects:manage:suggest unity migration")}
</p>
@ -459,7 +451,7 @@ function Suggest2022PatchMigrationCard({
onMigrateRequested: () => void;
}) {
return (
<Card className={"shrink-0 p-2 flex flex-row items-center"}>
<Card className={"shrink-0 p-2 flex flex-row items-center compact:p-1"}>
<p className="cursor-pointer py-1.5 font-bold grow-0 shrink overflow-hidden whitespace-normal text-sm pl-2">
{tc("projects:manage:suggest unity patch migration")}
</p>
@ -483,7 +475,7 @@ function SuggestChinaToInternationalMigrationCard({
onMigrateRequested: () => void;
}) {
return (
<Card className={"shrink-0 p-2 flex flex-row items-center"}>
<Card className={"shrink-0 p-2 flex flex-row items-center compact:p-1"}>
<p className="cursor-pointer py-1.5 font-bold grow-0 shrink overflow-hidden whitespace-normal text-sm pl-2">
{tc("projects:manage:suggest unity china to international migration")}
</p>
@ -520,13 +512,13 @@ function ProjectViewHeader({
return (
<HNavBar
className={`${className}`}
commonClassName={"min-h-12"}
className={className}
leading={
<>
<Tooltip>
<TooltipTrigger asChild>
<Button
className={"compact:h-10"}
variant={"ghost"}
size={"sm"}
onClick={() => history.back()}
@ -539,7 +531,7 @@ function ProjectViewHeader({
</TooltipContent>
</Tooltip>
<div className={"pl-2 space-y-0 my-1 shrink min-w-0"}>
<div className={"pl-2 space-y-0 shrink min-w-0 compact:pl-0"}>
<p className="cursor-pointer font-bold grow-0 whitespace-pre mb-0 leading-tight">
{projectName}
</p>
@ -591,13 +583,6 @@ function ProjectViewHeader({
);
}
function projectGetCustomUnityArgs(projectPath: string) {
return queryOptions({
queryKey: ["projectGetCustomUnityArgs", projectPath],
queryFn: async () => await commands.projectGetCustomUnityArgs(projectPath),
});
}
function LaunchSettings({
defaultUnityArgs,
initialValue,
@ -617,12 +602,12 @@ function LaunchSettings({
<>
<DialogTitle>{tc("projects:dialog:launch options")}</DialogTitle>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
<DialogDescription className={"max-h-[50dvh] overflow-y-auto"}>
<div className={"max-h-[50dvh] overflow-y-auto"}>
<h3 className={"text-lg"}>
{tc("projects:dialog:command-line arguments")}
</h3>
<UnityArgumentsSettings context={context} />
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(false)} variant={"destructive"}>
{tc("general:button:cancel")}
@ -750,36 +735,37 @@ function ProjectButton({
};
return (
<>
<DropdownMenu>
<div className={"flex divide-x"}>
<OpenUnityButton
projectPath={projectPath}
unityVersion={unityVersion}
unityRevision={unityRevision}
className={"rounded-r-none pl-4 pr-3"}
/>
<DropdownMenuTrigger asChild className={"rounded-l-none pl-2 pr-2"}>
<Button>
<ChevronDown className={"w-4 h-4"} />
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent>
<DropdownMenuContentBody
projectPath={projectPath}
removeProject={() => {
void openSingleDialog(RemoveProjectDialog, {
project: {
path: projectPath,
is_exists: true,
},
});
}}
onChangeLaunchOptions={onChangeLaunchOptions}
/>
</DropdownMenuContent>
</DropdownMenu>
</>
<DropdownMenu>
<div className={"flex divide-x"}>
<OpenUnityButton
projectPath={projectPath}
unityVersion={unityVersion}
unityRevision={unityRevision}
className={"rounded-r-none pl-4 pr-3 compact:h-10"}
/>
<DropdownMenuTrigger
asChild
className={"rounded-l-none pl-2 pr-2 compact:h-10"}
>
<Button>
<ChevronDown className={"w-4 h-4"} />
</Button>
</DropdownMenuTrigger>
</div>
<DropdownMenuContent>
<DropdownMenuContentBody
projectPath={projectPath}
removeProject={() => {
void openSingleDialog(RemoveProjectDialog, {
project: {
path: projectPath,
is_exists: true,
},
});
}}
onChangeLaunchOptions={onChangeLaunchOptions}
/>
</DropdownMenuContent>
</DropdownMenu>
);
}

View file

@ -1,12 +1,12 @@
"use client";
import { createFileRoute, Outlet, useLocation } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { SideBar } from "@/components/SideBar";
import { commands } from "@/lib/bindings";
import { useDocumentEvent } from "@/lib/events";
import { updateCurrentPath, usePrevPathName } from "@/lib/prev-page";
import { useEffectEvent } from "@/lib/use-effect-event";
import { Outlet, createFileRoute, useLocation } from "@tanstack/react-router";
import { useEffect, useState } from "react";
export const Route = createFileRoute("/_main")({
component: MainLayout,
@ -57,14 +57,23 @@ function MainLayout() {
}, [pathName]);
useEffect(() => {
setIsVisible(true);
(async () => {
if (await commands.environmentGuiCompact()) {
document.documentElement.setAttribute("compact", "");
} else {
document.documentElement.removeAttribute("compact");
}
setIsVisible(true);
})();
}, []);
return (
<>
<SideBar className={`grow-0 ${isVisible ? "slide-right" : ""}`} />
<SideBar
className={`grow-0 ${isVisible ? "slide-right" : "invisible"}`}
/>
<div
className={`h-screen grow overflow-hidden flex p-4 ${animationState}`}
className={`h-screen grow overflow-hidden flex p-4 compact:p-2 ${animationState}`}
onAnimationEnd={() => setAnimationState("")}
>
<Outlet />

View file

@ -1,26 +1,33 @@
"use client";
import {
queryOptions,
useMutation,
useQueryClient,
useSuspenseQuery,
} from "@tanstack/react-query";
import { createFileRoute, Link } from "@tanstack/react-router";
import { RefreshCw } from "lucide-react";
import type React from "react";
import { Suspense, useEffect, useTransition } from "react";
import Loading from "@/app/-loading";
import { CheckForUpdateMessage } from "@/components/CheckForUpdateMessage";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import {
BackupFormatSelect,
BackupPathWarnings,
FilePathRow,
GuiAnimationSwitch,
GuiCompactSwitch,
LanguageSelector,
ProjectPathWarnings,
ThemeSelector,
} from "@/components/common-setting-parts";
import { HNavBar, VStack } from "@/components/layout";
import { HNavBar, HNavBarText, VStack } from "@/components/layout";
import { ScrollableCardTable } from "@/components/ScrollableCardTable";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import {
Tooltip,
@ -44,17 +51,7 @@ import {
toastThrownError,
} from "@/lib/toast";
import { useEffectEvent } from "@/lib/use-effect-event";
import {
queryOptions,
useMutation,
useQueryClient,
useSuspenseQuery,
} from "@tanstack/react-query";
import { Link, createFileRoute } from "@tanstack/react-router";
import { RefreshCw } from "lucide-react";
import { Suspense } from "react";
import { useTransition } from "react";
import { useEffect } from "react";
import { cn } from "@/lib/utils";
export const Route = createFileRoute("/_main/settings/")({
component: Page,
@ -69,12 +66,8 @@ function Page() {
return (
<VStack>
<HNavBar
className={"shrink-0"}
leading={
<p className="cursor-pointer py-1.5 font-bold grow-0">
{tc("settings")}
</p>
}
className="shrink-0"
leading={<HNavBarText>{tc("settings")}</HNavBarText>}
/>
<Suspense
fallback={
@ -131,6 +124,18 @@ function Settings() {
);
}
function SettingsCard({
className,
children,
...props
}: React.ComponentProps<typeof Card>) {
return (
<Card className={cn("shrink-0 p-4 compact:p-3", className)} {...props}>
{children}
</Card>
);
}
function UnityHubPathCard({
updateUnityPaths,
}: {
@ -175,7 +180,7 @@ function UnityHubPathCard({
});
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard>
<h2 className={"pb-2"}>{tc("settings:unity hub path")}</h2>
<FilePathRow
path={unityHub}
@ -183,7 +188,7 @@ function UnityHubPathCard({
notFoundMessage={"Unity Hub Not Found"}
withOpen={false}
/>
</Card>
</SettingsCard>
);
}
@ -264,7 +269,7 @@ function UnityInstallationsCard({
];
return (
<Card className={"shrink-0 p-4 flex flex-col gap-2"}>
<SettingsCard className={"flex flex-col gap-2"}>
<div className={"flex align-middle"}>
<div className={"grow flex items-center"}>
<h2>{tc("settings:unity installations")}</h2>
@ -351,7 +356,7 @@ function UnityInstallationsCard({
{tc("settings:use legacy unity hub loading description")}
</p>
</div>
</Card>
</SettingsCard>
);
}
@ -365,7 +370,7 @@ function UnityLaunchArgumentsCard() {
const realUnityArgs = unityArgs ?? defaultUnityArgs;
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard>
<div className={"mb-2 flex align-middle"}>
<div className={"grow flex items-center"}>
<h2>{tc("settings:default unity arguments")}</h2>
@ -392,10 +397,11 @@ function UnityLaunchArgumentsCard() {
</p>
<ol className={"flex flex-col"}>
{realUnityArgs.map((v, i) => (
// biome-ignore lint/suspicious/noArrayIndexKey: unity args are ordered list
<Input disabled key={i + v} value={v} className={"w-full"} />
))}
</ol>
</Card>
</SettingsCard>
);
}
@ -446,9 +452,9 @@ function LaunchArgumentsEditDialogBody({
{tc("settings:dialog:default launch arguments")}
</DialogTitle>
{/* TODO: use ScrollArea (I failed to use it inside dialog) */}
<DialogDescription className={"max-h-[50dvh] overflow-y-auto"}>
<div className={"max-h-[50dvh] overflow-y-auto"}>
<UnityArgumentsSettings context={context} />
</DialogDescription>
</div>
<DialogFooter>
<Button onClick={() => dialog.close(false)} variant={"destructive"}>
{tc("general:button:cancel")}
@ -505,7 +511,7 @@ function DefaultProjectPathCard() {
});
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard>
<h2 className={"mb-2"}>{tc("settings:default project path")}</h2>
<p className={"whitespace-normal"}>
{tc("settings:default project path description")}
@ -515,7 +521,7 @@ function DefaultProjectPathCard() {
pick={pickProjectDefaultPath.mutate}
/>
<ProjectPathWarnings projectPath={defaultProjectPath} />
</Card>
</SettingsCard>
);
}
@ -578,7 +584,7 @@ function BackupCard() {
});
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard>
<h2>{tc("projects:backup")}</h2>
<div className="mt-2">
<h3>{tc("settings:backup:path")}</h3>
@ -614,7 +620,7 @@ function BackupCard() {
{tc("settings:backup:exclude vpm packages from backup description")}
</p>
</div>
</Card>
</SettingsCard>
);
}
@ -671,7 +677,7 @@ function PackagesCard() {
});
return (
<Card className={"shrink-0 p-4 flex flex-col gap-4"}>
<SettingsCard className={"flex flex-col gap-4"}>
<h2>{tc("settings:packages")}</h2>
<div className={"flex flex-row flex-wrap gap-2"}>
<Button onClick={() => clearPackageCache.mutate()}>
@ -690,18 +696,19 @@ function PackagesCard() {
{tc("settings:show prerelease description")}
</p>
</div>
</Card>
</SettingsCard>
);
}
function AppearanceCard() {
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard className={"flex flex-col gap-2"}>
<h2>{tc("settings:appearance")}</h2>
<LanguageSelector />
<ThemeSelector />
<GuiAnimationSwitch />
</Card>
<GuiCompactSwitch />
</SettingsCard>
);
}
@ -724,7 +731,7 @@ function FilesAndFoldersCard() {
};
return (
<Card className={"shrink-0 p-4"}>
<SettingsCard>
<h2>{tc("settings:files and directories")}</h2>
<p className={"mt-2"}>
{tc("settings:files and directories:description")}
@ -751,7 +758,7 @@ function FilesAndFoldersCard() {
{tc("settings:button:open vcc templates")}
</Button>
</div>
</Card>
</SettingsCard>
);
}
@ -863,7 +870,7 @@ function AlcomCard() {
};
return (
<Card className={"shrink-0 p-4 flex flex-col gap-4"}>
<SettingsCard className={"flex flex-col gap-4"}>
<h2>ALCOM</h2>
<div className={"flex flex-row flex-wrap gap-2"}>
{globalInfo.checkForUpdates && (
@ -928,7 +935,7 @@ function AlcomCard() {
},
)}
</p>
</Card>
</SettingsCard>
);
}
@ -936,7 +943,7 @@ function SystemInformationCard() {
const info = useGlobalInfo();
return (
<Card className={"shrink-0 p-4 flex flex-col gap-4"}>
<SettingsCard className={"flex flex-col gap-4"}>
<h2>{tc("settings:system information")}</h2>
<dl>
<dt>{tc("settings:os")}</dt>
@ -950,6 +957,6 @@ function SystemInformationCard() {
<dt>{tc("settings:alcom commit hash")}</dt>
<dd className={"opacity-50 mb-2"}>{info.commitHash}</dd>
</dl>
</Card>
</SettingsCard>
);
}

View file

@ -1,9 +1,9 @@
"use client";
import licenses from "build:licenses.json";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { ScrollableCard } from "@/components/ScrollableCard";
import { VStack } from "@/components/layout";
import { ScrollableCard } from "@/components/ScrollableCard";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { Card } from "@/components/ui/card";
import { commands } from "@/lib/bindings";
@ -20,7 +20,7 @@ export default function RenderPage() {
<ul />
</Card>
{licenses.map((license, idx) => (
{licenses.map((license) => (
<Card className={"p-4"} key={license.text}>
<h3>{license.name}</h3>
<h4>Used by:</h4>

View file

@ -1,10 +1,10 @@
import licenses from "build:licenses.json";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { ScrollableCard } from "@/components/ScrollableCard";
import { createFileRoute } from "@tanstack/react-router";
import { VStack } from "@/components/layout";
import { ScrollableCard } from "@/components/ScrollableCard";
import { ScrollPageContainer } from "@/components/ScrollPageContainer";
import { Card } from "@/components/ui/card";
import { commands } from "@/lib/bindings";
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/_main/settings/licenses/")({
component: Page,
@ -23,7 +23,7 @@ function Page() {
<ul />
</Card>
{licenses.map((license, idx) => (
{licenses.map((license) => (
<Card className={"p-4"} key={license.text}>
<h3>{license.name}</h3>
<h4>Used by:</h4>

View file

@ -1,8 +1,8 @@
"use client";
import {
Outlet,
createFileRoute,
Outlet,
useNavigate,
useRouter,
} from "@tanstack/react-router";

View file

@ -1,13 +1,13 @@
import { useQuery } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { Circle, CircleCheck, CircleChevronRight } from "lucide-react";
import type React from "react";
import { Button } from "@/components/ui/button";
import { Card, CardFooter, CardHeader } from "@/components/ui/card";
import type { SetupPages, TauriEnvironmentSettings } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
import { useGlobalInfo } from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import { useQuery } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { Circle, CircleCheck, CircleChevronRight } from "lucide-react";
import type React from "react";
export type BodyProps = Readonly<{
environment: TauriEnvironmentSettings;
@ -52,9 +52,9 @@ export function SetupPageBase({
<div className={"flex gap-4"}>
{!withoutSteps && <StepCard current={pageId} />}
<Card
className={`${withoutSteps ? "w-[30rem]" : "w-96"} min-w-[50vw] min-h-[max(50dvh,20rem)] p-4 flex gap-3`}
className={`${withoutSteps ? "w-[30rem]" : "w-96"} min-w-[50vw] min-h-[max(50dvh,20rem)] p-4 flex gap-3 compact:min-h-[max(40dvh,20rem)]`}
>
<div className={"flex flex-col grow"}>
<div className={"flex flex-col grow gap-3 compact:gap-2"}>
<CardHeader>
<h1 className={"text-center"}>{heading}</h1>
</CardHeader>
@ -65,7 +65,7 @@ export function SetupPageBase({
<Body environment={result.data} />
)}
<div className={"grow"} />
<CardFooter className="p-0 pt-3 items-end flex-row gap-2 justify-end">
<CardFooter className="p-0 pt-3 items-end flex-row gap-2 justify-end compact:-m-2">
{prevPage && (
<Button onClick={() => navigate({ to: prevPage })}>
{backContent}
@ -80,11 +80,7 @@ export function SetupPageBase({
);
}
function StepCard({
current,
}: {
current: SetupPages | null;
}) {
function StepCard({ current }: { current: SetupPages | null }) {
// TODO: get progress from backend
const finisheds = useQuery({
queryKey: ["environmentGetFinishedSetupPages"],

View file

@ -1,13 +1,14 @@
"use client";
import { createFileRoute } from "@tanstack/react-router";
import {
GuiAnimationSwitch,
GuiCompactSwitch,
LanguageSelector,
ThemeSelector,
} from "@/components/common-setting-parts";
import { CardDescription } from "@/components/ui/card";
import { tc } from "@/lib/i18n";
import { createFileRoute } from "@tanstack/react-router";
import { SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/appearance/")({
@ -40,6 +41,7 @@ function Body() {
<LanguageSelector />
<ThemeSelector />
<GuiAnimationSwitch />
<GuiCompactSwitch />
</>
);
}

View file

@ -1,5 +1,7 @@
"use client";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import {
BackupFormatSelect,
BackupPathWarnings,
@ -11,8 +13,6 @@ import { commands } from "@/lib/bindings";
import { useGlobalInfo } from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { type BodyProps, SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/backups/")({

View file

@ -1,9 +1,9 @@
"use client";
import { createFileRoute } from "@tanstack/react-router";
import { CardDescription } from "@/components/ui/card";
import { useGlobalInfo } from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import { createFileRoute } from "@tanstack/react-router";
import { SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/finish/")({

View file

@ -1,5 +1,7 @@
"use client";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import {
FilePathRow,
ProjectPathWarnings,
@ -9,8 +11,6 @@ import { assertNever } from "@/lib/assert-never";
import { commands } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { type BodyProps, SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/project-path/")({

View file

@ -1,10 +1,5 @@
"use client";
import { Checkbox } from "@/components/ui/checkbox";
import { commands } from "@/lib/bindings";
import { useGlobalInfo } from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import {
queryOptions,
useMutation,
@ -12,6 +7,11 @@ import {
useQueryClient,
} from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { Checkbox } from "@/components/ui/checkbox";
import { commands } from "@/lib/bindings";
import { useGlobalInfo } from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import { toastThrownError } from "@/lib/toast";
import { type BodyProps, SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/system-setting/")({

View file

@ -1,5 +1,7 @@
"use client";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { FilePathRow } from "@/components/common-setting-parts";
import {
Accordion,
@ -13,8 +15,6 @@ import { assertNever } from "@/lib/assert-never";
import { commands } from "@/lib/bindings";
import { tc, tt } from "@/lib/i18n";
import { toastError, toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { type BodyProps, SetupPageBase } from "../-setup-page-base";
export const Route = createFileRoute("/_setup/setup/unity-hub/")({

View file

@ -2,6 +2,7 @@
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@custom-variant compact (&:is([compact] *));
@theme inline {
--background-image-gradient-radial: radial-gradient(var(--tw-gradient-stops));
@ -98,7 +99,7 @@
--secondary: hsl(240 4.8% 95.9%);
--secondary-foreground: hsl(240 5.9% 10%);
--muted: hsl(240 4.8% 95.9%);
--muted-foreground: hsl(240 3.8% 46.1%);
--muted-foreground: oklch(0.556 0 0);
--accent: hsl(240 4.8% 95.9%);
--accent-foreground: hsl(240 5.9% 30%);
--info: hsl(207 90% 54%);
@ -134,7 +135,7 @@
--secondary: var(--secondary-bg);
--secondary-foreground: var(--fg-color);
--muted: var(--secondary-bg);
--muted-foreground: 240 5% 74%;
--muted-foreground: oklch(0.708 0 0);
--accent: var(--secondary-bg);
--accent-foreground: var(--fg-color);
--info: hsl(207 90% 54%);
@ -170,7 +171,7 @@
--secondary: var(--secondary-bg);
--secondary-foreground: var(--fg-color);
--muted: var(--secondary-bg);
--muted-foreground: 240 5% 74%;
--muted-foreground: oklch(0.708 0 0);
--accent: var(--secondary-bg);
--accent-foreground: var(--fg-color);
--info: hsl(207 90% 54%);
@ -187,7 +188,7 @@
}
}
:root {
body {
--toastify-font-family: var(--font-sans);
--toastify-color-light: var(--background);
/*--toastify-color-info: #3498db;*/
@ -286,6 +287,7 @@ html {
/* Radix ui sets display:block for each scroll viewport element but it seem it make worse */
[data-radix-scroll-area-viewport] > div {
/* biome-ignore lint/complexity/noImportantStyles: necessary to override element */
display: block !important;
}
@ -293,13 +295,25 @@ html {
* Add padding end for horizontal scroll bar of scrollable card if vertical scroll bar is invisible
* This prevents the horizontal scroll bar hide corner of the card
*/
.vrc-get-scrollable-card:not(:has(> .vrc-get-scrollable-card-vertical-bar))
> div[data-radix-scroll-area-viewport]
.vrc-get-scrollable-card:not(
:has(> .vrc-get-scrollable-card-vertical-bar)
) > div[data-radix-scroll-area-viewport]
> div
> div.vrc-get-scrollable-card-horizontal-bar {
@apply pe-2.5;
}
/*
* Add padding end for the content area of scrollable card if vertical scroll bar is visible
* This prevents the table / items from being hidden behind the vertical scroll bar
*/
.vrc-get-scrollable-card:has(
> .vrc-get-scrollable-card-vertical-bar
) > div[data-radix-scroll-area-viewport]
> div {
@apply pe-2.5;
}
.vrc-get-sidebar-hostname-warning-container {
contain-intrinsic-size: 0 7em;
contain: size;

View file

@ -1,5 +1,5 @@
import { createFileRoute, Outlet } from "@tanstack/react-router";
import ErrorPage from "@/app/-error";
import { Outlet, createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/")({
component: RouteComponent,
@ -7,9 +7,5 @@ export const Route = createFileRoute("/")({
});
function RouteComponent() {
return (
<>
<Outlet />
</>
);
return <Outlet />;
}

View file

@ -1,15 +1,16 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"files": {
"ignore": [
"project-templates",
"node_modules",
".next",
"out",
"gen",
"lib/bindings.ts",
"lib/routeTree.gen.ts",
"build"
"includes": [
"**",
"!project-templates",
"!node_modules",
"!.next",
"!out",
"!gen",
"!lib/bindings.ts",
"!lib/routeTree.gen.ts",
"!build"
]
},
"formatter": {
@ -24,9 +25,20 @@
// In my opinion, '!.' => '?.' is not reasonable for all cases, so I disabled automatic fix.
"fix": "none",
"level": "error"
},
"noRestrictedGlobals": {
"level": "error",
"options": {
"deniedGlobals": {
"close": "window.close is unlikely to be called"
}
}
}
},
"suspicious": {
// false positives with tailwind css
// see https://github.com/biomejs/biome/issues/7223
"noUnknownAtRules": "off",
"noAssignInExpressions": "off"
},
"correctness": {
@ -63,7 +75,16 @@
},
"enabled": true
},
"organizeImports": {
"enabled": true
"assist": {
"actions": {
"source": {
"organizeImports": "on"
}
}
},
"css": {
"parser": {
"tailwindDirectives": true
}
}
}

View file

@ -1,3 +1,3 @@
thumbnail.png
thumbnail.*.svg
booth.zip
app-icon.png

View file

@ -1,9 +1,11 @@
npm.install:
npm install
thumbnail.embed.svg: thumbnail.svg alcom-dark.png alcom-light.png ../app-icon.png
node embeder.mjs thumbnail.embed.svg thumbnail.svg alcom-dark.png alcom-light.png ../app-icon.png
app-icon.png: ../app-icon.png
cp ../app-icon.png app-icon.png
thumbnail.png: thumbnail.embed.svg
npx sharp -i thumbnail.embed.svg -o thumbnail.png
thumbnail.png: thumbnail.svg alcom-dark.png alcom-light.png app-icon.png
rsvg-convert thumbnail.svg -o thumbnail.png
booth.zip: website.url README.ja.txt README.en.txt LICENSE
zip -r $@ $^

View file

@ -1,15 +0,0 @@
import * as fs from "node:fs/promises";
const output = process.argv[2];
const input = process.argv[3];
let inputText = await fs.readFile(input, { encoding: "utf-8" });
for (let i = 4; i < process.argv.length; i++) {
const embedPath = process.argv[i];
const embedDataBase64 = await fs.readFile(embedPath, { encoding: "base64" });
const embedDataUrl = `data:image/png;base64,${embedDataBase64}`;
inputText = inputText.replace(`"${embedPath}"`, `"${embedDataUrl}"`);
}
await fs.writeFile(output, inputText);

View file

@ -2,9 +2,9 @@
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
>
<rect x="0" y="0" width="4096" height="4096" style="fill:rgb(45,45,45);"/>
<image x="-95" y="1013" width="3149px" height="2021" xlink:href="alcom-light.png"/>
<image x="980" y="1670" width="3216px" height="2064" xlink:href="alcom-dark.png"/>
<image x="254" y="138" width="844px" height="844px" xlink:href="../app-icon.png"/>
<image x="-95" y="1013" width="3149px" height="2021" xlink:href="./alcom-light.png"/>
<image x="980" y="1670" width="3216px" height="2064" xlink:href="./alcom-dark.png"/>
<image x="254" y="138" width="844px" height="844px" xlink:href="./app-icon.png"/>
<text x="1286" y="679" class="NotoSansBold Green">ALCOM</text>
<text x="1286" y="918" class="NotoSansMediumItalic Green">Fast VCC alternative for any desktop</text>

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 3 KiB

Before After
Before After

View file

@ -100,5 +100,5 @@ fn get_commit_hash() {
return;
};
println!("cargo:rustc-env=COMMIT_HASH={}", hash_value);
println!("cargo:rustc-env=COMMIT_HASH={hash_value}");
}

View file

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>ALCOM VCC URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>vcc</string>
</array>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>ALCOM Project Template</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSItemContentTypes</key>
<array>
<string>com.anatawa12.vrc-get.alcomtemplate</string>
</array>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeIdentifier</key>
<string>com.anatawa12.vrc-get.alcomtemplate</string>
<key>UTTypeIcons</key>
<dict>
<key>UTTypeIconText</key>
<string>Template</string>
<key>UTTypeIconBackgroundName</key>
<string></string>
<key>UTTypeIconBadgeName</key>
<string>icon.icns</string>
</dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.content</string>
</array>
<key>UTTypeDescription</key>
<string>ALCOM Project Template</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>alcomtemplate</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,9 @@
[Desktop Entry]
Categories=Development
Comment=ALCOM - Alternative Creator Companion
Exec={{exec}} %u
Icon=alcom
Name=ALCOM
Terminal=false
Type=Application
MimeType=x-scheme-handler/vcc

View file

@ -0,0 +1,70 @@
Name: alcom
Version: 1.1.6
Release: 1%{?dist}
Summary: A short description of my custom application
%global git_version %(echo "%{version}" | tr '~' '-')
License: MIT
URL: https://vrc-get.anatawa12.com/alcom/
Source0: https://github.com/vrc-get/vrc-get/archive/gui-v%{git_version}.tar.gz
BuildRequires: gcc
BuildRequires: nodejs
BuildRequires: npm
BuildRequires: pkgconfig(gtk+-3.0)
BuildRequires: pkgconfig(webkit2gtk-4.1)
BuildRequires: pkgconfig(openssl)
# we download rust toolchain manually when building inside mock container
%if ! 0%{?install_rust:1}
BuildRequires: cargo
%endif
# disable stripping symbols.
%global __os_install_post %{nil}
%global debug_package %{nil}
%description
ALCOM - Alternative Creator Companion
ALCOM is a fast and open-source alternative VCC (VRChat Creator Companion) written in rust and tauri.
%prep
%setup -q -n vrc-get-gui-v%{git_version}
%if 0%{?install_rust:1}
echo "=== Mock environment detected. Installing isolated Rust toolchain ==="
export RUSTUP_HOME="$(pwd)/.rustup"
export CARGO_HOME="$(pwd)/.cargo"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
cat << EOF > ./load_rust_env.sh
export RUSTUP_HOME="${RUSTUP_HOME}"
export CARGO_HOME="${CARGO_HOME}"
source "${CARGO_HOME}/env"
EOF
%endif
# marker: ci inserts version update here
%build
%{?install_rust: source ./load_rust_env.sh}
cargo xtask build-alcom --release
%install
%{?install_rust: source ./load_rust_env.sh}
rm -rf %{buildroot}
cargo xtask bundle-alcom --release --bundles buildroot --buildroot=%{buildroot}
%files
%license LICENSE
# %doc vrc-get-gui/README.md
#%doc vrc-get-gui/CHANGELOG.md
%{_bindir}/alcom
%{_datadir}/applications/alcom.desktop
%{_datadir}/icons/hicolor/*/apps/alcom.png
%changelog
* Migrated to native rpm build pipeline with spec file

7
vrc-get-gui/bundle/debian/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
/*-build-stamp
/*.substvars
/.debhelper
/files
/cargo_home
/npm_cache
alcom/

View file

@ -0,0 +1,5 @@
alcom for Debian
ALCOM is a fast and open-source alternative VCC (VRChat Creator Companion) written in rust and tauri.
-- anatawa12 <i@anatawa12.com> Thu, 11 Jun 2026 14:34:57 +0000

View file

@ -0,0 +1,20 @@
alcom for Debian
This is README for alcom Debian package.
This Debian package is made to provide one of official distribution of alcom, formaly known as vrc-get-gui.
Starting with 1.1.7 or later, alcom maintainer switched from custom .deb toolchain to official .deb toolchain.
This directory contains source code of debian package as non-native package.
This directory is placed at vrc-get-gui/bundles/debian on original source tree, but before building debian package,
you must copy vrc-get-gui/bundles/debian to debian.
Violating best practice of debian package, this package requires network access, to download cargo dependencies on build.
In addition, by declaring `INSTALL_RUST` environment variable to `1` with `--set-envvar=INSTALL_RUST=1`, you can let
build process to install newest available rust to build on older distribution does not provide new enough rust version.
You also install NODEJS on build by declaring `INSTALL_NODEJS=1`.
Those options are helpful when building inside sandbox like pbuilder.
This Debian package is based on package generated by debmake Version 4.5.1.
-- anatawa12 <i@anatawa12.com> Thu, 11 Jun 2026 14:34:57 +0000

View file

@ -0,0 +1,5 @@
alcom (1.1.6-1) UNRELEASED; urgency=low
* No changelog are provided for this package
-- root <i@anatawa12.com> Thu, 11 Jun 2026 14:34:57 +0000

View file

@ -0,0 +1,8 @@
target/
vrc-get-gui/node_modules/
vrc-get-gui/out/
vrc-get-gui/gen/
debian/cargo_home/
debian/npm_cache/
debian/rustup_home/
debian/nodejs_installed/

View file

@ -0,0 +1,29 @@
Source: alcom
Priority: optional
Maintainer: anatawa12 <i@anatawa12.com>
Build-Depends:
debhelper-compat (= 13),
libssl-dev,
pkg-config,
cargo,
nodejs,
npm,
# curl for rust-install build only
curl,
libgtk-3-dev,
libwebkit2gtk-4.1-dev (>= 2.41),
Standards-Version: 4.7.0
Homepage: https://vrc-get.anatawa12.com/alcom/
Rules-Requires-Root: no
Package: alcom
Architecture: any
Multi-Arch: foreign
Depends:
${misc:Depends},
${shlibs:Depends},
Description: ALCOM - Alternative Creator Companion
ALCOM is a fast and open-source alternative VCC (VRChat Creator Companion) written in rust and tauri.
.
This package is one of official distribution of ALCOM, released as a part of the updates from ALCOM.
No packaging only updates will be provided.

View file

@ -0,0 +1,41 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: alcom
Upstream-Contact: <preferred name and address to reach the upstream project>
Source: <url://example.com>
Files: *
Copyright: Copyright (c) 2023 anatawa12 and other contribcmeutors
License: MIT
MIT License
.
Copyright (c) 2023 anatawa12 and other contributors
.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
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.
.
Files: vrc-get-gui/third-party/Anton-Regular.ttf
vrc-get-gui/third-party/NotoSans-Italic-VariableFont_wdth,wght.ttf
vrc-get-gui/third-party/NotoSans-VariableFont_wdth,wght.ttf
Copyright: 2020 The Anton Project Authors (https://github.com/googlefonts/AntonFont.git)
2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)
License: SIL Open Font License 1.1
Files: vrc-get-gui/icons/*
Copyright: 2024 lilxyzw, anatawa12 and other contributors
License: CC-BY-4.0

39
vrc-get-gui/bundle/debian/rules Executable file
View file

@ -0,0 +1,39 @@
#!/usr/bin/make -f
export DEB_BUILD_OPTIONS += nostrip
export CARGO_HOME = $(CURDIR)/debian/cargo_home
export NPM_CONFIG_CACHE = $(CURDIR)/debian/npm_cache
%:
dh $@
# install rust in configure phase when requested
ifeq ($(INSTALL_RUST),1)
export RUSTUP_HOME = $(CURDIR)/debian/rustup_home
export PATH := $(CURDIR)/debian/cargo_home/bin:$(PATH)
override_dh_auto_configure::
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
endif
ifeq ($(INSTALL_NODEJS),1)
export RUSTUP_HOME = $(CURDIR)/debian/rustup_home
export PATH := $(CURDIR)/debian/nodejs_installed/bin:$(PATH)
ifeq ($(DEB_HOST_ARCH),amd64)
NODE_ARCH := x64
else ifeq ($(DEB_HOST_ARCH),arm64)
NODE_ARCH := arm64
endif
override_dh_auto_configure::
mkdir -p $(CURDIR)/debian/nodejs_installed
curl --proto '=https' --tlsv1.2 -sSf https://nodejs.org/dist/v26.3.0/node-v26.3.0-linux-$(NODE_ARCH).tar.gz | gunzip | tar x --strip-components 1 -C $(CURDIR)/debian/nodejs_installed
endif
override_dh_auto_build:
cargo xtask build-alcom --release
override_dh_auto_install:
cargo xtask bundle-alcom --release --bundles buildroot --buildroot=$(CURDIR)/debian/alcom

View file

@ -0,0 +1 @@
3.0 (quilt)

View file

@ -0,0 +1,24 @@
# Metadata about the upstream project.
# See https://wiki.debian.org/UpstreamMetadata
Bug-Database: https://github.com/vrc-get/vrc-get/issues
Bug-Submit: https://github.com/vrc-get/vrc-get/issues/new
Changelog: https://github.com/vrc-get/vrc-get/blob/master/vrc-get-gui/CHANGELOG.md
Documentation: https://vrc-get.anatawa12.com/alcom/
Repository-Browse: https://github.com/vrc-get/vrc-get
Repository: https://github.com/vrc-get/vrc-get.git
#FAQ: https://github.com/<user>/<project>/blob/main/FAQ.md
Donation: https://github.com/sponsors/anatawa12
#Registration: https://github.com/signup
#Archive: PyPI # or CPAN, boost, etc.
# Uncomment these and fill them out to help users evaluate upstream:
#Gallery: https://github.com/<user>/<project>/wiki/pictures-made-with-this-program
#Screenshots: # pictures *of* the program, as opposed to pictures *made with* the program
# - https://github.com/<user>/<project>/wiki/login-screen.png
# - https://github.com/<user>/<project>/wiki/help-menu.png
# - ...
# Uncomment these and fill them out to help resolve security issues:
#Security-Contact: <how to send security-related messages>
#CPE: <space-separated Common Platform Enumerator values - see https://wiki.debian.org/CPEtagPackagesDep>

View file

@ -0,0 +1,10 @@
# You must remove unused comment lines for the released package.
# Compulsory line, this is a version 4 file
version=4
opts=\
filenamemangle=s%.*/@ANY_VERSION@%@PACKAGE@-$1.tar.gz%,\
downloadurlmangle=s%(api.github.com/repos/[^/]+/[^/]+)/git/refs/%$1/tarball/refs/%g,\
uversionmangle=s/(\d)[-]?((RC|rc|pre|dev|beta|alpha)\.\d*)$/$1~$2/,\
searchmode=plain \
https://api.github.com/repos/vrc-get/vrc-get/git/matching-refs/tags/gui- \
https://api.github.com/repos/[^/]+/[^/]+/git/refs/tags/gui-@ANY_VERSION@

Binary file not shown.

View file

@ -0,0 +1,211 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
; Non-commercial use only
#ifndef ApplicationVersion
#error ApplicationVersion is not defined. Define with -DApplicationVersion=
#endif
#ifndef WebView2SetupPath
#error WebView2SetupPath is not defined. Define with -DWebView2SetupPath=
#endif
#ifndef ApplicationPath
#error ApplicationPath is not defined. Define with -DApplicationPath=LicensePath
#endif
#ifndef LicensePath
#error LicensePath is not defined. Define with -DLicensePath=
#endif
#define MyAppName "ALCOM"
#define MyAppPublisher "anatawa12"
#define MyAppURL "https://vrc-get.anatawa12.com/alcom/"
#define MyAppExeName "ALCOM.exe"
#define MyAppAssocName "ALCOM Template"
#define MyAppAssocExt ".alcomtemplate"
#define MyAppAssocKey "ALCOM Project Template"
[Setup]
AppId={{4C3D0631-AE29-4D20-A231-678D9CF8D6DB}
AppName={#MyAppName}
AppVersion={#ApplicationVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
UninstallDisplayIcon={app}\{#MyAppExeName}
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
; on anything but x64 and Windows 11 on Arm.
ArchitecturesAllowed=x64compatible
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
; meaning it should use the native 64-bit Program Files directory and
; the 64-bit view of the registry.
ArchitecturesInstallIn64BitMode=x64compatible
ChangesAssociations=yes
DisableProgramGroupPage=yes
LicenseFile={#LicensePath}
; Remove the following line to run in administrative install mode (install for all users).
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
OutputBaseFilename=alcom
SolidCompression=yes
WizardStyle=modern dynamic
; allow users to install ALCOM to different location than before.
; this would cause ALCOM to be installed to multiple location, but user may move ALCOM
; without uninstalling ALCOM so this is 'safer' option than normal one.
DisableDirPage=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl"
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
[Files]
Source: "{#ApplicationPath}"; DestDir: "{app}"; DestName: "{#MyAppExeName}"; Flags: ignoreversion
Source: "{#WebView2SetupPath}"; DestName: "MicrosoftEdgeWebView2Setup.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Registry]
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0"
Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1"""
[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
; No skipifsilent to relaunch after application quit
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall runasoriginaluser
[Code]
// NSIS to inno setup migrations
// There are many differences between nsis and inno setup.
// (There are more changes than following in default settings but can be fixed by changing settings)
// We'll fix following changes in each ways.
// (Following uses bash-like fallback style: ${Variable:-fallbackValue} and HKLM/-style path for reference
// - default installation path changes
// NSIS: ${LOCALAPPDATA}\ALCOM
// Inno Setup: ${FOLDERID_UserProgramFiles:-${LOCALAPPDATA}/Programs}/${AppName}
// No relocation will be done for installation location since updating will break existing shortcuts.
// We'll let inno setup to use old location when no inno setup detected
// - Registry key for remove entry
// NSIS: HKA\Software\Microsoft\Windows\CurrentVersion\Uninstall\ALCOM
// Inno Setup: HKA\Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppId}_is1
// (source: https://github.com/jrsoftware/issrc/blob/7d001a7eaa056a4b43bc89f6ff09c4edd213585d/Projects/Src/Setup.MainFunc.pas#L3123)
// We will remove the old key
// - Previous installation registry entry
// NSIS: HKA\Software\anatawa12\vrc-get-gui ""
// Inno Setup: HKA\Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppId}_is1 "Inno Setup: App Path"
// We will remove the old key and copy previous install to new one
// - Previous installer language
// NSIS: HKA\Software\anatawa12\vrc-get-gui "Installer Language"
// Inno Setup: HKA\Software\Microsoft\Windows\CurrentVersion\Uninstall\${AppId}_is1 "Inno Setup: Language"
// We will remove the old key, but no migration will be done
var NsisMigration: Boolean;
procedure InitializeWizard();
var
NsisInstallPath: string;
begin
if (WizardForm.PrevAppDir = '') and not IsAdminInstallMode then
begin
// Inno setup previous installation not found.
// We'll find NSIS install information
Log('No Inno Setup installation found while single user installation is enabled, trying migration from NSIS');
if RegQueryStringValue(HKEY_CURRENT_USER, 'Software\anatawa12\vrc-get-gui', '', NsisInstallPath) then
begin
Log('Previous NSIS installation path found: ' + NsisInstallPath);
NsisMigration := True;
WizardForm.DirEdit.Text := NsisInstallPath;
// We want to set PrevAppDir to new value to prevent 'directly alredy exists' warning,
// but pascal runtime in inno setup doesn't allow us to access private fields so we leave it.
end
end;
end;
procedure PostInstallNsisMigration();
begin
if NsisMigration then
begin
// remove old uninstall entry
RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER, 'Software\anatawa12\vrc-get-gui');
RegDeleteKeyIfEmpty(HKEY_CURRENT_USER, 'Software\anatawa12');
RegDeleteKeyIncludingSubkeys(HKEY_CURRENT_USER, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\ALCOM');
// remove uninstaller from NSIS
DeleteFile(ExpandConstant('{app}\uninstall.exe'))
end;
end;
// webview2 installation
const WebView2RegKey = 'SOFTWARE\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}';
// Check both HKLM32 and HKCU for user install.
// Check HKLM32 twice for system install.
// We always check HKLM32 even our system use 64bit.
function IsWebView2Installed: Boolean;
begin
Result := RegKeyExists(HKLM32, WebView2RegKey) or RegKeyExists(HKA, WebView2RegKey);
end;
function InstallWebView2: Boolean;
var
InstallerPath: string;
ResultCode: Integer;
begin
Result := False;
InstallerPath :=
ExpandConstant('{tmp}\MicrosoftEdgeWebView2Setup.exe');
if not Exec(
InstallerPath,
'/silent /install',
'',
SW_HIDE,
ewWaitUntilTerminated,
ResultCode
) then
begin
MsgBox('Failed to launch WebView2 installer.', mbError, MB_OK);
exit;
end;
if ResultCode <> 0 then
begin
MsgBox(
'WebView2 installation failed. Exit code: ' + IntToStr(ResultCode),
mbError,
MB_OK
);
exit;
end;
Result := True;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssInstall then
begin
if not IsWebView2Installed then
begin
if not InstallWebView2 then
begin
Abort;
end;
end;
end;
if CurStep = ssPostInstall then
begin
PostInstallNsisMigration;
end;
end;

View file

@ -1,9 +1,7 @@
import type React from "react";
import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import type { TauriCreateBackupProgress } from "@/lib/bindings";
import { commands } from "@/lib/bindings";
@ -12,9 +10,6 @@ import type { DialogContext } from "@/lib/dialog";
import { tc } from "@/lib/i18n";
import { toastNormal, toastSuccess } from "@/lib/toast";
import { useEffectEvent } from "@/lib/use-effect-event";
import type React from "react";
import { useRef } from "react";
import { useEffect, useState } from "react";
export function BackupProjectDialog({
projectPath,
@ -70,7 +65,7 @@ export function BackupProjectDialog({
return (
<div className={"contents whitespace-normal"}>
<DialogTitle>{header ?? tc("projects:dialog:backup header")}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("projects:dialog:creating backup...")}</p>
<p>
{tc("projects:dialog:proceed k/n", {
@ -82,7 +77,7 @@ export function BackupProjectDialog({
{progress.last_proceed || "Collecting files..."}
</p>
<Progress value={progress.proceed} max={progress.total} />
</DialogDescription>
</div>
<DialogFooter>
<Button className="mr-1" onClick={() => cancelRef.current?.()}>
{tc("general:button:cancel")}

View file

@ -1,10 +1,7 @@
import React, { useState } from "react";
import { ExternalLink } from "@/components/ExternalLink";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { Progress } from "@/components/ui/progress";
import { assertNever } from "@/lib/assert-never";
import type { CheckForUpdateResponse } from "@/lib/bindings";
@ -12,8 +9,7 @@ import { commands } from "@/lib/bindings";
import { callAsyncCommand } from "@/lib/call-async-command";
import type { DialogContext } from "@/lib/dialog";
import globalInfo from "@/lib/global-info";
import { tc } from "@/lib/i18n";
import React, { useState } from "react";
import { localizeExternalComponent, tc } from "@/lib/i18n";
type ConfirmStatus =
| {
@ -99,13 +95,59 @@ export function CheckForUpdateMessage({
}
};
const openAlcomWebsite = async () => {
await commands.utilOpenUrl("https://an12.net/alcom/");
};
switch (confirmStatus.state) {
case "confirming":
case "confirming": {
let message: React.ReactNode;
switch (response.updater_status) {
case "Updatable":
message = <p>{tc("check update:dialog:new version description")}</p>;
break;
case "NoPlatform":
message = (
<p>
{tc("check update:dialog:new version no platform description")}
</p>
);
break;
case "NotUpdatable":
message = (
<p>
{tc("check update:dialog:new version not updatable description")}
</p>
);
break;
case "UpdaterDisabled":
message = (
<p>
{tc(
"check update:dialog:new version updater disabled base description",
)}
<br />
{localizeExternalComponent(response.updater_disabled_messages, {
localized:
"check update:dialog:new version updater how to upgrade fallback",
})}
</p>
);
break;
default:
assertNever(response.updater_status);
}
const withDownloadButton = response.updater_status === "Updatable";
const withDownloadLink =
!withDownloadButton && response.updater_status !== "UpdaterDisabled";
return (
<>
<DialogTitle>{tc("check update:dialog:title")}</DialogTitle>
<DialogDescription>
<p>{tc("check update:dialog:new version description")}</p>
<div>
{message}
<p>
{tc("check update:dialog:current version")}{" "}
{response.current_version}
@ -122,37 +164,45 @@ export function CheckForUpdateMessage({
}
/>
</p>
</DialogDescription>
</div>
<DialogFooter className={"gap-2"}>
<Button onClick={() => dialog.close(false)}>
{tc("check update:dialog:dismiss")}
</Button>
<Button onClick={startDownload}>
{tc("check update:dialog:update")}
</Button>
{withDownloadButton && (
<Button onClick={startDownload}>
{tc("check update:dialog:update")}
</Button>
)}
{withDownloadLink && (
<Button onClick={openAlcomWebsite}>
{tc("check update:dialog:open download page")}
</Button>
)}
</DialogFooter>
</>
);
}
case "downloading":
return (
<>
<DialogTitle>{tc("check update:dialog:title")}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("check update:dialog:downloading...")}</p>
<Progress
value={confirmStatus.downloaded}
max={confirmStatus.total}
/>
</DialogDescription>
</div>
</>
);
case "waitingForRelaunch":
return (
<>
<DialogTitle>{tc("check update:dialog:title")}</DialogTitle>
<DialogDescription>
<div>
<p>{tc("check update:dialog:relaunching...")}</p>
</DialogDescription>
</div>
</>
);
}
@ -160,7 +210,7 @@ export function CheckForUpdateMessage({
const LinkedText = React.memo(({ text }: { text: string }) => {
const urlRegex =
/https:\/\/[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)+\/[a-zA-Z0-9$\-_.+!*'()%\/?#]*/g;
/https:\/\/[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)+\/[a-zA-Z0-9$\-_.+!*'()%/?#]*/g;
const components: React.ReactNode[] = [];
let lastMatchEnd = 0;
for (const match of text.matchAll(urlRegex)) {

View file

@ -1,6 +1,6 @@
import { Button } from "@/components/ui/button";
import type React from "react";
import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
export function DelayedButton({
disabled,
delay,

View file

@ -1,7 +1,7 @@
import { commands } from "@/lib/bindings";
import { cn } from "@/lib/utils";
import { ExternalLink as LucideExternalLink } from "lucide-react";
import type React from "react";
import { commands } from "@/lib/bindings";
import { cn } from "@/lib/utils";
export function ExternalLink({
children,
@ -25,7 +25,7 @@ export function ExternalLink({
<a
className={cn(className, "underline inline")}
type={"button"}
// biome-ignore lint/a11y/useValidAnchor: This is navigation with external browser, not a action
href={href}
onClick={() => commands.utilOpenUrl(href)}
>
{body}

View file

@ -0,0 +1,54 @@
import { Star, StarOff } from "lucide-react";
import { cn } from "@/lib/utils";
export function FavoriteStarToggleButton({
favorite,
disabled,
onToggle,
className,
}: {
favorite: boolean;
disabled?: boolean;
onToggle?: () => void;
className?: string;
}) {
if (disabled) {
return (
<StarOff
strokeWidth={favorite ? 1.5 : 3}
className={cn(
"size-4 transition-colors cursor-pointer",
"text-foreground/30",
"opacity-0 group-hover:opacity-100",
"hover:opacity-100",
className,
)}
fill={favorite ? "currentColor" : "none"}
onClick={() => {
if (!disabled) {
onToggle?.();
}
}}
/>
);
} else {
return (
<Star
strokeWidth={favorite ? 1.5 : 3}
className={cn(
"size-4 transition-colors cursor-pointer",
favorite ? "text-foreground" : "text-foreground/30",
!favorite && "opacity-0 group-hover:opacity-100",
"hover:text-foreground hover:opacity-100",
className,
)}
fill={favorite ? "currentColor" : "none"}
onClick={() => {
if (!disabled) {
onToggle?.();
}
}}
/>
);
}
}

View file

@ -1,11 +1,10 @@
import { queryOptions, useQueryClient } from "@tanstack/react-query";
import type React from "react";
import { useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { commands } from "@/lib/bindings";
import { tc } from "@/lib/i18n";
import { openUnity } from "@/lib/open-unity";
import { queryOptions, useQueryClient } from "@tanstack/react-query";
import type React from "react";
import { useState } from "react";
import { useRef } from "react";
function PreventDoubleClick({
delayMs,

View file

@ -1,5 +1,5 @@
import { cn } from "@/lib/utils";
import React from "react";
import { cn } from "@/lib/utils";
/**
* Overlays multiple elements to one place with grid layout
@ -13,10 +13,13 @@ import React from "react";
export function Overlay({
children,
className,
}: { className?: string; children?: React.ReactNode }) {
}: {
className?: string;
children?: React.ReactNode;
}) {
return (
<div className={cn("grid", className)}>
{React.Children.map(children, (child, i) => {
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
const childElement = child as React.ReactHTMLElement<HTMLElement>;
return React.cloneElement(childElement, {

View file

@ -1,16 +1,12 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useLocation, useRouter } from "@tanstack/react-router";
import { Button } from "@/components/ui/button";
import {
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
import { DialogFooter, DialogTitle } from "@/components/ui/dialog";
import { commands } from "@/lib/bindings";
import type { DialogContext } from "@/lib/dialog";
import { tc, tt } from "@/lib/i18n";
import { nameFromPath } from "@/lib/os";
import { toastSuccess, toastThrownError } from "@/lib/toast";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useLocation, useRouter } from "@tanstack/react-router";
type Project = {
path: string;
@ -32,7 +28,10 @@ export function RemoveProjectDialog({
mutationFn: async ({
project,
removeDir,
}: { project: Project; removeDir: boolean }) => {
}: {
project: Project;
removeDir: boolean;
}) => {
await commands.environmentRemoveProjectByPath(project.path, removeDir);
},
onSuccess: () => {
@ -60,7 +59,7 @@ export function RemoveProjectDialog({
return (
<div className={"contents whitespace-normal"}>
<DialogTitle>{tc("projects:remove project")}</DialogTitle>
<DialogDescription>
<div>
{removeProject.isPending ? (
<p className={"font-normal"}>{tc("projects:dialog:removing...")}</p>
) : (
@ -70,7 +69,7 @@ export function RemoveProjectDialog({
})}
</p>
)}
</DialogDescription>
</div>
<DialogFooter className={"flex gap-2"}>
<Button
onClick={() => dialog.close(false)}

View file

@ -1,5 +1,3 @@
import { Button } from "@/components/ui/button";
import { assertNever } from "@/lib/assert-never";
import { ArrowDown, ArrowUp, CircleMinus, CirclePlus } from "lucide-react";
import type React from "react";
import {
@ -9,11 +7,13 @@ import {
useMemo,
useState,
} from "react";
import { Button } from "@/components/ui/button";
import { assertNever } from "@/lib/assert-never";
const internalSymbol: unique symbol = Symbol("ReorderableListContextInternal");
const idSymbol: unique symbol = Symbol("IdSymbol");
type Id = { [idSymbol]: number; toString: () => string };
export type ReorderableListId = { [idSymbol]: number; toString: () => string };
type NonFunction =
| string
@ -25,9 +25,9 @@ type NonFunction =
| bigint
| object;
type AddOptions = { after: Id } | { before: Id };
type AddOptions = { after: ReorderableListId } | { before: ReorderableListId };
type ReordeableListValue<T> = { id: Id; value: T };
type ReordeableListValue<T> = { id: ReorderableListId; value: T };
type ReorderableListContextInternal<T> = {
backedList: ReordeableListValue<T>[];
@ -40,8 +40,8 @@ type ReorderableListContextInternal<T> = {
export type ReorderableListContext<T> = {
setList: Dispatch<SetStateAction<T[]>>;
add: (value: T, options?: AddOptions) => void;
remove: (id: Id) => void;
update: (id: Id, action: SetStateAction<T>) => void;
remove: (id: ReorderableListId) => void;
update: (id: ReorderableListId, action: SetStateAction<T>) => void;
get value(): T[];
[internalSymbol]: ReorderableListContextInternal<T>;
};
@ -127,7 +127,7 @@ export function useReorderableList<T extends NonFunction>({
}, []);
const remove = useCallback(
(id: Id) => {
(id: ReorderableListId) => {
setBackedList((old) => {
let list = old.filter(({ id: _id }) => _id !== id);
if (list.length === 0 && !allowEmpty) list = [makeValue(defaultValue)];
@ -137,26 +137,29 @@ export function useReorderableList<T extends NonFunction>({
[allowEmpty, defaultValue],
);
const update = useCallback((id: Id, action: SetStateAction<T>) => {
if (typeof action === "function") {
setBackedList((old) => {
const idx = old.findIndex(({ id: _id }) => _id === id);
if (idx === -1) return old;
const newValue = action(old[idx].value);
const newArray = [...old];
newArray[idx] = { id, value: newValue };
return newArray;
});
} else {
setBackedList((old) => {
const idx = old.findIndex(({ id: _id }) => _id === id);
if (idx === -1) return old;
const newArray = [...old];
newArray[idx] = { id, value: action };
return newArray;
});
}
}, []);
const update = useCallback(
(id: ReorderableListId, action: SetStateAction<T>) => {
if (typeof action === "function") {
setBackedList((old) => {
const idx = old.findIndex(({ id: _id }) => _id === id);
if (idx === -1) return old;
const newValue = action(old[idx].value);
const newArray = [...old];
newArray[idx] = { id, value: newValue };
return newArray;
});
} else {
setBackedList((old) => {
const idx = old.findIndex(({ id: _id }) => _id === id);
if (idx === -1) return old;
const newArray = [...old];
newArray[idx] = { id, value: action };
return newArray;
});
}
},
[],
);
const swap = useCallback((index1: number, index2: number) => {
setBackedList((old) => {
@ -168,14 +171,15 @@ export function useReorderableList<T extends NonFunction>({
});
}, []);
return useMemo(
() => ({
return useMemo(() => {
let valueCache: T[] | undefined;
return {
setList,
add,
update,
remove,
get value() {
return backedList.map(({ value }) => value);
return (valueCache ??= backedList.map(({ value }) => value));
},
[internalSymbol]: {
backedList,
@ -184,19 +188,18 @@ export function useReorderableList<T extends NonFunction>({
reorderable,
addable,
},
}),
[
setList,
add,
update,
remove,
backedList,
defaultValue,
swap,
reorderable,
addable,
],
);
};
}, [
setList,
add,
update,
remove,
backedList,
defaultValue,
swap,
reorderable,
addable,
]);
}
export function ReorderableList<T>({
@ -206,7 +209,7 @@ export function ReorderableList<T>({
disabled,
}: {
context: ReorderableListContext<T>;
renderItem: (value: T, id: Id) => React.ReactNode;
renderItem: (value: T, id: ReorderableListId) => React.ReactNode;
ifEmpty?: () => React.ReactNode;
disabled?: boolean;
}) {

View file

@ -11,7 +11,7 @@ export function ScrollPageContainer({
}) {
return (
<ScrollArea
className={`-mr-3 pr-3 ${className}`}
className={`-mr-3 pr-3 compact:mr-0 ${className}`}
scrollBarClassName={"bg-background rounded-full border-l-0 p-[1.5px]"}
viewportClassName={`${viewportClassName}`}
>

View file

@ -1,7 +1,7 @@
import type React from "react";
import { Card } from "@/components/ui/card";
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
import type React from "react";
export function ScrollableCard({
children,

Some files were not shown because too many files have changed in this diff Show more