Compare commits

...

2 Commits

Author SHA1 Message Date
Julien Calixte
e11609990d fix(repo): derive starred list from saved favorites
Starred section used to intersect favorites with the paginated GitHub
repo list, so favorites past the first page only appeared after the user
scrolled. Derive RepoBase directly from PouchDB favorites and exclude
them from "all repos" by both id and name.
2026-05-17 00:24:47 +02:00
Julien Calixte
e121cc2d05 fix(repo): dedupe favorite repos by name
Stale FavoriteRepo docs with old GitHub IDs (e.g. from deleted or
recreated repos) surfaced as duplicates once the prefix scan started
returning every doc.
2026-05-17 00:24:43 +02:00
2 changed files with 29 additions and 16 deletions

View File

@@ -14,9 +14,15 @@ export const useFavoriteRepos = () => {
})
}
const savedFavoriteRepos = computed(() =>
savedRepos.value.filter((repo) => repo.isFavorite)
)
const savedFavoriteRepos = computed(() => {
const seen = new Map<string, FavoriteRepo>()
for (const repo of savedRepos.value) {
if (repo.isFavorite && !seen.has(repo.name)) {
seen.set(repo.name, repo)
}
}
return [...seen.values()]
})
onMounted(() => {
getFavorites()

View File

@@ -1,31 +1,38 @@
import { computed } from "vue"
import { DataType } from "@/data/DataType.enum"
import { useRepos } from "@/hooks/useRepos.hook"
import { useFavoriteRepos } from "@/modules/repo/hooks/useFavoriteRepos.hook"
import { RepoBase } from "@/modules/repo/interfaces/RepoBase"
const FAVORITE_ID_PREFIX = `${DataType.FavoriteRepo}-`
export const useRepoList = () => {
const { savedFavoriteRepos, addFavorite, removeFavorite } = useFavoriteRepos()
const { repos, canLoadMore, loadMore } = useRepos()
const favoriteRepos = computed(() => {
return repos.value.filter((repo) =>
savedFavoriteRepos.value.find(
(fav) => fav._id?.includes(repo.id) ?? false
)
)
})
const otherRepos = computed(() => {
return repos.value.filter(
(repo) => !favoriteRepos.value.find((favorite) => favorite.id === repo.id)
)
})
const favoriteRepos = computed<RepoBase[]>(() =>
savedFavoriteRepos.value.map((fav) => ({
id: fav._id?.startsWith(FAVORITE_ID_PREFIX)
? fav._id.slice(FAVORITE_ID_PREFIX.length)
: (fav._id ?? ""),
name: fav.name,
isPrivate: fav.isPrivate
}))
)
const favoriteCheckboxes = computed(() =>
favoriteRepos.value.map((favorite) => favorite.id)
)
const otherRepos = computed(() => {
const starredIds = new Set(favoriteCheckboxes.value)
const starredNames = new Set(favoriteRepos.value.map((r) => r.name))
return repos.value.filter(
(repo) => !starredIds.has(repo.id) && !starredNames.has(repo.name)
)
})
const toggleCheckbox = async (repo: RepoBase) => {
if (favoriteCheckboxes.value.includes(repo.id)) {
await removeFavorite(repo)