diff --git a/package-lock.json b/package-lock.json
index 40341894..2d430739 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "imwald",
- "version": "23.17.4",
+ "version": "23.17.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "imwald",
- "version": "23.17.4",
+ "version": "23.17.5",
"license": "MIT",
"dependencies": {
"@asciidoctor/core": "^3.0.4",
diff --git a/package.json b/package.json
index 80161d7f..6e02c753 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "imwald",
- "version": "23.17.4",
+ "version": "23.17.5",
"description": "Imwald — a user-friendly Nostr client focused on relay feed browsing, publications, and relay discovery",
"private": true,
"type": "module",
diff --git a/src/components/KindFilter/index.tsx b/src/components/KindFilter/index.tsx
index 2ba66e73..a845f5ce 100644
--- a/src/components/KindFilter/index.tsx
+++ b/src/components/KindFilter/index.tsx
@@ -18,6 +18,7 @@ import {
} from '@/lib/feed-kind-filter'
import { LIVE_ACTIVITY_KINDS } from '@/lib/live-activities'
import { cn } from '@/lib/utils'
+import { useFontSize } from '@/providers/FontSizeProvider'
import { useKindFilterOrDefaults } from '@/providers/KindFilterProvider'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { ListFilter } from 'lucide-react'
@@ -59,6 +60,7 @@ export default function KindFilter({
}) {
const { t } = useTranslation()
const { isSmallScreen } = useScreenSize()
+ const { fontSize } = useFontSize()
const {
showKinds: savedShowKinds,
showKind1OPs: savedShowKind1OPs,
@@ -179,7 +181,14 @@ export default function KindFilter({
}}
>
- {t('Filter')}
+
+ {t('Filter')}
+
{isDifferentFromSaved && (
)}
diff --git a/src/components/NormalFeed/index.tsx b/src/components/NormalFeed/index.tsx
index 05aec602..7d1c3e76 100644
--- a/src/components/NormalFeed/index.tsx
+++ b/src/components/NormalFeed/index.tsx
@@ -306,7 +306,7 @@ const NormalFeed = forwardRef {
const kindRowOptions = (
-
+
{onSubHeaderRefresh != null &&
}
{mergeFilterWithTabsRow ? (
diff --git a/src/components/Tabs/index.tsx b/src/components/Tabs/index.tsx
index 7cb1f87c..0074d4f9 100644
--- a/src/components/Tabs/index.tsx
+++ b/src/components/Tabs/index.tsx
@@ -130,18 +130,19 @@ export default function Tabs({
-
+
{tabs.map((tab, index) => (
{options ? (
-
{options}
+
{options}
) : null}
)
diff --git a/src/providers/DeepBrowsingProvider.tsx b/src/providers/DeepBrowsingProvider.tsx
index 44a26626..cdfd6896 100644
--- a/src/providers/DeepBrowsingProvider.tsx
+++ b/src/providers/DeepBrowsingProvider.tsx
@@ -29,10 +29,29 @@ export function DeepBrowsingProvider({
(!scrollAreaRef ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
)
const [lastScrollTop, setLastScrollTop] = useState(lastScrollTopRef.current)
+ /**
+ * Chrome (especially installed PWA) fires scroll when we restore `scrollTop` programmatically.
+ * That one-shot jump looks like "deep browse" and hid sticky tab rows via translate. Firefox often
+ * does not surface the same scroll event pattern on restore.
+ */
+ const ignoreScrollForDeepBrowseRef = useRef(true)
useEffect(() => {
if (!active) return
+ ignoreScrollForDeepBrowseRef.current = true
+ setDeepBrowsing(false)
+ const syncScrollTop = () => {
+ const scrollTop = (!scrollAreaRef ? window.scrollY : scrollAreaRef.current?.scrollTop) || 0
+ lastScrollTopRef.current = scrollTop
+ setLastScrollTop(scrollTop)
+ }
+ syncScrollTop()
+ const graceTimer = window.setTimeout(() => {
+ ignoreScrollForDeepBrowseRef.current = false
+ syncScrollTop()
+ }, 150)
+
let rafId: number | null = null
const handleScroll = () => {
// Use requestAnimationFrame to throttle scroll updates and prevent scroll-linked positioning warnings
@@ -43,6 +62,12 @@ export function DeepBrowsingProvider({
const diff = scrollTop - lastScrollTopRef.current
lastScrollTopRef.current = scrollTop
setLastScrollTop(scrollTop)
+
+ if (ignoreScrollForDeepBrowseRef.current) {
+ rafId = null
+ return
+ }
+
if (scrollTop <= 800) {
setDeepBrowsing(false)
rafId = null
@@ -62,6 +87,7 @@ export function DeepBrowsingProvider({
target?.addEventListener('scroll', handleScroll, { passive: true })
return () => {
+ window.clearTimeout(graceTimer)
target?.removeEventListener('scroll', handleScroll)
if (rafId !== null) {
cancelAnimationFrame(rafId)