diff --git a/eslint.config.mjs b/eslint.config.mjs
index 1ddcdfdf6..93715971c 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -37,6 +37,7 @@ export default defineConfig(
'*.e2e.ts',
'*.e2e.tsx',
'eslint.config.mjs',
+ 'svgo.config.mjs',
'.jscodeshift/**',
'rspack.config.ts',
'scripts/post-web-build.js',
diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx
index 758764dd7..2a5664543 100644
--- a/src/components/ProfileHoverCard/index.web.tsx
+++ b/src/components/ProfileHoverCard/index.web.tsx
@@ -528,8 +528,8 @@ function Inner({
))}
-
-
+
+
+
-
-
-
+
+
{isBlockedUser && (
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index 90604169a..d0f1aa68f 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -251,3 +251,5 @@ export const webLinks = {
community: `https://bsky.social/about/support/community-guidelines`,
communityDeprecated: `https://bsky.social/about/support/community-guidelines-deprecated`,
}
+
+export const DOH_ENDPOINT = 'https://cloudflare-dns.com/dns-query'
diff --git a/src/screens/Profile/Header/Handle.tsx b/src/screens/Profile/Header/Handle.tsx
index 967327b5d..67e02383a 100644
--- a/src/screens/Profile/Header/Handle.tsx
+++ b/src/screens/Profile/Header/Handle.tsx
@@ -1,4 +1,4 @@
-import {View} from 'react-native'
+import {type GestureResponderEvent, View} from 'react-native'
import {type AppBskyActorDefs} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
@@ -9,6 +9,8 @@ import {sanitizePronouns} from '#/lib/strings/pronouns'
import {type Shadow} from '#/state/cache/types'
import {useShowFollowsYouBadge} from '#/state/preferences/show-follows-you-badge'
import {useShowLinkInHandle} from '#/state/preferences/show-link-in-handle.tsx'
+import {useShowLinkInHandleOnlyOnWorkingLinks} from '#/state/preferences/show-link-in-handle-only-on-working-links'
+import {useHandleLinkQuery} from '#/state/queries/handle-link'
import {atoms as a, useTheme, web} from '#/alf'
import {InlineLinkText} from '#/components/Link.tsx'
import {NewskieDialog} from '#/components/NewskieDialog'
@@ -18,9 +20,13 @@ import {IS_IOS, IS_NATIVE} from '#/env'
export function ProfileHeaderHandle({
profile,
disableTaps,
+ disableAuxiliaryTaps,
+ onLinkPress,
}: {
profile: Shadow
disableTaps?: boolean
+ disableAuxiliaryTaps?: boolean
+ onLinkPress?: (e: GestureResponderEvent) => void | false
}) {
const t = useTheme()
const {_} = useLingui()
@@ -30,17 +36,50 @@ export function ProfileHeaderHandle({
const isBskySocialHandle = profile.handle.endsWith('.bsky.social')
const showFollowsYouBadge = useShowFollowsYouBadge()
const showProfileInHandle = useShowLinkInHandle()
+ const showLinkInHandleOnlyOnWorkingLinks =
+ useShowLinkInHandleOnlyOnWorkingLinks()
+ const shouldCheckHandleLink =
+ showProfileInHandle &&
+ showLinkInHandleOnlyOnWorkingLinks &&
+ !invalidHandle &&
+ !isBskySocialHandle
+ const {data: hasWorkingHandleLink = false} = useHandleLinkQuery(
+ profile.handle,
+ shouldCheckHandleLink,
+ )
+ const shouldShowProfileLink =
+ showProfileInHandle &&
+ !isBskySocialHandle &&
+ (!showLinkInHandleOnlyOnWorkingLinks || hasWorkingHandleLink)
+ const disableNewskieDialog = disableTaps || disableAuxiliaryTaps
const sanitized = sanitizeHandle(
profile.handle,
'@',
// forceLTR handled by CSS above on web
IS_NATIVE,
)
+ const handleTextStyle = [
+ invalidHandle
+ ? [
+ a.border,
+ a.text_xs,
+ a.px_sm,
+ a.py_xs,
+ a.rounded_xs,
+ {borderColor: t.palette.contrast_200},
+ ]
+ : [a.text_md, a.leading_tight, t.atoms.text_contrast_medium],
+ web({
+ wordBreak: 'break-all',
+ direction: 'ltr',
+ unicodeBidi: 'isolate',
+ }),
+ ]
return (
-
+
{showFollowsYouBadge && profile.viewer?.followedBy && !blockHide ? (
@@ -49,40 +88,24 @@ export function ProfileHeaderHandle({
) : undefined}
-
- {invalidHandle ? (
- _(msg`⚠Invalid Handle`)
- ) : showProfileInHandle && !isBskySocialHandle ? (
-
-
- {sanitized}
-
-
- ) : (
- sanitized
- )}
-
+ {invalidHandle ? (
+
+ {_(msg`⚠Invalid Handle`)}
+
+ ) : shouldShowProfileLink ? (
+
+ {sanitized}
+
+ ) : (
+
+ {sanitized}
+
+ )}
{pronouns && (
{sanitizePronouns(pronouns, IS_NATIVE)}
diff --git a/src/screens/Settings/RunesSettings.tsx b/src/screens/Settings/RunesSettings.tsx
index f4feb8b87..fad7bcb7a 100644
--- a/src/screens/Settings/RunesSettings.tsx
+++ b/src/screens/Settings/RunesSettings.tsx
@@ -156,6 +156,10 @@ import {
useSetShowLinkInHandle,
useShowLinkInHandle,
} from '#/state/preferences/show-link-in-handle.tsx'
+import {
+ useSetShowLinkInHandleOnlyOnWorkingLinks,
+ useShowLinkInHandleOnlyOnWorkingLinks,
+} from '#/state/preferences/show-link-in-handle-only-on-working-links'
import {
useLibreTranslateInstance,
useSetLibreTranslateInstance,
@@ -256,7 +260,7 @@ function ConstellationInstanceDialog({