Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
v-if="showLogo"
class="flex-1 flex flex-row items-center h-20 border-b mx-3 md:mx-6"
>
<jabref-logo class="w-10 flex-none" />
<jabref-logo class="w-12 flex-none" />
<span
class="ml-3 flex-1 text-highlighted text-2xl font-semibold lg:inline-block hidden"
>
Expand Down Expand Up @@ -137,11 +137,30 @@
</div>
</nav>

<!-- Empty stopper for proper alignment -->
<!-- Right spacer — also holds the GitHub link to keep menu centred -->
<div
v-show="!isSmallDisplay"
class="flex-1 mx-3 md:mx-6"
/>
class="flex-1 flex items-center justify-end mx-3 md:mx-6"
>
<a
v-if="showGithubLink"
href="https://github.com/JabRef/jabref"
target="_blank"
rel="noopener noreferrer"
class="flex items-center gap-1.5 text-dimmed hover:text-primary-600 transition-colors"
aria-label="JabRef on GitHub"
>
<Icon
name="ri:github-fill"
class="text-2xl"
/>
<span
v-if="stars"
class="text-sm font-medium"
>{{ stars }}</span
>
</a>
</div>
</nav>
</template>

Expand All @@ -156,7 +175,7 @@ const isHamburgerShown = ref(false)

const isSmallDisplay = useBreakpoints(breakpointsTailwind).smallerOrEqual('md')

defineProps({
const props = defineProps({
showLogo: {
type: Boolean,
default: false,
Expand All @@ -169,8 +188,16 @@ defineProps({
type: Boolean,
default: false,
},
showGithubLink: {
type: Boolean,
default: false,
},
})

const { stars } = props.showGithubLink
? useGitHubStars()
: { stars: ref<string | null>(null) }

const { resolveClient } = useApolloClient()

const { mutate: logout, onDone } = useMutation(
Expand Down
30 changes: 30 additions & 0 deletions composables/useGitHubStars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export function useGitHubStars() {
const stars = ref<string | null>(null)

if (import.meta.client) {
fetch('/api/githubStars')
.then((res) => {
if (!res.ok) {
throw new Error(`Failed to fetch GitHub stars: ${res.statusText}`)
}
return res.json()
})
.then((data: { stars?: number }) => {
if (data.stars !== undefined) {
stars.value = formatStarCount(data.stars)
}
})
.catch((error) => {
console.debug('Failed to fetch GitHub stars:', error)
})
}

return { stars }
}

function formatStarCount(count: number): string {
if (count >= 1000) {
return `${(count / 1000).toFixed(1).replace(/\.0$/, '')}K`
}
return count.toString()
}
15 changes: 15 additions & 0 deletions pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<NavBar
:show-search-bar="false"
:show-logo="true"
:show-github-link="true"
>
<div class="space-x-14">
<t-nuxtlink
Expand All @@ -29,6 +30,20 @@
>{{ link.title }}</t-nuxtlink
>
</li>
<li>
<a
href="https://github.com/JabRef/jabref"
target="_blank"
rel="noopener noreferrer"
class="hover:text-primary-600 font-semibold inline-flex items-center gap-1.5"
>
<Icon
name="ri:github-fill"
class="text-lg"
/>
GitHub
</a>
</li>
</ul>
</template>
</NavBar>
Expand Down
49 changes: 49 additions & 0 deletions server/api/githubStars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/** JabRef desktop app repo — fixed to avoid open proxy / rate-limit abuse */
const JABREF_REPO = 'JabRef/jabref'

export default defineCachedEventHandler(
async (event) => {
event.node.res.setHeader(
'Cache-Control',
'public, s-maxage=300, stale-while-revalidate=600',
)

const config = useRuntimeConfig()
const githubToken = config.githubRepoToken as string | undefined

const headers: Record<string, string> = {
Accept: 'application/vnd.github.v3+json',
'User-Agent': 'jabref-online',
}
if (githubToken) {
headers.Authorization = `Bearer ${githubToken}`
}

try {
const response = await fetch(
`https://api.github.com/repos/${JABREF_REPO}`,
{ headers },
)

if (!response.ok) {
throw new Error(`GitHub API responded with ${response.status}`)
}

const data = (await response.json()) as { stargazers_count?: number }

return {
stars: data.stargazers_count ?? 0,
}
} catch (error) {
console.debug('Failed to fetch GitHub stars for repo', JABREF_REPO, error)
throw createError({
statusCode: 500,
message: 'Failed to fetch GitHub stars',
})
}
},
{
name: 'github-stars-jabref',
maxAge: 300,
},
)
Loading