From ddd1228374f5d1656564a46155ca3571ba7e78eb Mon Sep 17 00:00:00 2001 From: roboloop <12248453+roboloop@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:42:17 +0000 Subject: [PATCH] Link the dashboard footer to the source code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The project is public and MIT-licensed, but nothing on the page pointed at it: someone weighing whether to hand this app their Twitch, Kick and VK tokens had to go find the repository themselves. The footer now carries a SOURCE link, and no longer hides itself when nothing is connected — the connectedCount condition moved onto the sign-out button, so the link is present on a first visit, which is exactly when that question gets asked. It reuses the external-link treatment the provider cards already use for DASHBOARD. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_018PcejKbjjFyH9pc6RucpSP --- src/views/DashboardView.vue | 27 +++++++++++++++++++++-- src/views/__tests__/DashboardView.spec.ts | 11 +++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue index 4b4a526..87028f5 100644 --- a/src/views/DashboardView.vue +++ b/src/views/DashboardView.vue @@ -44,6 +44,9 @@ const ERRORS: Record = { exchange_failed: 'Could not complete the connection. Please try again.', } +/** Where the page's own code lives; linked from the footer. */ +const SOURCE_URL = 'https://github.com/roboloop/only-dashboard' + const syncNote = computed(() => { if (session.loading || !session.fetchedAt) return 'syncing…' return `synced ${relativeTime(session.fetchedAt, now.value)} ago` @@ -104,8 +107,14 @@ async function disconnect(id: ProviderId) { - @@ -171,6 +180,20 @@ async function disconnect(id: ProviderId) { margin: 26px 26px 0; padding-top: 22px; border-top: 1px solid var(--border-rule); + display: flex; + align-items: center; + justify-content: space-between; +} + +.source { + font: 500 var(--fs-micro) / 1 var(--font-sans); + letter-spacing: 0.06em; + color: var(--text-dim); + text-decoration: none; +} + +.source:hover { + color: var(--accent); } .signout { diff --git a/src/views/__tests__/DashboardView.spec.ts b/src/views/__tests__/DashboardView.spec.ts index 73985b4..52f0221 100644 --- a/src/views/__tests__/DashboardView.spec.ts +++ b/src/views/__tests__/DashboardView.spec.ts @@ -111,6 +111,17 @@ describe('DashboardView', () => { expect(wrapper.findAll('a.dashboard')).toHaveLength(1) }) + it('links to the source repository even with nothing connected', async () => { + stubApi([providerState()]) + const wrapper = await mountView() + + const link = wrapper.get('a.source') + expect(link.attributes('href')).toBe('https://github.com/roboloop/only-dashboard') + expect(link.attributes('target')).toBe('_blank') + expect(link.text()).toContain('SOURCE') + expect(wrapper.text()).not.toContain('SIGN OUT') + }) + it('pre-fills the title input with the current shared title', async () => { stubApi([providerState({ connected: true, streamTitle: 'Current title' })]) const wrapper = await mountView()