Add disable autoplay preference and group related settings into a dedicated page (#3626)
* add autoplay preference * group accessibility settings into a dedicated page * fix gray background on web * Put a11y first --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>zio/stable
parent
ade2ea6172
commit
8b33ffdfb5
|
@ -190,6 +190,7 @@ func serve(cctx *cli.Context) error {
|
||||||
e.GET("/settings/saved-feeds", server.WebGeneric)
|
e.GET("/settings/saved-feeds", server.WebGeneric)
|
||||||
e.GET("/settings/threads", server.WebGeneric)
|
e.GET("/settings/threads", server.WebGeneric)
|
||||||
e.GET("/settings/external-embeds", server.WebGeneric)
|
e.GET("/settings/external-embeds", server.WebGeneric)
|
||||||
|
e.GET("/settings/accessibility", server.WebGeneric)
|
||||||
e.GET("/sys/debug", server.WebGeneric)
|
e.GET("/sys/debug", server.WebGeneric)
|
||||||
e.GET("/sys/debug-mod", server.WebGeneric)
|
e.GET("/sys/debug-mod", server.WebGeneric)
|
||||||
e.GET("/sys/log", server.WebGeneric)
|
e.GET("/sys/log", server.WebGeneric)
|
||||||
|
|
|
@ -53,6 +53,7 @@ import {
|
||||||
setEmailConfirmationRequested,
|
setEmailConfirmationRequested,
|
||||||
shouldRequestEmailConfirmation,
|
shouldRequestEmailConfirmation,
|
||||||
} from './state/shell/reminders'
|
} from './state/shell/reminders'
|
||||||
|
import {AccessibilitySettingsScreen} from './view/screens/AccessibilitySettings'
|
||||||
import {CommunityGuidelinesScreen} from './view/screens/CommunityGuidelines'
|
import {CommunityGuidelinesScreen} from './view/screens/CommunityGuidelines'
|
||||||
import {CopyrightPolicyScreen} from './view/screens/CopyrightPolicy'
|
import {CopyrightPolicyScreen} from './view/screens/CopyrightPolicy'
|
||||||
import {DebugModScreen} from './view/screens/DebugMod'
|
import {DebugModScreen} from './view/screens/DebugMod'
|
||||||
|
@ -276,6 +277,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
|
||||||
requireAuth: true,
|
requireAuth: true,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="AccessibilitySettings"
|
||||||
|
getComponent={() => AccessibilitySettingsScreen}
|
||||||
|
options={{
|
||||||
|
title: title(msg`Accessibility Settings`),
|
||||||
|
requireAuth: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="Hashtag"
|
name="Hashtag"
|
||||||
getComponent={() => HashtagScreen}
|
getComponent={() => HashtagScreen}
|
||||||
|
|
|
@ -35,6 +35,7 @@ export type CommonNavigatorParams = {
|
||||||
PreferencesFollowingFeed: undefined
|
PreferencesFollowingFeed: undefined
|
||||||
PreferencesThreads: undefined
|
PreferencesThreads: undefined
|
||||||
PreferencesExternalEmbeds: undefined
|
PreferencesExternalEmbeds: undefined
|
||||||
|
AccessibilitySettings: undefined
|
||||||
Search: {q?: string}
|
Search: {q?: string}
|
||||||
Hashtag: {tag: string; author?: string}
|
Hashtag: {tag: string; author?: string}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ export const router = new Router({
|
||||||
PreferencesFollowingFeed: '/settings/following-feed',
|
PreferencesFollowingFeed: '/settings/following-feed',
|
||||||
PreferencesThreads: '/settings/threads',
|
PreferencesThreads: '/settings/threads',
|
||||||
PreferencesExternalEmbeds: '/settings/external-embeds',
|
PreferencesExternalEmbeds: '/settings/external-embeds',
|
||||||
|
AccessibilitySettings: '/settings/accessibility',
|
||||||
SavedFeeds: '/settings/saved-feeds',
|
SavedFeeds: '/settings/saved-feeds',
|
||||||
Support: '/support',
|
Support: '/support',
|
||||||
PrivacyPolicy: '/support/privacy',
|
PrivacyPolicy: '/support/privacy',
|
||||||
|
|
|
@ -60,6 +60,7 @@ export const schema = z.object({
|
||||||
lastSelectedHomeFeed: z.string().optional(),
|
lastSelectedHomeFeed: z.string().optional(),
|
||||||
pdsAddressHistory: z.array(z.string()).optional(),
|
pdsAddressHistory: z.array(z.string()).optional(),
|
||||||
disableHaptics: z.boolean().optional(),
|
disableHaptics: z.boolean().optional(),
|
||||||
|
disableAutoplay: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
export type Schema = z.infer<typeof schema>
|
export type Schema = z.infer<typeof schema>
|
||||||
|
|
||||||
|
@ -96,4 +97,5 @@ export const defaults: Schema = {
|
||||||
lastSelectedHomeFeed: undefined,
|
lastSelectedHomeFeed: undefined,
|
||||||
pdsAddressHistory: [],
|
pdsAddressHistory: [],
|
||||||
disableHaptics: false,
|
disableHaptics: false,
|
||||||
|
disableAutoplay: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import * as persisted from '#/state/persisted'
|
||||||
|
|
||||||
|
type StateContext = boolean
|
||||||
|
type SetContext = (v: boolean) => void
|
||||||
|
|
||||||
|
const stateContext = React.createContext<StateContext>(
|
||||||
|
Boolean(persisted.defaults.disableAutoplay),
|
||||||
|
)
|
||||||
|
const setContext = React.createContext<SetContext>((_: boolean) => {})
|
||||||
|
|
||||||
|
export function Provider({children}: {children: React.ReactNode}) {
|
||||||
|
const [state, setState] = React.useState(
|
||||||
|
Boolean(persisted.get('disableAutoplay')),
|
||||||
|
)
|
||||||
|
|
||||||
|
const setStateWrapped = React.useCallback(
|
||||||
|
(autoplayDisabled: persisted.Schema['disableAutoplay']) => {
|
||||||
|
setState(Boolean(autoplayDisabled))
|
||||||
|
persisted.write('disableAutoplay', autoplayDisabled)
|
||||||
|
},
|
||||||
|
[setState],
|
||||||
|
)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
return persisted.onUpdate(() => {
|
||||||
|
setState(Boolean(persisted.get('disableAutoplay')))
|
||||||
|
})
|
||||||
|
}, [setStateWrapped])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<stateContext.Provider value={state}>
|
||||||
|
<setContext.Provider value={setStateWrapped}>
|
||||||
|
{children}
|
||||||
|
</setContext.Provider>
|
||||||
|
</stateContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAutoplayDisabled = () => React.useContext(stateContext)
|
||||||
|
export const useSetAutoplayDisabled = () => React.useContext(setContext)
|
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import {Provider as AltTextRequiredProvider} from '../preferences/alt-text-required'
|
import {Provider as AltTextRequiredProvider} from './alt-text-required'
|
||||||
import {Provider as HiddenPostsProvider} from '../preferences/hidden-posts'
|
import {Provider as AutoplayProvider} from './autoplay'
|
||||||
import {Provider as DisableHapticsProvider} from './disable-haptics'
|
import {Provider as DisableHapticsProvider} from './disable-haptics'
|
||||||
import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs'
|
import {Provider as ExternalEmbedsProvider} from './external-embeds-prefs'
|
||||||
|
import {Provider as HiddenPostsProvider} from './hidden-posts'
|
||||||
import {Provider as InAppBrowserProvider} from './in-app-browser'
|
import {Provider as InAppBrowserProvider} from './in-app-browser'
|
||||||
import {Provider as LanguagesProvider} from './languages'
|
import {Provider as LanguagesProvider} from './languages'
|
||||||
|
|
||||||
|
@ -11,6 +12,8 @@ export {
|
||||||
useRequireAltTextEnabled,
|
useRequireAltTextEnabled,
|
||||||
useSetRequireAltTextEnabled,
|
useSetRequireAltTextEnabled,
|
||||||
} from './alt-text-required'
|
} from './alt-text-required'
|
||||||
|
export {useAutoplayDisabled, useSetAutoplayDisabled} from './autoplay'
|
||||||
|
export {useHapticsDisabled, useSetHapticsDisabled} from './disable-haptics'
|
||||||
export {
|
export {
|
||||||
useExternalEmbedsPrefs,
|
useExternalEmbedsPrefs,
|
||||||
useSetExternalEmbedPref,
|
useSetExternalEmbedPref,
|
||||||
|
@ -26,7 +29,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||||
<ExternalEmbedsProvider>
|
<ExternalEmbedsProvider>
|
||||||
<HiddenPostsProvider>
|
<HiddenPostsProvider>
|
||||||
<InAppBrowserProvider>
|
<InAppBrowserProvider>
|
||||||
<DisableHapticsProvider>{children}</DisableHapticsProvider>
|
<DisableHapticsProvider>
|
||||||
|
<AutoplayProvider>{children}</AutoplayProvider>
|
||||||
|
</DisableHapticsProvider>
|
||||||
</InAppBrowserProvider>
|
</InAppBrowserProvider>
|
||||||
</HiddenPostsProvider>
|
</HiddenPostsProvider>
|
||||||
</ExternalEmbedsProvider>
|
</ExternalEmbedsProvider>
|
||||||
|
|
|
@ -1,63 +1,72 @@
|
||||||
import {library} from '@fortawesome/fontawesome-svg-core'
|
import {library} from '@fortawesome/fontawesome-svg-core'
|
||||||
|
|
||||||
import {faAddressCard} from '@fortawesome/free-regular-svg-icons'
|
import {faAddressCard} from '@fortawesome/free-regular-svg-icons'
|
||||||
|
import {faBell as farBell} from '@fortawesome/free-regular-svg-icons/faBell'
|
||||||
|
import {faBookmark as farBookmark} from '@fortawesome/free-regular-svg-icons/faBookmark'
|
||||||
|
import {faCalendar as farCalendar} from '@fortawesome/free-regular-svg-icons/faCalendar'
|
||||||
|
import {faCircle} from '@fortawesome/free-regular-svg-icons/faCircle'
|
||||||
|
import {faCircleCheck as farCircleCheck} from '@fortawesome/free-regular-svg-icons/faCircleCheck'
|
||||||
|
import {faCirclePlay} from '@fortawesome/free-regular-svg-icons/faCirclePlay'
|
||||||
|
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
||||||
|
import {faClone as farClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
||||||
|
import {faComment} from '@fortawesome/free-regular-svg-icons/faComment'
|
||||||
|
import {faComments} from '@fortawesome/free-regular-svg-icons/faComments'
|
||||||
|
import {faCompass} from '@fortawesome/free-regular-svg-icons/faCompass'
|
||||||
|
import {faEyeSlash as farEyeSlash} from '@fortawesome/free-regular-svg-icons/faEyeSlash'
|
||||||
|
import {faFaceSmile} from '@fortawesome/free-regular-svg-icons/faFaceSmile'
|
||||||
|
import {faFloppyDisk} from '@fortawesome/free-regular-svg-icons/faFloppyDisk'
|
||||||
|
import {faHand as farHand} from '@fortawesome/free-regular-svg-icons/faHand'
|
||||||
|
import {faHeart} from '@fortawesome/free-regular-svg-icons/faHeart'
|
||||||
|
import {faImage as farImage} from '@fortawesome/free-regular-svg-icons/faImage'
|
||||||
|
import {faMessage} from '@fortawesome/free-regular-svg-icons/faMessage'
|
||||||
|
import {faPaste} from '@fortawesome/free-regular-svg-icons/faPaste'
|
||||||
|
import {faSquare} from '@fortawesome/free-regular-svg-icons/faSquare'
|
||||||
|
import {faSquareCheck} from '@fortawesome/free-regular-svg-icons/faSquareCheck'
|
||||||
|
import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus'
|
||||||
|
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
||||||
|
import {faUser} from '@fortawesome/free-regular-svg-icons/faUser'
|
||||||
|
import {faFlask} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
import {faUniversalAccess} from '@fortawesome/free-solid-svg-icons'
|
||||||
import {faAngleDown} from '@fortawesome/free-solid-svg-icons/faAngleDown'
|
import {faAngleDown} from '@fortawesome/free-solid-svg-icons/faAngleDown'
|
||||||
import {faAngleLeft} from '@fortawesome/free-solid-svg-icons/faAngleLeft'
|
import {faAngleLeft} from '@fortawesome/free-solid-svg-icons/faAngleLeft'
|
||||||
import {faAngleRight} from '@fortawesome/free-solid-svg-icons/faAngleRight'
|
import {faAngleRight} from '@fortawesome/free-solid-svg-icons/faAngleRight'
|
||||||
import {faAngleUp} from '@fortawesome/free-solid-svg-icons/faAngleUp'
|
import {faAngleUp} from '@fortawesome/free-solid-svg-icons/faAngleUp'
|
||||||
|
import {faArrowDown} from '@fortawesome/free-solid-svg-icons/faArrowDown'
|
||||||
import {faArrowLeft} from '@fortawesome/free-solid-svg-icons/faArrowLeft'
|
import {faArrowLeft} from '@fortawesome/free-solid-svg-icons/faArrowLeft'
|
||||||
import {faArrowRight} from '@fortawesome/free-solid-svg-icons/faArrowRight'
|
import {faArrowRight} from '@fortawesome/free-solid-svg-icons/faArrowRight'
|
||||||
import {faArrowUp} from '@fortawesome/free-solid-svg-icons/faArrowUp'
|
|
||||||
import {faArrowDown} from '@fortawesome/free-solid-svg-icons/faArrowDown'
|
|
||||||
import {faArrowRightFromBracket} from '@fortawesome/free-solid-svg-icons/faArrowRightFromBracket'
|
import {faArrowRightFromBracket} from '@fortawesome/free-solid-svg-icons/faArrowRightFromBracket'
|
||||||
|
import {faArrowRotateLeft} from '@fortawesome/free-solid-svg-icons/faArrowRotateLeft'
|
||||||
|
import {faArrowsRotate} from '@fortawesome/free-solid-svg-icons/faArrowsRotate'
|
||||||
|
import {faArrowTrendUp} from '@fortawesome/free-solid-svg-icons/faArrowTrendUp'
|
||||||
|
import {faArrowUp} from '@fortawesome/free-solid-svg-icons/faArrowUp'
|
||||||
import {faArrowUpFromBracket} from '@fortawesome/free-solid-svg-icons/faArrowUpFromBracket'
|
import {faArrowUpFromBracket} from '@fortawesome/free-solid-svg-icons/faArrowUpFromBracket'
|
||||||
import {faArrowUpRightFromSquare} from '@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare'
|
import {faArrowUpRightFromSquare} from '@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare'
|
||||||
import {faArrowRotateLeft} from '@fortawesome/free-solid-svg-icons/faArrowRotateLeft'
|
|
||||||
import {faArrowTrendUp} from '@fortawesome/free-solid-svg-icons/faArrowTrendUp'
|
|
||||||
import {faArrowsRotate} from '@fortawesome/free-solid-svg-icons/faArrowsRotate'
|
|
||||||
import {faAt} from '@fortawesome/free-solid-svg-icons/faAt'
|
import {faAt} from '@fortawesome/free-solid-svg-icons/faAt'
|
||||||
import {faBars} from '@fortawesome/free-solid-svg-icons/faBars'
|
|
||||||
import {faBan} from '@fortawesome/free-solid-svg-icons/faBan'
|
import {faBan} from '@fortawesome/free-solid-svg-icons/faBan'
|
||||||
|
import {faBars} from '@fortawesome/free-solid-svg-icons/faBars'
|
||||||
import {faBell} from '@fortawesome/free-solid-svg-icons/faBell'
|
import {faBell} from '@fortawesome/free-solid-svg-icons/faBell'
|
||||||
import {faBell as farBell} from '@fortawesome/free-regular-svg-icons/faBell'
|
|
||||||
import {faBookmark} from '@fortawesome/free-solid-svg-icons/faBookmark'
|
import {faBookmark} from '@fortawesome/free-solid-svg-icons/faBookmark'
|
||||||
import {faBookmark as farBookmark} from '@fortawesome/free-regular-svg-icons/faBookmark'
|
|
||||||
import {faCalendar as farCalendar} from '@fortawesome/free-regular-svg-icons/faCalendar'
|
|
||||||
import {faCamera} from '@fortawesome/free-solid-svg-icons/faCamera'
|
import {faCamera} from '@fortawesome/free-solid-svg-icons/faCamera'
|
||||||
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'
|
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck'
|
||||||
|
import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown'
|
||||||
import {faChevronRight} from '@fortawesome/free-solid-svg-icons/faChevronRight'
|
import {faChevronRight} from '@fortawesome/free-solid-svg-icons/faChevronRight'
|
||||||
import {faCircle} from '@fortawesome/free-regular-svg-icons/faCircle'
|
|
||||||
import {faCircleCheck as farCircleCheck} from '@fortawesome/free-regular-svg-icons/faCircleCheck'
|
|
||||||
import {faCircleCheck} from '@fortawesome/free-solid-svg-icons/faCircleCheck'
|
import {faCircleCheck} from '@fortawesome/free-solid-svg-icons/faCircleCheck'
|
||||||
import {faCircleDot} from '@fortawesome/free-solid-svg-icons/faCircleDot'
|
import {faCircleDot} from '@fortawesome/free-solid-svg-icons/faCircleDot'
|
||||||
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons/faCircleExclamation'
|
import {faCircleExclamation} from '@fortawesome/free-solid-svg-icons/faCircleExclamation'
|
||||||
import {faCirclePlay} from '@fortawesome/free-regular-svg-icons/faCirclePlay'
|
|
||||||
import {faCircleUser} from '@fortawesome/free-regular-svg-icons/faCircleUser'
|
|
||||||
import {faClone} from '@fortawesome/free-solid-svg-icons/faClone'
|
import {faClone} from '@fortawesome/free-solid-svg-icons/faClone'
|
||||||
import {faClone as farClone} from '@fortawesome/free-regular-svg-icons/faClone'
|
|
||||||
import {faComment} from '@fortawesome/free-regular-svg-icons/faComment'
|
|
||||||
import {faCommentSlash} from '@fortawesome/free-solid-svg-icons/faCommentSlash'
|
import {faCommentSlash} from '@fortawesome/free-solid-svg-icons/faCommentSlash'
|
||||||
import {faComments} from '@fortawesome/free-regular-svg-icons/faComments'
|
|
||||||
import {faCompass} from '@fortawesome/free-regular-svg-icons/faCompass'
|
|
||||||
import {faDownload} from '@fortawesome/free-solid-svg-icons/faDownload'
|
import {faDownload} from '@fortawesome/free-solid-svg-icons/faDownload'
|
||||||
import {faEllipsis} from '@fortawesome/free-solid-svg-icons/faEllipsis'
|
import {faEllipsis} from '@fortawesome/free-solid-svg-icons/faEllipsis'
|
||||||
import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
import {faEnvelope} from '@fortawesome/free-solid-svg-icons/faEnvelope'
|
||||||
import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation'
|
import {faExclamation} from '@fortawesome/free-solid-svg-icons/faExclamation'
|
||||||
import {faEye} from '@fortawesome/free-solid-svg-icons/faEye'
|
import {faEye} from '@fortawesome/free-solid-svg-icons/faEye'
|
||||||
import {faEyeSlash as farEyeSlash} from '@fortawesome/free-regular-svg-icons/faEyeSlash'
|
import {faFilter} from '@fortawesome/free-solid-svg-icons/faFilter'
|
||||||
import {faFaceSmile} from '@fortawesome/free-regular-svg-icons/faFaceSmile'
|
|
||||||
import {faFire} from '@fortawesome/free-solid-svg-icons/faFire'
|
import {faFire} from '@fortawesome/free-solid-svg-icons/faFire'
|
||||||
import {faFlask} from '@fortawesome/free-solid-svg-icons'
|
|
||||||
import {faFloppyDisk} from '@fortawesome/free-regular-svg-icons/faFloppyDisk'
|
|
||||||
import {faGear} from '@fortawesome/free-solid-svg-icons/faGear'
|
import {faGear} from '@fortawesome/free-solid-svg-icons/faGear'
|
||||||
import {faGlobe} from '@fortawesome/free-solid-svg-icons/faGlobe'
|
import {faGlobe} from '@fortawesome/free-solid-svg-icons/faGlobe'
|
||||||
import {faHand} from '@fortawesome/free-solid-svg-icons/faHand'
|
import {faHand} from '@fortawesome/free-solid-svg-icons/faHand'
|
||||||
import {faHand as farHand} from '@fortawesome/free-regular-svg-icons/faHand'
|
|
||||||
import {faHashtag} from '@fortawesome/free-solid-svg-icons/faHashtag'
|
import {faHashtag} from '@fortawesome/free-solid-svg-icons/faHashtag'
|
||||||
import {faHeart} from '@fortawesome/free-regular-svg-icons/faHeart'
|
|
||||||
import {faHeart as fasHeart} from '@fortawesome/free-solid-svg-icons/faHeart'
|
import {faHeart as fasHeart} from '@fortawesome/free-solid-svg-icons/faHeart'
|
||||||
import {faHouse} from '@fortawesome/free-solid-svg-icons/faHouse'
|
import {faHouse} from '@fortawesome/free-solid-svg-icons/faHouse'
|
||||||
import {faImage as farImage} from '@fortawesome/free-regular-svg-icons/faImage'
|
|
||||||
import {faImage} from '@fortawesome/free-solid-svg-icons/faImage'
|
import {faImage} from '@fortawesome/free-solid-svg-icons/faImage'
|
||||||
import {faInfo} from '@fortawesome/free-solid-svg-icons/faInfo'
|
import {faInfo} from '@fortawesome/free-solid-svg-icons/faInfo'
|
||||||
import {faLanguage} from '@fortawesome/free-solid-svg-icons/faLanguage'
|
import {faLanguage} from '@fortawesome/free-solid-svg-icons/faLanguage'
|
||||||
|
@ -66,10 +75,8 @@ import {faList} from '@fortawesome/free-solid-svg-icons/faList'
|
||||||
import {faListUl} from '@fortawesome/free-solid-svg-icons/faListUl'
|
import {faListUl} from '@fortawesome/free-solid-svg-icons/faListUl'
|
||||||
import {faLock} from '@fortawesome/free-solid-svg-icons/faLock'
|
import {faLock} from '@fortawesome/free-solid-svg-icons/faLock'
|
||||||
import {faMagnifyingGlass} from '@fortawesome/free-solid-svg-icons/faMagnifyingGlass'
|
import {faMagnifyingGlass} from '@fortawesome/free-solid-svg-icons/faMagnifyingGlass'
|
||||||
import {faMessage} from '@fortawesome/free-regular-svg-icons/faMessage'
|
|
||||||
import {faNoteSticky} from '@fortawesome/free-solid-svg-icons/faNoteSticky'
|
import {faNoteSticky} from '@fortawesome/free-solid-svg-icons/faNoteSticky'
|
||||||
import {faPause} from '@fortawesome/free-solid-svg-icons/faPause'
|
import {faPause} from '@fortawesome/free-solid-svg-icons/faPause'
|
||||||
import {faPaste} from '@fortawesome/free-regular-svg-icons/faPaste'
|
|
||||||
import {faPen} from '@fortawesome/free-solid-svg-icons/faPen'
|
import {faPen} from '@fortawesome/free-solid-svg-icons/faPen'
|
||||||
import {faPenNib} from '@fortawesome/free-solid-svg-icons/faPenNib'
|
import {faPenNib} from '@fortawesome/free-solid-svg-icons/faPenNib'
|
||||||
import {faPenToSquare} from '@fortawesome/free-solid-svg-icons/faPenToSquare'
|
import {faPenToSquare} from '@fortawesome/free-solid-svg-icons/faPenToSquare'
|
||||||
|
@ -87,23 +94,16 @@ import {faShareFromSquare} from '@fortawesome/free-solid-svg-icons/faShareFromSq
|
||||||
import {faShield} from '@fortawesome/free-solid-svg-icons/faShield'
|
import {faShield} from '@fortawesome/free-solid-svg-icons/faShield'
|
||||||
import {faSignal} from '@fortawesome/free-solid-svg-icons/faSignal'
|
import {faSignal} from '@fortawesome/free-solid-svg-icons/faSignal'
|
||||||
import {faSliders} from '@fortawesome/free-solid-svg-icons/faSliders'
|
import {faSliders} from '@fortawesome/free-solid-svg-icons/faSliders'
|
||||||
import {faSquare} from '@fortawesome/free-regular-svg-icons/faSquare'
|
|
||||||
import {faSquareCheck} from '@fortawesome/free-regular-svg-icons/faSquareCheck'
|
|
||||||
import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus'
|
|
||||||
import {faThumbtack} from '@fortawesome/free-solid-svg-icons/faThumbtack'
|
import {faThumbtack} from '@fortawesome/free-solid-svg-icons/faThumbtack'
|
||||||
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
||||||
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
|
||||||
import {faUser} from '@fortawesome/free-regular-svg-icons/faUser'
|
|
||||||
import {faUsers} from '@fortawesome/free-solid-svg-icons/faUsers'
|
|
||||||
import {faUserCheck} from '@fortawesome/free-solid-svg-icons/faUserCheck'
|
import {faUserCheck} from '@fortawesome/free-solid-svg-icons/faUserCheck'
|
||||||
import {faUserSlash} from '@fortawesome/free-solid-svg-icons/faUserSlash'
|
|
||||||
import {faUserPlus} from '@fortawesome/free-solid-svg-icons/faUserPlus'
|
import {faUserPlus} from '@fortawesome/free-solid-svg-icons/faUserPlus'
|
||||||
import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark'
|
import {faUsers} from '@fortawesome/free-solid-svg-icons/faUsers'
|
||||||
|
import {faUserSlash} from '@fortawesome/free-solid-svg-icons/faUserSlash'
|
||||||
import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash'
|
import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash'
|
||||||
|
import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark'
|
||||||
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
||||||
import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark'
|
import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark'
|
||||||
import {faChevronDown} from '@fortawesome/free-solid-svg-icons/faChevronDown'
|
|
||||||
import {faFilter} from '@fortawesome/free-solid-svg-icons/faFilter'
|
|
||||||
|
|
||||||
library.add(
|
library.add(
|
||||||
faAddressCard,
|
faAddressCard,
|
||||||
|
@ -196,6 +196,7 @@ library.add(
|
||||||
faSquare,
|
faSquare,
|
||||||
faSquareCheck,
|
faSquareCheck,
|
||||||
faSquarePlus,
|
faSquarePlus,
|
||||||
|
faUniversalAccess,
|
||||||
faUser,
|
faUser,
|
||||||
faUsers,
|
faUsers,
|
||||||
faUserCheck,
|
faUserCheck,
|
||||||
|
|
|
@ -0,0 +1,132 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {StyleSheet, View} from 'react-native'
|
||||||
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {isNative} from '#/platform/detection'
|
||||||
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
|
import {useAnalytics} from 'lib/analytics/analytics'
|
||||||
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
||||||
|
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
|
||||||
|
import {s} from 'lib/styles'
|
||||||
|
import {
|
||||||
|
useAutoplayDisabled,
|
||||||
|
useHapticsDisabled,
|
||||||
|
useRequireAltTextEnabled,
|
||||||
|
useSetAutoplayDisabled,
|
||||||
|
useSetHapticsDisabled,
|
||||||
|
useSetRequireAltTextEnabled,
|
||||||
|
} from 'state/preferences'
|
||||||
|
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
|
||||||
|
import {SimpleViewHeader} from '../com/util/SimpleViewHeader'
|
||||||
|
import {Text} from '../com/util/text/Text'
|
||||||
|
import {ScrollView} from '../com/util/Views'
|
||||||
|
|
||||||
|
type Props = NativeStackScreenProps<
|
||||||
|
CommonNavigatorParams,
|
||||||
|
'AccessibilitySettings'
|
||||||
|
>
|
||||||
|
export function AccessibilitySettingsScreen({}: Props) {
|
||||||
|
const pal = usePalette('default')
|
||||||
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
|
const {screen} = useAnalytics()
|
||||||
|
const {isMobile} = useWebMediaQueries()
|
||||||
|
const {_} = useLingui()
|
||||||
|
|
||||||
|
const requireAltTextEnabled = useRequireAltTextEnabled()
|
||||||
|
const setRequireAltTextEnabled = useSetRequireAltTextEnabled()
|
||||||
|
const autoplayDisabled = useAutoplayDisabled()
|
||||||
|
const setAutoplayDisabled = useSetAutoplayDisabled()
|
||||||
|
const hapticsDisabled = useHapticsDisabled()
|
||||||
|
const setHapticsDisabled = useSetHapticsDisabled()
|
||||||
|
|
||||||
|
useFocusEffect(
|
||||||
|
React.useCallback(() => {
|
||||||
|
screen('PreferencesExternalEmbeds')
|
||||||
|
setMinimalShellMode(false)
|
||||||
|
}, [screen, setMinimalShellMode]),
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={s.hContentRegion} testID="accessibilitySettingsScreen">
|
||||||
|
<SimpleViewHeader
|
||||||
|
showBackButton={isMobile}
|
||||||
|
style={[
|
||||||
|
pal.border,
|
||||||
|
{borderBottomWidth: 1},
|
||||||
|
!isMobile && {borderLeftWidth: 1, borderRightWidth: 1},
|
||||||
|
]}>
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
<Text type="title-lg" style={[pal.text, {fontWeight: 'bold'}]}>
|
||||||
|
<Trans>Accessibility Settings</Trans>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</SimpleViewHeader>
|
||||||
|
<ScrollView
|
||||||
|
// @ts-ignore web only -prf
|
||||||
|
dataSet={{'stable-gutters': 1}}
|
||||||
|
style={s.flex1}
|
||||||
|
contentContainerStyle={[
|
||||||
|
s.flex1,
|
||||||
|
{paddingBottom: 200},
|
||||||
|
isMobile && pal.viewLight,
|
||||||
|
]}>
|
||||||
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
|
<Trans>Alt text</Trans>
|
||||||
|
</Text>
|
||||||
|
<View style={[pal.view, styles.toggleCard]}>
|
||||||
|
<ToggleButton
|
||||||
|
type="default-light"
|
||||||
|
label={_(msg`Require alt text before posting`)}
|
||||||
|
labelType="lg"
|
||||||
|
isSelected={requireAltTextEnabled}
|
||||||
|
onPress={() => setRequireAltTextEnabled(!requireAltTextEnabled)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
|
<Trans>Media</Trans>
|
||||||
|
</Text>
|
||||||
|
<View style={[pal.view, styles.toggleCard]}>
|
||||||
|
<ToggleButton
|
||||||
|
type="default-light"
|
||||||
|
label={_(msg`Disable autoplay for GIFs`)}
|
||||||
|
labelType="lg"
|
||||||
|
isSelected={autoplayDisabled}
|
||||||
|
onPress={() => setAutoplayDisabled(!autoplayDisabled)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
{isNative && (
|
||||||
|
<>
|
||||||
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
|
<Trans>Haptics</Trans>
|
||||||
|
</Text>
|
||||||
|
<View style={[pal.view, styles.toggleCard]}>
|
||||||
|
<ToggleButton
|
||||||
|
type="default-light"
|
||||||
|
label={_(msg`Disable haptic feedback`)}
|
||||||
|
labelType="lg"
|
||||||
|
isSelected={hapticsDisabled}
|
||||||
|
onPress={() => setHapticsDisabled(!hapticsDisabled)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
heading: {
|
||||||
|
paddingHorizontal: 18,
|
||||||
|
paddingTop: 14,
|
||||||
|
paddingBottom: 6,
|
||||||
|
},
|
||||||
|
toggleCard: {
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 6,
|
||||||
|
marginBottom: 1,
|
||||||
|
},
|
||||||
|
})
|
|
@ -20,14 +20,10 @@ import {useLingui} from '@lingui/react'
|
||||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {isIOS, isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {useModalControls} from '#/state/modals'
|
import {useModalControls} from '#/state/modals'
|
||||||
import {clearLegacyStorage} from '#/state/persisted/legacy'
|
import {clearLegacyStorage} from '#/state/persisted/legacy'
|
||||||
import {clear as clearStorage} from '#/state/persisted/store'
|
import {clear as clearStorage} from '#/state/persisted/store'
|
||||||
import {
|
|
||||||
useRequireAltTextEnabled,
|
|
||||||
useSetRequireAltTextEnabled,
|
|
||||||
} from '#/state/preferences'
|
|
||||||
import {
|
import {
|
||||||
useInAppBrowser,
|
useInAppBrowser,
|
||||||
useSetInAppBrowser,
|
useSetInAppBrowser,
|
||||||
|
@ -56,10 +52,6 @@ import {makeProfileLink} from 'lib/routes/links'
|
||||||
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
|
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
|
||||||
import {NavigationProp} from 'lib/routes/types'
|
import {NavigationProp} from 'lib/routes/types'
|
||||||
import {colors, s} from 'lib/styles'
|
import {colors, s} from 'lib/styles'
|
||||||
import {
|
|
||||||
useHapticsDisabled,
|
|
||||||
useSetHapticsDisabled,
|
|
||||||
} from 'state/preferences/disable-haptics'
|
|
||||||
import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn'
|
import {AccountDropdownBtn} from 'view/com/util/AccountDropdownBtn'
|
||||||
import {SelectableBtn} from 'view/com/util/forms/SelectableBtn'
|
import {SelectableBtn} from 'view/com/util/forms/SelectableBtn'
|
||||||
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
|
import {ToggleButton} from 'view/com/util/forms/ToggleButton'
|
||||||
|
@ -162,12 +154,8 @@ export function SettingsScreen({}: Props) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const requireAltTextEnabled = useRequireAltTextEnabled()
|
|
||||||
const setRequireAltTextEnabled = useSetRequireAltTextEnabled()
|
|
||||||
const inAppBrowserPref = useInAppBrowser()
|
const inAppBrowserPref = useInAppBrowser()
|
||||||
const setUseInAppBrowser = useSetInAppBrowser()
|
const setUseInAppBrowser = useSetInAppBrowser()
|
||||||
const isHapticsDisabled = useHapticsDisabled()
|
|
||||||
const setHapticsDisabled = useSetHapticsDisabled()
|
|
||||||
const onboardingDispatch = useOnboardingDispatch()
|
const onboardingDispatch = useOnboardingDispatch()
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
const {isMobile} = useWebMediaQueries()
|
const {isMobile} = useWebMediaQueries()
|
||||||
|
@ -282,6 +270,10 @@ export function SettingsScreen({}: Props) {
|
||||||
navigation.navigate('SavedFeeds')
|
navigation.navigate('SavedFeeds')
|
||||||
}, [navigation])
|
}, [navigation])
|
||||||
|
|
||||||
|
const onPressAccessibilitySettings = React.useCallback(() => {
|
||||||
|
navigation.navigate('AccessibilitySettings')
|
||||||
|
}, [navigation])
|
||||||
|
|
||||||
const onPressStatusPage = React.useCallback(() => {
|
const onPressStatusPage = React.useCallback(() => {
|
||||||
Linking.openURL(STATUS_PAGE_URL)
|
Linking.openURL(STATUS_PAGE_URL)
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -318,7 +310,7 @@ export function SettingsScreen({}: Props) {
|
||||||
</View>
|
</View>
|
||||||
</SimpleViewHeader>
|
</SimpleViewHeader>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
style={[s.hContentRegion]}
|
style={s.hContentRegion}
|
||||||
contentContainerStyle={isMobile && pal.viewLight}
|
contentContainerStyle={isMobile && pal.viewLight}
|
||||||
scrollIndicatorInsets={{right: 1}}
|
scrollIndicatorInsets={{right: 1}}
|
||||||
// @ts-ignore web only -prf
|
// @ts-ignore web only -prf
|
||||||
|
@ -417,21 +409,6 @@ export function SettingsScreen({}: Props) {
|
||||||
|
|
||||||
<View style={styles.spacer20} />
|
<View style={styles.spacer20} />
|
||||||
|
|
||||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
|
||||||
<Trans>Accessibility</Trans>
|
|
||||||
</Text>
|
|
||||||
<View style={[pal.view, styles.toggleCard]}>
|
|
||||||
<ToggleButton
|
|
||||||
type="default-light"
|
|
||||||
label={_(msg`Require alt text before posting`)}
|
|
||||||
labelType="lg"
|
|
||||||
isSelected={requireAltTextEnabled}
|
|
||||||
onPress={() => setRequireAltTextEnabled(!requireAltTextEnabled)}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.spacer20} />
|
|
||||||
|
|
||||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
<Trans>Appearance</Trans>
|
<Trans>Appearance</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -492,6 +469,29 @@ export function SettingsScreen({}: Props) {
|
||||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
<Trans>Basics</Trans>
|
<Trans>Basics</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
<TouchableOpacity
|
||||||
|
testID="accessibilitySettingsBtn"
|
||||||
|
style={[
|
||||||
|
styles.linkCard,
|
||||||
|
pal.view,
|
||||||
|
isSwitchingAccounts && styles.dimmed,
|
||||||
|
]}
|
||||||
|
onPress={
|
||||||
|
isSwitchingAccounts ? undefined : onPressAccessibilitySettings
|
||||||
|
}
|
||||||
|
accessibilityRole="button"
|
||||||
|
accessibilityLabel={_(msg`Accessibility settings`)}
|
||||||
|
accessibilityHint={_(msg`Opens accessibility settings`)}>
|
||||||
|
<View style={[styles.iconContainer, pal.btn]}>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="universal-access"
|
||||||
|
style={pal.text as FontAwesomeIconStyle}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text type="lg" style={pal.text}>
|
||||||
|
<Trans>Accessibility</Trans>
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
testID="preferencesHomeFeedButton"
|
testID="preferencesHomeFeedButton"
|
||||||
style={[
|
style={[
|
||||||
|
@ -689,19 +689,6 @@ export function SettingsScreen({}: Props) {
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
{isNative && (
|
|
||||||
<View style={[pal.view, styles.toggleCard]}>
|
|
||||||
<ToggleButton
|
|
||||||
type="default-light"
|
|
||||||
label={
|
|
||||||
isIOS ? _(msg`Disable haptics`) : _(msg`Disable vibrations`)
|
|
||||||
}
|
|
||||||
labelType="lg"
|
|
||||||
isSelected={isHapticsDisabled}
|
|
||||||
onPress={() => setHapticsDisabled(!isHapticsDisabled)}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
<View style={styles.spacer20} />
|
<View style={styles.spacer20} />
|
||||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
<Trans>Account</Trans>
|
<Trans>Account</Trans>
|
||||||
|
|
Loading…
Reference in New Issue