Add algorithmic visibility setting
This commit is contained in:
@@ -14,9 +14,11 @@ import * as Admonition from '#/components/Admonition'
|
|||||||
import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging'
|
import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging'
|
||||||
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlashIcon} from '#/components/icons/EyeSlash'
|
import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlashIcon} from '#/components/icons/EyeSlash'
|
||||||
import {Key_Stroke2_Corner2_Rounded as KeyIcon} from '#/components/icons/Key'
|
import {Key_Stroke2_Corner2_Rounded as KeyIcon} from '#/components/icons/Key'
|
||||||
|
import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass'
|
||||||
import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield'
|
import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield'
|
||||||
import * as Layout from '#/components/Layout'
|
import * as Layout from '#/components/Layout'
|
||||||
import {InlineLinkText} from '#/components/Link'
|
import {InlineLinkText} from '#/components/Link'
|
||||||
|
import {AlgoVisibilityOptOut} from './components/AlgoVisibilityOptOut'
|
||||||
import {Email2FAToggle} from './components/Email2FAToggle'
|
import {Email2FAToggle} from './components/Email2FAToggle'
|
||||||
import {PwiOptOut} from './components/PwiOptOut'
|
import {PwiOptOut} from './components/PwiOptOut'
|
||||||
import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle'
|
import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle'
|
||||||
@@ -101,13 +103,14 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) {
|
|||||||
/>
|
/>
|
||||||
</SettingsList.LinkItem>
|
</SettingsList.LinkItem>
|
||||||
<SettingsList.Divider />
|
<SettingsList.Divider />
|
||||||
<SettingsList.Group>
|
<SettingsList.Item style={[a.align_start]}>
|
||||||
|
<SettingsList.ItemIcon icon={MagnifyingGlassIcon} />
|
||||||
|
<AlgoVisibilityOptOut />
|
||||||
|
</SettingsList.Item>
|
||||||
|
<SettingsList.Item style={[a.align_start]}>
|
||||||
<SettingsList.ItemIcon icon={EyeSlashIcon} />
|
<SettingsList.ItemIcon icon={EyeSlashIcon} />
|
||||||
<SettingsList.ItemText>
|
|
||||||
<Trans>Logged-out visibility</Trans>
|
|
||||||
</SettingsList.ItemText>
|
|
||||||
<PwiOptOut />
|
<PwiOptOut />
|
||||||
</SettingsList.Group>
|
</SettingsList.Item>
|
||||||
<SettingsList.Item>
|
<SettingsList.Item>
|
||||||
<Admonition.Outer type="tip" style={[a.flex_1]}>
|
<Admonition.Outer type="tip" style={[a.flex_1]}>
|
||||||
<Admonition.Row>
|
<Admonition.Row>
|
||||||
@@ -115,11 +118,10 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) {
|
|||||||
<Admonition.Content>
|
<Admonition.Content>
|
||||||
<Admonition.Text>
|
<Admonition.Text>
|
||||||
<Trans>
|
<Trans>
|
||||||
Note: Bluesky is an open and public network. This setting
|
Note: Bluesky is part of the Atmosphere, an open public
|
||||||
only limits the visibility of your content on the Bluesky
|
network. These settings ask other apps and websites to
|
||||||
app and website, and other apps may not respect this
|
limit your visibility, but they can choose not to. Your
|
||||||
setting. Your content may still be shown to logged-out
|
public content may still appear elsewhere.
|
||||||
users by other apps and websites.
|
|
||||||
</Trans>
|
</Trans>
|
||||||
</Admonition.Text>
|
</Admonition.Text>
|
||||||
<Admonition.Text>
|
<Admonition.Text>
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import {useCallback} from 'react'
|
||||||
|
import {View} from 'react-native'
|
||||||
|
import {type $Typed, ComAtprotoLabelDefs} from '@atproto/api'
|
||||||
|
import {msg} from '@lingui/core/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {
|
||||||
|
useProfileQuery,
|
||||||
|
useProfileUpdateMutation,
|
||||||
|
} from '#/state/queries/profile'
|
||||||
|
import {useSession} from '#/state/session'
|
||||||
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
|
import * as Toggle from '#/components/forms/Toggle'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
|
const NO_PROMOTE_LABEL = '!no-promote'
|
||||||
|
|
||||||
|
export function AlgoVisibilityOptOut() {
|
||||||
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
|
const {currentAccount} = useSession()
|
||||||
|
const {data: profile} = useProfileQuery({did: currentAccount?.did})
|
||||||
|
const updateProfile = useProfileUpdateMutation()
|
||||||
|
|
||||||
|
const isOptedOut =
|
||||||
|
profile?.labels?.some(label => label.val === NO_PROMOTE_LABEL) || false
|
||||||
|
const canToggle = profile && !updateProfile.isPending
|
||||||
|
|
||||||
|
const onToggleOptOut = useCallback(() => {
|
||||||
|
if (!profile) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let wasAdded = false
|
||||||
|
updateProfile.mutate({
|
||||||
|
profile,
|
||||||
|
updates: existing => {
|
||||||
|
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.validate(
|
||||||
|
existing.labels,
|
||||||
|
ComAtprotoLabelDefs.validateSelfLabels,
|
||||||
|
)
|
||||||
|
? existing.labels
|
||||||
|
: {
|
||||||
|
$type: 'com.atproto.label.defs#selfLabels',
|
||||||
|
values: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasLabel = labels.values.some(
|
||||||
|
label => label.val === NO_PROMOTE_LABEL,
|
||||||
|
)
|
||||||
|
if (hasLabel) {
|
||||||
|
labels.values = labels.values.filter(
|
||||||
|
label => label.val !== NO_PROMOTE_LABEL,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
wasAdded = true
|
||||||
|
labels.values.push({val: NO_PROMOTE_LABEL})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (labels.values.length === 0) {
|
||||||
|
delete existing.labels
|
||||||
|
} else {
|
||||||
|
existing.labels = labels
|
||||||
|
}
|
||||||
|
|
||||||
|
return existing
|
||||||
|
},
|
||||||
|
checkCommitted: response => {
|
||||||
|
const exists = !!response.data.labels?.some(
|
||||||
|
label => label.val === NO_PROMOTE_LABEL,
|
||||||
|
)
|
||||||
|
return exists === wasAdded
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}, [updateProfile, profile])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[a.flex_1, a.gap_sm]}>
|
||||||
|
<Toggle.Item
|
||||||
|
name="algorithmic_visibility"
|
||||||
|
disabled={!canToggle}
|
||||||
|
value={isOptedOut}
|
||||||
|
onChange={onToggleOptOut}
|
||||||
|
label={_(
|
||||||
|
msg`Ask apps to hide my posts from algorithmic recommendations`,
|
||||||
|
)}
|
||||||
|
style={[a.w_full]}>
|
||||||
|
<Toggle.LabelText style={[a.flex_1]}>
|
||||||
|
<Trans>
|
||||||
|
Ask apps to hide my posts from algorithmic recommendations
|
||||||
|
</Trans>
|
||||||
|
</Toggle.LabelText>
|
||||||
|
<Toggle.Platform />
|
||||||
|
</Toggle.Item>
|
||||||
|
|
||||||
|
<Text style={[a.leading_snug, t.atoms.text_contrast_high]}>
|
||||||
|
<Trans>
|
||||||
|
Bluesky will not show your posts in algorithmic recommendations and
|
||||||
|
will ask other apps to do the same. Your posts may still appear in the
|
||||||
|
Discover feed, but only to your followers.
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -85,12 +85,12 @@ export function PwiOptOut() {
|
|||||||
value={isOptedOut}
|
value={isOptedOut}
|
||||||
onChange={onToggleOptOut}
|
onChange={onToggleOptOut}
|
||||||
label={_(
|
label={_(
|
||||||
msg`Discourage apps from showing my account to logged-out users`,
|
msg`Ask apps and sites not to show my account to logged-out users`,
|
||||||
)}
|
)}
|
||||||
style={[a.w_full]}>
|
style={[a.w_full]}>
|
||||||
<Toggle.LabelText style={[a.flex_1]}>
|
<Toggle.LabelText style={[a.flex_1]}>
|
||||||
<Trans>
|
<Trans>
|
||||||
Discourage apps from showing my account to logged-out users
|
Ask apps and sites not to show my account to logged-out users
|
||||||
</Trans>
|
</Trans>
|
||||||
</Toggle.LabelText>
|
</Toggle.LabelText>
|
||||||
<Toggle.Platform />
|
<Toggle.Platform />
|
||||||
@@ -98,9 +98,9 @@ export function PwiOptOut() {
|
|||||||
|
|
||||||
<Text style={[a.leading_snug, t.atoms.text_contrast_high]}>
|
<Text style={[a.leading_snug, t.atoms.text_contrast_high]}>
|
||||||
<Trans>
|
<Trans>
|
||||||
Bluesky will not show your profile and posts to logged-out users.
|
Bluesky will not show your account to logged-out users and will ask
|
||||||
Other apps may not honor this request. This does not make your account
|
other apps to do the same. Other apps may not honor this request. It
|
||||||
private.
|
doesn't make your account private.
|
||||||
</Trans>
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
Reference in New Issue
Block a user