diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ea308e..bf79c32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,38 @@ have not been reconstructed. See [release note guidance](CONTRIBUTING.md#documen ## [Unreleased] +### Added + +- Favicons beside ordinary internal and external Markdown links in public content + and admin previews, with a text-only fallback when an icon cannot load. +- PowerShell syntax highlighting, including the `ps1` alias, in the shared editor + language picker and public Markdown renderer. +- An independent word-wrap toggle on every public code block, including short + blocks. Wrapping changes presentation without changing copied code. + +### Changed + +- Public Markdown links reveal their underline on hover with a 300 ms transition. + Project and collection mentions retain their existing badges and icons. +- Public code blocks use custom One Light and One Dark Pro syntax palettes with + matching bold-token rules, transparent bodies and headers, and equally sized + icon-only copy and wrap controls with hover and keyboard-focus tooltips. +- Update oRPC to `2.0.0-beta.49` and tsrs to `0.23.0-ts7.1.0-beta`. + +### Fixed + +- Keep BlockNote's block-style select inside its editor portal so selecting part + of a paragraph and opening the toolbar menu does not dismiss it. Heading + changes remain available through the pointer and keyboard. +- Generate a name-based avatar when an account has no image. + +### Upgrade notes + +- Deploy matching API and web revisions. Changes since `v1.1.0` add no database + migrations or environment variables; existing Markdown needs no migration. +- External-link favicons use Google S2 with only the destination hostname and no + referrer. If that service is unavailable, links remain usable without icons. + ## [1.1.0] - 2026-11-05 ### Added diff --git a/apps/web/src/components/public-content/code-block.tsx b/apps/web/src/components/public-content/code-block.tsx index d034275..16d59eb 100644 --- a/apps/web/src/components/public-content/code-block.tsx +++ b/apps/web/src/components/public-content/code-block.tsx @@ -1,8 +1,15 @@ -import { IconCheck, IconCopy } from '@tabler/icons-react' +import { IconCheck, IconCopy, IconTextWrap, IconX } from '@tabler/icons-react' +import { cn } from 'cn' import { Fragment, useEffect, useRef, useState } from 'react' import type { CSSProperties } from 'react' import { Button } from '@altstack/ui/components/button' +import { Toggle } from '@altstack/ui/components/toggle' +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from '@altstack/ui/components/tooltip' import type { CodeTokenStyle, @@ -26,6 +33,7 @@ function themeStyles(light: CodeTokenStyle, dark: CodeTokenStyle) { } export function PublicCodeBlock({ block }: { block: PreparedCodeBlock }) { + const [wordWrap, setWordWrap] = useState(false) const [copyState, setCopyState] = useState<'idle' | 'copied' | 'failed'>( 'idle' ) @@ -50,28 +58,59 @@ export function PublicCodeBlock({ block }: { block: PreparedCodeBlock }) { className="not-prose my-6 overflow-hidden rounded-lg border border-border" data-code-block > -
+
{block.language} - +
+ + + } + > + + + {wordWrap ? 'Disable word wrap' : 'Enable word wrap'} + + + + + } + > + {copyState === 'copied' ? ( + + + {copyState === 'copied' + ? 'Copied' + : copyState === 'failed' + ? 'Copy failed' + : 'Copy code'} + + +
{copyState === 'copied' ? 'Code copied to clipboard.' @@ -81,7 +120,10 @@ export function PublicCodeBlock({ block }: { block: PreparedCodeBlock }) {
 		)
 	}
+	const imageLink = node && containsImage(node)
+	const faviconSrc = target.internal
+		? '/favicon.svg'
+		: `https://www.google.com/s2/favicons?domain=${encodeURIComponent(target.url.hostname)}&sz=32`
+	const linkContent = (
+		<>
+			{!imageLink && }
+			{children}
+		
+	)
 	if (!target.internal) {
 		return (
 			
-				{children}
+				{linkContent}