Composer - fix modals, and other tweaks (#4298)

* fix depreciated import

* add animations to old dropdown

* wrap modals in fullwindowoverlay

* move errors inside header

* add background to bottom bar and stop overlap

* nest dialogs on android

* fix android (wrap in gesturehandlerrootview)

* make borders all the same color

* revert threadgate button back to solid
This commit is contained in:
Samuel Newman
2024-05-31 14:55:51 +03:00
committed by GitHub
parent d614f6cb71
commit 05b55c1966
11 changed files with 269 additions and 221 deletions
+118 -110
View File
@@ -181,12 +181,7 @@ export const ComposePost = observer(function ComposePost({
borderColor: interpolateColor(
hasScrolled.value,
[0, 1],
[
'transparent',
isWeb
? t.atoms.border_contrast_low.borderColor
: t.atoms.border_contrast_high.borderColor,
],
['transparent', t.atoms.border_contrast_medium.borderColor],
),
}
})
@@ -405,106 +400,112 @@ export const ComposePost = observer(function ComposePost({
<KeyboardAvoidingView
testID="composePostView"
behavior="padding"
style={s.flex1}
keyboardVerticalOffset={replyTo ? 60 : isAndroid ? 120 : 100}>
<View style={[s.flex1, viewStyles]} aria-modal accessibilityViewIsModal>
style={a.flex_1}
keyboardVerticalOffset={replyTo ? 120 : isAndroid ? 180 : 150}>
<View
style={[a.flex_1, viewStyles]}
aria-modal
accessibilityViewIsModal>
<Animated.View
style={[
styles.topbar,
topBarAnimatedStyle,
isWeb && isTabletOrDesktop && styles.topbarDesktop,
]}>
<TouchableOpacity
testID="composerDiscardButton"
onPress={onPressCancel}
onAccessibilityEscape={onPressCancel}
accessibilityRole="button"
accessibilityLabel={_(msg`Cancel`)}
accessibilityHint={_(
msg`Closes post composer and discards post draft`,
)}
hitSlop={HITSLOP_10}>
<Text style={[pal.link, s.f18]}>
<Trans>Cancel</Trans>
</Text>
</TouchableOpacity>
<View style={s.flex1} />
{isProcessing ? (
<>
<Text style={pal.textLight}>{processingState}</Text>
<View style={styles.postBtn}>
<ActivityIndicator />
</View>
</>
) : (
<>
<LabelsBtn
labels={labels}
onChange={setLabels}
hasMedia={hasMedia}
/>
{canPost ? (
<TouchableOpacity
testID="composerPublishBtn"
onPress={onPressPublish}
accessibilityRole="button"
accessibilityLabel={
replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)
}
accessibilityHint="">
<LinearGradient
colors={[
gradients.blueLight.start,
gradients.blueLight.end,
]}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}
style={styles.postBtn}>
<Text style={[s.white, s.f16, s.bold]}>
{replyTo ? (
<Trans context="action">Reply</Trans>
) : (
<Trans context="action">Post</Trans>
)}
</Text>
</LinearGradient>
</TouchableOpacity>
) : (
<View style={[styles.postBtn, pal.btn]}>
<Text style={[pal.textLight, s.f16, s.bold]}>
<Trans context="action">Post</Trans>
</Text>
</View>
<View style={styles.topbarInner}>
<TouchableOpacity
testID="composerDiscardButton"
onPress={onPressCancel}
onAccessibilityEscape={onPressCancel}
accessibilityRole="button"
accessibilityLabel={_(msg`Cancel`)}
accessibilityHint={_(
msg`Closes post composer and discards post draft`,
)}
</>
hitSlop={HITSLOP_10}>
<Text style={[pal.link, s.f18]}>
<Trans>Cancel</Trans>
</Text>
</TouchableOpacity>
<View style={a.flex_1} />
{isProcessing ? (
<>
<Text style={pal.textLight}>{processingState}</Text>
<View style={styles.postBtn}>
<ActivityIndicator />
</View>
</>
) : (
<>
<LabelsBtn
labels={labels}
onChange={setLabels}
hasMedia={hasMedia}
/>
{canPost ? (
<TouchableOpacity
testID="composerPublishBtn"
onPress={onPressPublish}
accessibilityRole="button"
accessibilityLabel={
replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)
}
accessibilityHint="">
<LinearGradient
colors={[
gradients.blueLight.start,
gradients.blueLight.end,
]}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}
style={styles.postBtn}>
<Text style={[s.white, s.f16, s.bold]}>
{replyTo ? (
<Trans context="action">Reply</Trans>
) : (
<Trans context="action">Post</Trans>
)}
</Text>
</LinearGradient>
</TouchableOpacity>
) : (
<View style={[styles.postBtn, pal.btn]}>
<Text style={[pal.textLight, s.f16, s.bold]}>
<Trans context="action">Post</Trans>
</Text>
</View>
)}
</>
)}
</View>
{isAltTextRequiredAndMissing && (
<View style={[styles.reminderLine, pal.viewLight]}>
<View style={styles.errorIcon}>
<FontAwesomeIcon
icon="exclamation"
style={{color: colors.red4}}
size={10}
/>
</View>
<Text style={[pal.text, a.flex_1]}>
<Trans>One or more images is missing alt text.</Trans>
</Text>
</View>
)}
{error !== '' && (
<View style={styles.errorLine}>
<View style={styles.errorIcon}>
<FontAwesomeIcon
icon="exclamation"
style={{color: colors.red4}}
size={10}
/>
</View>
<Text style={[s.red4, a.flex_1]}>{error}</Text>
</View>
)}
</Animated.View>
{isAltTextRequiredAndMissing && (
<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]}>
<Trans>One or more images is missing alt text.</Trans>
</Text>
</View>
)}
{error !== '' && (
<View style={styles.errorLine}>
<View style={styles.errorIcon}>
<FontAwesomeIcon
icon="exclamation"
style={{color: colors.red4}}
size={10}
/>
</View>
<Text style={[s.red4, s.flex1]}>{error}</Text>
</View>
)}
<Animated.ScrollView
onScroll={scrollHandler}
style={styles.scrollView}
@@ -576,7 +577,12 @@ export const ComposePost = observer(function ComposePost({
{replyTo ? null : (
<ThreadgateBtn threadgate={threadgate} onChange={setThreadgate} />
)}
<View style={[pal.border, styles.bottomBar]}>
<View
style={[
t.atoms.bg,
t.atoms.border_contrast_medium,
styles.bottomBar,
]}>
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
<SelectPhotoBtn gallery={gallery} disabled={!canSelectImages} />
<OpenCameraBtn gallery={gallery} disabled={!canSelectImages} />
@@ -598,7 +604,7 @@ export const ComposePost = observer(function ComposePost({
</Button>
) : null}
</View>
<View style={s.flex1} />
<View style={a.flex_1} />
<SelectLangBtn />
<CharProgress count={graphemeLength} />
</View>
@@ -621,11 +627,6 @@ export function useComposerCancelRef() {
const styles = StyleSheet.create({
topbar: {
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 16,
height: 54,
gap: 4,
borderBottomWidth: StyleSheet.hairlineWidth,
},
topbarDesktop: {
@@ -633,6 +634,13 @@ const styles = StyleSheet.create({
paddingBottom: 10,
height: 50,
},
topbarInner: {
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 16,
height: 54,
gap: 4,
},
postBtn: {
borderRadius: 20,
paddingHorizontal: 20,
@@ -643,19 +651,19 @@ const styles = StyleSheet.create({
flexDirection: 'row',
backgroundColor: colors.red1,
borderRadius: 6,
marginHorizontal: 15,
marginHorizontal: 16,
paddingHorizontal: 8,
paddingVertical: 6,
marginVertical: 6,
marginBottom: 8,
},
reminderLine: {
flexDirection: 'row',
alignItems: 'center',
borderRadius: 6,
marginHorizontal: 15,
marginHorizontal: 16,
paddingHorizontal: 8,
paddingVertical: 6,
marginBottom: 6,
marginBottom: 8,
},
errorIcon: {
borderWidth: hairlineWidth,
@@ -690,8 +698,8 @@ const styles = StyleSheet.create({
bottomBar: {
flexDirection: 'row',
paddingVertical: 4,
paddingLeft: 15,
paddingRight: 20,
paddingLeft: 8,
paddingRight: 16,
alignItems: 'center',
borderTopWidth: hairlineWidth,
},
+1 -5
View File
@@ -10,7 +10,6 @@ import {
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {isWeb} from '#/platform/detection'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {sanitizeHandle} from 'lib/strings/handles'
import {ComposerOptsPostRef} from 'state/shell/composer'
@@ -76,10 +75,7 @@ export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
return (
<Pressable
style={[
isWeb ? t.atoms.border_contrast_low : t.atoms.border_contrast_high,
styles.replyToLayout,
]}
style={[t.atoms.border_contrast_medium, styles.replyToLayout]}
onPress={onPress}
accessibilityRole="button"
accessibilityLabel={_(
@@ -7,7 +7,7 @@ import {isNative} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {ThreadgateSetting} from '#/state/queries/threadgate'
import {useAnalytics} from 'lib/analytics/analytics'
import {atoms as a} from '#/alf'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign'
import {Earth_Stroke2_Corner0_Rounded as Earth} from '#/components/icons/Globe'
@@ -22,6 +22,7 @@ export function ThreadgateBtn({
}) {
const {track} = useAnalytics()
const {_} = useLingui()
const t = useTheme()
const {openModal} = useModalControls()
const onPress = () => {
@@ -45,7 +46,7 @@ export function ThreadgateBtn({
: _(msg`Some people can reply`)
return (
<View style={[a.flex_row, a.pb_sm, a.px_md]}>
<View style={[a.flex_row, a.py_xs, a.px_sm, t.atoms.bg]}>
<Button
variant="solid"
color="secondary"