mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 19:05:06 +03:00
- Update Changelog [index page layout](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog): - with full timeline - filterable based on text search and tags - New Changelog [detail pages](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071) - all added to www_sitemap - Changelog [RSS Feed](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071) + llm-friendly [/changelog.md](https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog.md) - and llm-friendly changelog detail md files: https://zone-www-dot-com-git-feat-changelog-update-supabase.vercel.app/changelog/45071.md ## Before <img width="1604" height="1094" alt="Screenshot 2026-04-27 at 17 07 55" src="https://github.com/user-attachments/assets/eac52f14-e447-4f64-8d50-a8e287ccf989" /> ## After <img width="1247" height="849" alt="changelog-index" src="https://github.com/user-attachments/assets/69b7bae1-63eb-4a4d-a065-7541ed9738b4" /> ### Detail page <img width="1695" height="1101" alt="Screenshot 2026-04-27 at 18 27 27" src="https://github.com/user-attachments/assets/accd4be8-d665-43ed-bcb7-0e6baf537762" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Redesigned changelog page with full-text search and product tag filtering * Individual pages for each changelog entry with dedicated URLs * Added RSS feeds for changelog updates and product-specific feeds * Copy changelog entries as markdown with one click * Direct sharing integration with ChatGPT and Claude <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
51 lines
1.3 KiB
TypeScript
51 lines
1.3 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useState } from 'react'
|
|
|
|
export type CopyMarkdownFromUrlOptions = {
|
|
/** When the markdown URL is missing or not OK, use this HTML string instead (e.g. rendered article). */
|
|
fallbackHtml?: () => string
|
|
}
|
|
|
|
const COPIED_FEEDBACK_MS = 2000
|
|
|
|
/**
|
|
* Fetches markdown from `mdUrl`, falls back to optional HTML when the response is not OK,
|
|
* then writes the result to the clipboard.
|
|
*/
|
|
export async function copyMarkdownFromUrl(
|
|
mdUrl: string,
|
|
options?: CopyMarkdownFromUrlOptions
|
|
): Promise<boolean> {
|
|
try {
|
|
const res = await fetch(mdUrl)
|
|
let text: string
|
|
if (res.ok) {
|
|
text = await res.text()
|
|
} else {
|
|
text = options?.fallbackHtml?.() ?? ''
|
|
if (!text) return false
|
|
}
|
|
await navigator.clipboard.writeText(text)
|
|
return true
|
|
} catch (error) {
|
|
console.error('Failed to copy markdown', error)
|
|
return false
|
|
}
|
|
}
|
|
|
|
export function useCopyMarkdownFromUrl() {
|
|
const [copied, setCopied] = useState(false)
|
|
|
|
const copyMarkdown = useCallback(async (mdUrl: string, options?: CopyMarkdownFromUrlOptions) => {
|
|
const ok = await copyMarkdownFromUrl(mdUrl, options)
|
|
if (ok) {
|
|
setCopied(true)
|
|
setTimeout(() => setCopied(false), COPIED_FEEDBACK_MS)
|
|
}
|
|
return ok
|
|
}, [])
|
|
|
|
return { copied, copyMarkdown }
|
|
}
|