···
import {useState} from 'react'
import {View} from 'react-native'
+
import {isDid} from '@atproto/api'
import {type ProfileViewBasic} from '@atproto/api/dist/client/types/app/bsky/actor/defs'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
+
import {APPVIEW_DID_PROXY} from '#/lib/constants'
import {usePalette} from '#/lib/hooks/usePalette'
import {type CommonNavigatorParams} from '#/lib/routes/types'
import {type Gate} from '#/lib/statsig/gates'
···
useConstellationInstance,
useSetConstellationInstance,
} from '#/state/preferences/constellation-instance'
+
import {useCustomAppViewDid} from '#/state/preferences/custom-appview-did'
useDeerVerificationEnabled,
useDeerVerificationTrusted,
···
} from '#/state/preferences/show-link-in-handle.tsx'
import {useProfilesQuery} from '#/state/queries/profile'
+
import {findService, useDidDocument} from '#/state/queries/resolve-identity'
+
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
import * as SettingsList from '#/screens/Settings/components/SettingsList'
import {atoms as a, useBreakpoints} from '#/alf'
import {Admonition} from '#/components/Admonition'
···
import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography'
import {SearchProfileCard} from '../Search/components/SearchProfileCard'
type Props = NativeStackScreenProps<CommonNavigatorParams>
function ConstellationInstanceDialog({
···
+
function CustomAppViewDidDialog({
+
control: Dialog.DialogControlProps
+
const pal = usePalette('default')
+
const {_} = useLingui()
+
const [did, setDid] = useState('')
+
const [, setCustomAppViewDid] = useCustomAppViewDid()
+
const doc = useDidDocument({did})
+
const bskyAppViewService =
+
doc.data && findService(doc.data, '#bsky_appview', 'BskyAppView')
+
if (did.length === 0) {
+
setCustomAppViewDid(undefined)
+
if (!bskyAppViewService?.serviceEndpoint) return
+
setCustomAppViewDid(did)
+
nativeOptions={{preventExpansion: true}}
+
onClose={() => setDid('')}>
+
<Dialog.ScrollableInner label={_(msg`Custom AppView Proxy DID`)}>
+
<View style={[a.gap_sm, a.pb_lg]}>
+
<Text style={[a.text_2xl, a.font_bold]}>
+
<Trans>Custom AppView Proxy DID</Trans>
+
<View style={a.gap_lg}>
+
label="Text input field"
+
style={[styles.textInput, pal.border, pal.text]}
+
onChangeText={value => {
+
APPVIEW_DID_PROXY?.substring(0, APPVIEW_DID_PROXY.indexOf('#')) ||
+
placeholderTextColor={pal.colors.textLight}
+
onSubmitEditing={submit}
+
msg`Input the DID of the AppView to proxy requests through`,
+
!!did && !bskyAppViewService?.serviceEndpoint && !doc.isLoading
+
{did && !isDid(did) && (
+
<ErrorMessage message={_(msg`must enter a DID`)} />
+
{did && (did.includes('#') || did.includes('?')) && (
+
<ErrorMessage message={_(msg`don't include the service id`)} />
+
doc.error.message || _(msg`document resolution failure`)
+
(doc.data as {message?: string}).message && (
+
message={(doc.data as {message: string}).message}
+
{doc.data && !bskyAppViewService && (
+
message={_(msg`document doesn't contain #bsky_appview service`)}
+
{bskyAppViewService && (
+
<Text style={[a.text_sm, a.leading_snug]}>
+
{JSON.stringify(bskyAppViewService, null, 2)}
+
<View style={isWeb && [a.flex_row, a.justify_end]}>
+
color={did.length > 0 ? 'primary' : 'secondary'}
+
did.length !== 0 && !bskyAppViewService?.serviceEndpoint
+
{did.length > 0 ? <Trans>Save</Trans> : <Trans>Reset</Trans>}
+
</Dialog.ScrollableInner>
function TrustedVerifiersDialog({
···
+
const [customAppViewDid] = useCustomAppViewDid()
+
const setCustomAppViewDidControl = Dialog.useDialogControl()
···
+
<SettingsList.ItemIcon icon={StarIcon} />
+
<SettingsList.ItemText>
+
<Trans>{`Custom AppView DID`}</Trans>
+
</SettingsList.ItemText>
+
<SettingsList.BadgeButton
+
label={customAppViewDid ? _(msg`Set`) : _(msg`Change`)}
+
onPress={() => setCustomAppViewDidControl.open()}
+
<Admonition type="info" style={[a.flex_1]}>
+
Restart app after changing your AppView.
+
{customAppViewDid && _(` Currently ${customAppViewDid}`)}
<SettingsList.Group contentContainerStyle={[a.gap_sm]}>
<SettingsList.ItemIcon icon={PaintRollerIcon} />
···
</SettingsList.Container>
<ConstellationInstanceDialog control={setConstellationInstanceControl} />
+
<CustomAppViewDidDialog control={setCustomAppViewDidControl} />
<TrustedVerifiersDialog control={setTrustedVerifiersDialogControl} />