Move self-label button (#5780)
* move self label button? * rm * make sure its usable on large font sizes * tweak wording * update icon * tweaks * change button label and change opacity when no media (#5794) * Tweak it moar (#5807) * Tweak it moar * Pluralize * Labels --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com> Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
|||||||
Keyboard,
|
Keyboard,
|
||||||
KeyboardAvoidingView,
|
KeyboardAvoidingView,
|
||||||
LayoutChangeEvent,
|
LayoutChangeEvent,
|
||||||
|
ScrollView,
|
||||||
StyleProp,
|
StyleProp,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
@@ -559,30 +560,17 @@ export const ComposePost = ({
|
|||||||
<ActivityIndicator />
|
<ActivityIndicator />
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : canPost ? (
|
||||||
<View style={[styles.postBtnWrapper]}>
|
|
||||||
<LabelsBtn
|
|
||||||
labels={draft.labels}
|
|
||||||
onChange={nextLabels => {
|
|
||||||
dispatch({type: 'update_labels', labels: nextLabels})
|
|
||||||
}}
|
|
||||||
hasMedia={hasMedia || Boolean(extLink)}
|
|
||||||
/>
|
|
||||||
{canPost ? (
|
|
||||||
<Button
|
<Button
|
||||||
testID="composerPublishBtn"
|
testID="composerPublishBtn"
|
||||||
label={
|
label={replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)}
|
||||||
replyTo ? _(msg`Publish reply`) : _(msg`Publish post`)
|
|
||||||
}
|
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="primary"
|
color="primary"
|
||||||
shape="default"
|
shape="default"
|
||||||
size="small"
|
size="small"
|
||||||
style={[a.rounded_full, a.py_sm]}
|
style={[a.rounded_full, a.py_sm]}
|
||||||
onPress={() => onPressPublish()}
|
onPress={() => onPressPublish()}
|
||||||
disabled={
|
disabled={videoState.status !== 'idle' && publishOnUpload}>
|
||||||
videoState.status !== 'idle' && publishOnUpload
|
|
||||||
}>
|
|
||||||
<ButtonText style={[a.text_md]}>
|
<ButtonText style={[a.text_md]}>
|
||||||
{replyTo ? (
|
{replyTo ? (
|
||||||
<Trans context="action">Reply</Trans>
|
<Trans context="action">Reply</Trans>
|
||||||
@@ -599,8 +587,6 @@ export const ComposePost = ({
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{isAltTextRequiredAndMissing && (
|
{isAltTextRequiredAndMissing && (
|
||||||
<View style={[styles.reminderLine, pal.viewLight]}>
|
<View style={[styles.reminderLine, pal.viewLight]}>
|
||||||
@@ -758,6 +744,13 @@ export const ComposePost = ({
|
|||||||
</Animated.ScrollView>
|
</Animated.ScrollView>
|
||||||
<SuggestedLanguage text={richtext.text} />
|
<SuggestedLanguage text={richtext.text} />
|
||||||
|
|
||||||
|
<Animated.View
|
||||||
|
style={[a.flex_row, a.p_sm, t.atoms.bg, bottomBarAnimatedStyle]}>
|
||||||
|
<ScrollView
|
||||||
|
contentContainerStyle={[a.gap_sm]}
|
||||||
|
horizontal={true}
|
||||||
|
bounces={false}
|
||||||
|
showsHorizontalScrollIndicator={false}>
|
||||||
{replyTo ? null : (
|
{replyTo ? null : (
|
||||||
<ThreadgateBtn
|
<ThreadgateBtn
|
||||||
postgate={draft.postgate}
|
postgate={draft.postgate}
|
||||||
@@ -774,6 +767,15 @@ export const ComposePost = ({
|
|||||||
style={bottomBarAnimatedStyle}
|
style={bottomBarAnimatedStyle}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<LabelsBtn
|
||||||
|
labels={draft.labels}
|
||||||
|
onChange={nextLabels => {
|
||||||
|
dispatch({type: 'update_labels', labels: nextLabels})
|
||||||
|
}}
|
||||||
|
hasMedia={hasMedia || Boolean(extLink)}
|
||||||
|
/>
|
||||||
|
</ScrollView>
|
||||||
|
</Animated.View>
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
@@ -988,10 +990,6 @@ const styles = StyleSheet.create({
|
|||||||
paddingVertical: 6,
|
paddingVertical: 6,
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
},
|
},
|
||||||
postBtnWrapper: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
gap: 14,
|
|
||||||
},
|
|
||||||
errorLine: {
|
errorLine: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {Keyboard, View} from 'react-native'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {ShieldExclamation} from '#/lib/icons'
|
|
||||||
import {
|
import {
|
||||||
ADULT_CONTENT_LABELS,
|
ADULT_CONTENT_LABELS,
|
||||||
AdultSelfLabel,
|
AdultSelfLabel,
|
||||||
@@ -12,12 +11,14 @@ import {
|
|||||||
SelfLabel,
|
SelfLabel,
|
||||||
} from '#/lib/moderation'
|
} from '#/lib/moderation'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import * as Toggle from '#/components/forms/Toggle'
|
import * as Toggle from '#/components/forms/Toggle'
|
||||||
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
|
||||||
|
import {Shield_Stroke2_Corner0_Rounded} from '#/components/icons/Shield'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export function LabelsBtn({
|
export function LabelsBtn({
|
||||||
labels,
|
labels,
|
||||||
hasMedia,
|
hasMedia,
|
||||||
@@ -28,7 +29,6 @@ export function LabelsBtn({
|
|||||||
onChange: (v: SelfLabel[]) => void
|
onChange: (v: SelfLabel[]) => void
|
||||||
}) {
|
}) {
|
||||||
const control = Dialog.useDialogControl()
|
const control = Dialog.useDialogControl()
|
||||||
const t = useTheme()
|
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|
||||||
const hasLabel = labels.length > 0
|
const hasLabel = labels.length > 0
|
||||||
@@ -52,20 +52,33 @@ export function LabelsBtn({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
color="secondary"
|
||||||
|
size="small"
|
||||||
testID="labelsBtn"
|
testID="labelsBtn"
|
||||||
style={!hasMedia && {opacity: 0.4}}
|
onPress={() => {
|
||||||
|
Keyboard.dismiss()
|
||||||
|
control.open()
|
||||||
|
}}
|
||||||
label={_(msg`Content warnings`)}
|
label={_(msg`Content warnings`)}
|
||||||
accessibilityHint={_(
|
accessibilityHint={_(
|
||||||
msg`Opens a dialog to add a content warning to your post`,
|
msg`Opens a dialog to add a content warning to your post`,
|
||||||
)}
|
)}
|
||||||
onPress={() => {
|
style={[
|
||||||
Keyboard.dismiss()
|
!hasMedia && {opacity: 0.5},
|
||||||
control.open()
|
native({
|
||||||
}}>
|
paddingHorizontal: 8,
|
||||||
<ShieldExclamation style={{color: t.palette.primary_500}} size={24} />
|
paddingVertical: 6,
|
||||||
|
}),
|
||||||
|
]}>
|
||||||
|
<ButtonIcon icon={hasLabel ? Check : Shield_Stroke2_Corner0_Rounded} />
|
||||||
|
<ButtonText numberOfLines={1}>
|
||||||
{labels.length > 0 ? (
|
{labels.length > 0 ? (
|
||||||
<Check size="sm" fill={t.palette.primary_500} />
|
<Trans>Labels added</Trans>
|
||||||
) : null}
|
) : (
|
||||||
|
<Trans>Labels</Trans>
|
||||||
|
)}
|
||||||
|
</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
||||||
@@ -114,7 +127,8 @@ function DialogInner({
|
|||||||
</Trans>
|
</Trans>
|
||||||
) : (
|
) : (
|
||||||
<Trans>
|
<Trans>
|
||||||
There are no self-labels that can be applied to this post.
|
No self-labels can be applied to this post because it contains
|
||||||
|
no media.
|
||||||
</Trans>
|
</Trans>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
@@ -235,7 +249,7 @@ function DialogInner({
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[a.mt_sm]}>
|
<View style={[a.mt_sm, web([a.flex_row, a.ml_auto])]}>
|
||||||
<Button
|
<Button
|
||||||
label={_(msg`Done`)}
|
label={_(msg`Done`)}
|
||||||
onPress={() => control.close()}
|
onPress={() => control.close()}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Keyboard, StyleProp, ViewStyle} from 'react-native'
|
import {Keyboard, StyleProp, ViewStyle} from 'react-native'
|
||||||
import Animated, {AnimatedStyle} from 'react-native-reanimated'
|
import {AnimatedStyle} from 'react-native-reanimated'
|
||||||
import {AppBskyFeedPostgate} from '@atproto/api'
|
import {AppBskyFeedPostgate} from '@atproto/api'
|
||||||
import {msg} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
|
import {ThreadgateAllowUISetting} from '#/state/queries/threadgate'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {native} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import {PostInteractionSettingsControlledDialog} from '#/components/dialogs/PostInteractionSettingsDialog'
|
import {PostInteractionSettingsControlledDialog} from '#/components/dialogs/PostInteractionSettingsDialog'
|
||||||
@@ -19,7 +19,6 @@ export function ThreadgateBtn({
|
|||||||
onChangePostgate,
|
onChangePostgate,
|
||||||
threadgateAllowUISettings,
|
threadgateAllowUISettings,
|
||||||
onChangeThreadgateAllowUISettings,
|
onChangeThreadgateAllowUISettings,
|
||||||
style,
|
|
||||||
}: {
|
}: {
|
||||||
postgate: AppBskyFeedPostgate.Record
|
postgate: AppBskyFeedPostgate.Record
|
||||||
onChangePostgate: (v: AppBskyFeedPostgate.Record) => void
|
onChangePostgate: (v: AppBskyFeedPostgate.Record) => void
|
||||||
@@ -30,7 +29,6 @@ export function ThreadgateBtn({
|
|||||||
style?: StyleProp<AnimatedStyle<ViewStyle>>
|
style?: StyleProp<AnimatedStyle<ViewStyle>>
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
|
||||||
const control = Dialog.useDialogControl()
|
const control = Dialog.useDialogControl()
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
@@ -53,7 +51,6 @@ export function ThreadgateBtn({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Animated.View style={[a.flex_row, a.p_sm, t.atoms.bg, style]}>
|
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@@ -64,13 +61,15 @@ export function ThreadgateBtn({
|
|||||||
accessibilityHint={_(
|
accessibilityHint={_(
|
||||||
msg`Opens a dialog to choose who can reply to this thread`,
|
msg`Opens a dialog to choose who can reply to this thread`,
|
||||||
)}
|
)}
|
||||||
style={
|
style={[
|
||||||
!isNative ? {paddingVertical: 6, paddingHorizontal: 8} : undefined
|
native({
|
||||||
}>
|
paddingHorizontal: 8,
|
||||||
|
paddingVertical: 6,
|
||||||
|
}),
|
||||||
|
]}>
|
||||||
<ButtonIcon icon={anyoneCanInteract ? Earth : Group} />
|
<ButtonIcon icon={anyoneCanInteract ? Earth : Group} />
|
||||||
<ButtonText numberOfLines={1}>{label}</ButtonText>
|
<ButtonText numberOfLines={1}>{label}</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
</Animated.View>
|
|
||||||
<PostInteractionSettingsControlledDialog
|
<PostInteractionSettingsControlledDialog
|
||||||
control={control}
|
control={control}
|
||||||
onSave={() => {
|
onSave={() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user