* Add alt text validation option to user preferences * Fix typos/linting issues * Update accessibility setting to match styles * Update the required alt text reminder to go away once it's added --------- Co-authored-by: Emma Fuller <emma@emmafuller.dev>zio/stable
parent
bc55241c9a
commit
696bffe832
|
@ -23,6 +23,10 @@ export class GalleryModel {
|
|||
return this.images.length
|
||||
}
|
||||
|
||||
get needsAltText() {
|
||||
return this.images.some(image => image.altText.trim() === '')
|
||||
}
|
||||
|
||||
async add(image_: Omit<RNImage, 'size'>) {
|
||||
if (this.size >= 4) {
|
||||
return
|
||||
|
|
|
@ -53,6 +53,7 @@ export class PreferencesModel {
|
|||
homeFeedRepliesThreshold: number = 2
|
||||
homeFeedRepostsEnabled: boolean = true
|
||||
homeFeedQuotePostsEnabled: boolean = true
|
||||
requireAltTextEnabled: boolean = false
|
||||
|
||||
// used to linearize async modifications to state
|
||||
lock = new AwaitLock()
|
||||
|
@ -72,6 +73,7 @@ export class PreferencesModel {
|
|||
homeFeedRepliesThreshold: this.homeFeedRepliesThreshold,
|
||||
homeFeedRepostsEnabled: this.homeFeedRepostsEnabled,
|
||||
homeFeedQuotePostsEnabled: this.homeFeedQuotePostsEnabled,
|
||||
requireAltTextEnabled: this.requireAltTextEnabled,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,6 +154,13 @@ export class PreferencesModel {
|
|||
) {
|
||||
this.homeFeedQuotePostsEnabled = v.homeFeedQuotePostsEnabled
|
||||
}
|
||||
// check if requiring alt text is enabled in preferences, then hydrate
|
||||
if (
|
||||
hasProp(v, 'requireAltTextEnabled') &&
|
||||
typeof v.requireAltTextEnabled === 'boolean'
|
||||
) {
|
||||
this.requireAltTextEnabled = v.requireAltTextEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,4 +476,8 @@ export class PreferencesModel {
|
|||
toggleHomeFeedQuotePostsEnabled() {
|
||||
this.homeFeedQuotePostsEnabled = !this.homeFeedQuotePostsEnabled
|
||||
}
|
||||
|
||||
toggleRequireAltTextEnabled() {
|
||||
this.requireAltTextEnabled = !this.requireAltTextEnabled
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,9 @@ export const ComposePost = observer(function ComposePost({
|
|||
if (isProcessing || rt.graphemeLength > MAX_GRAPHEME_LENGTH) {
|
||||
return
|
||||
}
|
||||
if (store.preferences.requireAltTextEnabled && gallery.needsAltText) {
|
||||
return
|
||||
}
|
||||
|
||||
setError('')
|
||||
|
||||
|
@ -220,8 +223,14 @@ export const ComposePost = observer(function ComposePost({
|
|||
)
|
||||
|
||||
const canPost = useMemo(
|
||||
() => graphemeLength <= MAX_GRAPHEME_LENGTH,
|
||||
[graphemeLength],
|
||||
() =>
|
||||
graphemeLength <= MAX_GRAPHEME_LENGTH &&
|
||||
(!store.preferences.requireAltTextEnabled || !gallery.needsAltText),
|
||||
[
|
||||
graphemeLength,
|
||||
store.preferences.requireAltTextEnabled,
|
||||
gallery.needsAltText,
|
||||
],
|
||||
)
|
||||
const selectTextInputPlaceholder = replyTo ? 'Write your reply' : `What's up?`
|
||||
|
||||
|
@ -282,6 +291,20 @@ export const ComposePost = observer(function ComposePost({
|
|||
<Text style={pal.text}>{processingState}</Text>
|
||||
</View>
|
||||
) : undefined}
|
||||
{store.preferences.requireAltTextEnabled && gallery.needsAltText && (
|
||||
<View style={[styles.reminderLine, pal.viewLight]}>
|
||||
<View style={styles.errorIcon}>
|
||||
<FontAwesomeIcon
|
||||
icon="exclamation"
|
||||
style={{color: colors.red4}}
|
||||
size={10}
|
||||
/>
|
||||
</View>
|
||||
<Text style={[pal.text, s.flex1]}>
|
||||
One or more images is missing alt text.
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
{error !== '' && (
|
||||
<View style={styles.errorLine}>
|
||||
<View style={styles.errorIcon}>
|
||||
|
@ -415,6 +438,15 @@ const styles = StyleSheet.create({
|
|||
paddingVertical: 6,
|
||||
marginVertical: 6,
|
||||
},
|
||||
reminderLine: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderRadius: 6,
|
||||
marginHorizontal: 15,
|
||||
paddingHorizontal: 8,
|
||||
paddingVertical: 6,
|
||||
marginBottom: 6,
|
||||
},
|
||||
errorIcon: {
|
||||
borderWidth: 1,
|
||||
borderColor: colors.red4,
|
||||
|
|
|
@ -5,18 +5,21 @@ import {Button, ButtonType} from './Button'
|
|||
import {useTheme} from 'lib/ThemeContext'
|
||||
import {choose} from 'lib/functions'
|
||||
import {colors} from 'lib/styles'
|
||||
import {TypographyVariant} from 'lib/ThemeContext'
|
||||
|
||||
export function ToggleButton({
|
||||
type = 'default-light',
|
||||
label,
|
||||
isSelected,
|
||||
style,
|
||||
labelType,
|
||||
onPress,
|
||||
}: {
|
||||
type?: ButtonType
|
||||
label: string
|
||||
isSelected: boolean
|
||||
style?: StyleProp<ViewStyle>
|
||||
labelType?: TypographyVariant
|
||||
onPress?: () => void
|
||||
}) {
|
||||
const theme = useTheme()
|
||||
|
@ -143,7 +146,7 @@ export function ToggleButton({
|
|||
/>
|
||||
</View>
|
||||
{label === '' ? null : (
|
||||
<Text type="button" style={[labelStyle, styles.label]}>
|
||||
<Text type={labelType || 'button'} style={[labelStyle, styles.label]}>
|
||||
{label}
|
||||
</Text>
|
||||
)}
|
||||
|
|
|
@ -330,6 +330,22 @@ export const SettingsScreen = withAuthRequired(
|
|||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.spacer20} />
|
||||
|
||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||
Accessibility
|
||||
</Text>
|
||||
<View style={[pal.view, styles.toggleCard]}>
|
||||
<ToggleButton
|
||||
type="default-light"
|
||||
label="Require alt text on images"
|
||||
labelType="lg"
|
||||
isSelected={store.preferences.requireAltTextEnabled}
|
||||
onPress={store.preferences.toggleRequireAltTextEnabled}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View style={styles.spacer20} />
|
||||
|
||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||
Appearance
|
||||
</Text>
|
||||
|
@ -633,6 +649,11 @@ const styles = StyleSheet.create({
|
|||
paddingHorizontal: 18,
|
||||
marginBottom: 1,
|
||||
},
|
||||
toggleCard: {
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 6,
|
||||
marginBottom: 1,
|
||||
},
|
||||
avi: {
|
||||
marginRight: 12,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue