summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-07 06:22:24 -0800
committerFuwn <[email protected]>2026-02-07 06:22:24 -0800
commit736a82f4a567cbbf82a7283d1ce7c4bf08689f71 (patch)
tree81e4d6e7d791188637cb570647cf8562025bf292 /apps
parentfeat: resolve 7 pre-ship QoL items (diff)
downloadasa.news-736a82f4a567cbbf82a7283d1ce7c4bf08689f71.tar.xz
asa.news-736a82f4a567cbbf82a7283d1ce7c4bf08689f71.zip
fix: space/shift+space scrolls focused panel, revert content font, fix share modal text
Space/Shift+Space now scrolls whichever panel is focused (entry list, detail panel, or sidebar) instead of only working in the detail panel. Removed content font setting. Fixed share modal placeholder casing and ellipsis spacing.
Diffstat (limited to 'apps')
-rw-r--r--apps/web/app/reader/_components/entry-detail-panel.tsx13
-rw-r--r--apps/web/app/reader/_components/entry-list.tsx2
-rw-r--r--apps/web/app/reader/_components/sidebar-content.tsx2
-rw-r--r--apps/web/app/reader/settings/_components/appearance-settings.tsx23
-rw-r--r--apps/web/lib/hooks/use-keyboard-navigation.ts40
-rw-r--r--apps/web/lib/stores/user-interface-store.ts8
6 files changed, 28 insertions, 60 deletions
diff --git a/apps/web/app/reader/_components/entry-detail-panel.tsx b/apps/web/app/reader/_components/entry-detail-panel.tsx
index 4d15e1f..6cf9841 100644
--- a/apps/web/app/reader/_components/entry-detail-panel.tsx
+++ b/apps/web/app/reader/_components/entry-detail-panel.tsx
@@ -68,15 +68,6 @@ export function EntryDetailPanel({
const showReadingTime = useUserInterfaceStore(
(state) => state.showReadingTime
)
- const contentFont = useUserInterfaceStore((state) => state.contentFont)
-
- const contentFontClass =
- contentFont === "serif"
- ? "font-serif"
- : contentFont === "monospace"
- ? "font-mono"
- : "font-sans"
-
const proseContainerReference = useRef<HTMLDivElement>(null)
const [selectionToolbarState, setSelectionToolbarState] = useState<{
selectionRect: DOMRect
@@ -498,7 +489,7 @@ export function EntryDetailPanel({
<div className="relative">
<div
ref={proseContainerReference}
- className={`prose-reader text-text-secondary ${contentFontClass}`}
+ className="prose-reader text-text-secondary"
/>
{selectionToolbarState && (
<HighlightSelectionToolbar
@@ -546,7 +537,7 @@ export function EntryDetailPanel({
value={shareNoteText}
onChange={(event) => setShareNoteText(event.target.value)}
rows={4}
- placeholder="Write a note to accompany this shared entry..."
+ placeholder="write a note to accompany this shared entry ..."
className="w-full resize-y border border-border bg-background-primary px-3 py-2 text-text-primary outline-none placeholder:text-text-dim focus:border-text-dim"
/>
</div>
diff --git a/apps/web/app/reader/_components/entry-list.tsx b/apps/web/app/reader/_components/entry-list.tsx
index 6d4bcf3..acc0990 100644
--- a/apps/web/app/reader/_components/entry-list.tsx
+++ b/apps/web/app/reader/_components/entry-list.tsx
@@ -164,7 +164,7 @@ export function EntryList({
}
return (
- <div ref={scrollContainerReference} className="h-full overflow-auto">
+ <div ref={scrollContainerReference} data-entry-list-scroll className="h-full overflow-auto">
<div
style={{
height: `${virtualizer.getTotalSize()}px`,
diff --git a/apps/web/app/reader/_components/sidebar-content.tsx b/apps/web/app/reader/_components/sidebar-content.tsx
index 17d07bb..4b58934 100644
--- a/apps/web/app/reader/_components/sidebar-content.tsx
+++ b/apps/web/app/reader/_components/sidebar-content.tsx
@@ -133,7 +133,7 @@ export function SidebarContent() {
let navIndex = 0
return (
- <nav className="flex-1 space-y-1 overflow-auto px-2">
+ <nav data-sidebar-nav className="flex-1 space-y-1 overflow-auto px-2">
<Link
href="/reader"
data-sidebar-nav-item
diff --git a/apps/web/app/reader/settings/_components/appearance-settings.tsx b/apps/web/app/reader/settings/_components/appearance-settings.tsx
index 508051f..6c04f00 100644
--- a/apps/web/app/reader/settings/_components/appearance-settings.tsx
+++ b/apps/web/app/reader/settings/_components/appearance-settings.tsx
@@ -31,10 +31,6 @@ export function AppearanceSettings() {
)
const fontSize = useUserInterfaceStore((state) => state.fontSize)
const setFontSize = useUserInterfaceStore((state) => state.setFontSize)
- const contentFont = useUserInterfaceStore((state) => state.contentFont)
- const setContentFont = useUserInterfaceStore(
- (state) => state.setContentFont
- )
const timeDisplayFormat = useUserInterfaceStore(
(state) => state.timeDisplayFormat
)
@@ -159,25 +155,6 @@ export function AppearanceSettings() {
</select>
</div>
<div className="mb-6">
- <h3 className="mb-2 text-text-primary">content font</h3>
- <p className="mb-3 text-text-dim">
- controls the typeface used for article content
- </p>
- <select
- value={contentFont}
- onChange={(event) =>
- setContentFont(
- event.target.value as "sans-serif" | "serif" | "monospace"
- )
- }
- className="border border-border bg-background-primary px-3 py-2 text-text-primary outline-none focus:border-text-dim"
- >
- <option value="sans-serif">sans-serif</option>
- <option value="serif">serif</option>
- <option value="monospace">monospace</option>
- </select>
- </div>
- <div className="mb-6">
<h3 className="mb-2 text-text-primary">time display</h3>
<p className="mb-3 text-text-dim">
choose between relative timestamps (e.g. &ldquo;2h ago&rdquo;) or
diff --git a/apps/web/lib/hooks/use-keyboard-navigation.ts b/apps/web/lib/hooks/use-keyboard-navigation.ts
index 8685396..275db29 100644
--- a/apps/web/lib/hooks/use-keyboard-navigation.ts
+++ b/apps/web/lib/hooks/use-keyboard-navigation.ts
@@ -153,6 +153,28 @@ export function useKeyboardNavigation() {
return
}
+ if (event.key === " ") {
+ const scrollSelectors: Record<string, string> = {
+ entryList: "[data-entry-list-scroll]",
+ detailPanel: "[data-detail-article]",
+ sidebar: "[data-sidebar-nav]",
+ }
+ const selector = scrollSelectors[focusedPanel]
+ const scrollableElement = selector
+ ? document.querySelector<HTMLElement>(selector)
+ : null
+ if (scrollableElement) {
+ event.preventDefault()
+ const pageScrollAmount = scrollableElement.clientHeight * 0.8
+ if (event.shiftKey) {
+ scrollableElement.scrollTop -= pageScrollAmount
+ } else {
+ scrollableElement.scrollTop += pageScrollAmount
+ }
+ }
+ return
+ }
+
if (focusedPanel === "sidebar") {
handleSidebarKeyDown(event)
return
@@ -368,7 +390,6 @@ export function useKeyboardNavigation() {
function handleDetailPanelKeyDown(event: KeyboardEvent) {
const SCROLL_AMOUNT = 100
- const PAGE_SCROLL_FRACTION = 0.8
const detailArticle = document.querySelector<HTMLElement>(
"[data-detail-article]"
)
@@ -386,19 +407,6 @@ export function useKeyboardNavigation() {
if (detailArticle) detailArticle.scrollTop -= SCROLL_AMOUNT
break
}
- case " ": {
- event.preventDefault()
- if (detailArticle) {
- const pageScrollAmount =
- detailArticle.clientHeight * PAGE_SCROLL_FRACTION
- if (event.shiftKey) {
- detailArticle.scrollTop -= pageScrollAmount
- } else {
- detailArticle.scrollTop += pageScrollAmount
- }
- }
- break
- }
case "?": {
event.preventDefault()
toggleShortcutsDialog()
@@ -517,9 +525,9 @@ export function useKeyboardNavigation() {
}
}
- document.addEventListener("keydown", handleKeyDown)
+ document.addEventListener("keydown", handleKeyDown, true)
- return () => document.removeEventListener("keydown", handleKeyDown)
+ return () => document.removeEventListener("keydown", handleKeyDown, true)
}, [
selectedEntryIdentifier,
focusedEntryIdentifier,
diff --git a/apps/web/lib/stores/user-interface-store.ts b/apps/web/lib/stores/user-interface-store.ts
index fdee347..01dceba 100644
--- a/apps/web/lib/stores/user-interface-store.ts
+++ b/apps/web/lib/stores/user-interface-store.ts
@@ -7,8 +7,6 @@ type DisplayDensity = "compact" | "default" | "spacious"
type FontSize = "small" | "default" | "large"
-type ContentFont = "sans-serif" | "serif" | "monospace"
-
type TimeDisplayFormat = "relative" | "absolute"
type FocusedPanel = "sidebar" | "entryList" | "detailPanel"
@@ -40,7 +38,6 @@ interface UserInterfaceState {
showFeedFavicons: boolean
focusFollowsInteraction: boolean
fontSize: FontSize
- contentFont: ContentFont
timeDisplayFormat: TimeDisplayFormat
showEntryImages: boolean
showReadingTime: boolean
@@ -65,7 +62,6 @@ interface UserInterfaceState {
setShowFeedFavicons: (show: boolean) => void
setFocusFollowsInteraction: (enabled: boolean) => void
setFontSize: (size: FontSize) => void
- setContentFont: (font: ContentFont) => void
setTimeDisplayFormat: (format: TimeDisplayFormat) => void
setShowEntryImages: (show: boolean) => void
setShowReadingTime: (show: boolean) => void
@@ -94,7 +90,6 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
showFeedFavicons: true,
focusFollowsInteraction: false,
fontSize: "default",
- contentFont: "sans-serif",
timeDisplayFormat: "relative",
showEntryImages: true,
showReadingTime: true,
@@ -139,8 +134,6 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
setFontSize: (size) => set({ fontSize: size }),
- setContentFont: (font) => set({ contentFont: font }),
-
setTimeDisplayFormat: (format) => set({ timeDisplayFormat: format }),
setShowEntryImages: (show) => set({ showEntryImages: show }),
@@ -194,7 +187,6 @@ export const useUserInterfaceStore = create<UserInterfaceState>()(
focusFollowsInteraction: state.focusFollowsInteraction,
expandedFolderIdentifiers: state.expandedFolderIdentifiers,
fontSize: state.fontSize,
- contentFont: state.contentFont,
timeDisplayFormat: state.timeDisplayFormat,
showEntryImages: state.showEntryImages,
showReadingTime: state.showReadingTime,