diff --git a/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js b/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js new file mode 100644 index 000000000..6af7b1f01 --- /dev/null +++ b/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js @@ -0,0 +1,109 @@ +// @flow + +import * as React from 'react'; +import { Text, ActivityIndicator } from 'react-native'; + +import { + deleteFarcasterChannelTagActionTypes, + useDeleteFarcasterChannelTag, +} from 'lib/actions/community-actions.js'; +import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; +import type { SetState } from 'lib/types/hook-types.js'; +import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js'; + +import Button from '../../components/button.react.js'; +import { useSelector } from '../../redux/redux-utils.js'; +import { useStyles, useColors } from '../../themes/colors.js'; + +const deleteFarcasterChannelTagStatusSelector = createLoadingStatusSelector( + deleteFarcasterChannelTagActionTypes, +); + +type Props = { + +communityID: string, + +channelID: string, + +setError: SetState, +}; + +function RemoveTagButton(props: Props): React.Node { + const { communityID, channelID, setError } = props; + + const styles = useStyles(unboundStyles); + const colors = useColors(); + + const dispatchActionPromise = useDispatchActionPromise(); + + const deleteFarcasterChannelTag = useDeleteFarcasterChannelTag(); + + const createDeleteActionPromise = React.useCallback(async () => { + try { + return await deleteFarcasterChannelTag({ + commCommunityID: communityID, + farcasterChannelID: channelID, + }); + } catch (e) { + setError(e.message); + throw e; + } + }, [channelID, communityID, deleteFarcasterChannelTag, setError]); + + const onPressRemoveTag = React.useCallback(() => { + void dispatchActionPromise( + deleteFarcasterChannelTagActionTypes, + createDeleteActionPromise(), + ); + }, [createDeleteActionPromise, dispatchActionPromise]); + + const deleteFarcasterChannelTagStatus = useSelector( + deleteFarcasterChannelTagStatusSelector, + ); + + const isLoadingDeleteFarcasterChannelTag = + deleteFarcasterChannelTagStatus === 'loading'; + + const buttonContent = React.useMemo(() => { + if (isLoadingDeleteFarcasterChannelTag) { + return ( + + ); + } + + return Remove tag; + }, [ + colors.panelForegroundLabel, + isLoadingDeleteFarcasterChannelTag, + styles.buttonText, + ]); + + return ( + + ); +} + +const unboundStyles = { + button: { + borderRadius: 8, + paddingVertical: 12, + paddingHorizontal: 24, + borderWidth: 1, + borderColor: 'vibrantRedButton', + }, + buttonText: { + fontSize: 16, + fontWeight: '500', + lineHeight: 24, + color: 'vibrantRedButton', + textAlign: 'center', + }, + buttonContainer: { + height: 24, + }, +}; + +export default RemoveTagButton; diff --git a/native/community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js b/native/community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js index 1f3a3e54d..55563b97d 100644 --- a/native/community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js +++ b/native/community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js @@ -1,149 +1,164 @@ // @flow import * as React from 'react'; import { View, Text } from 'react-native'; import type { CommunityInfo } from 'lib/types/community-types.js'; +import RemoveTagButton from './remove-tag-button.react.js'; import TagChannelButton from './tag-channel-button.react.js'; import type { TagFarcasterChannelNavigationProp } from './tag-farcaster-channel-navigator.react.js'; import { tagFarcasterChannelErrorMessages } from './tag-farcaster-channel-utils.js'; import { type NavigationRoute } from '../../navigation/route-names.js'; import { useSelector } from '../../redux/redux-utils.js'; import { useStyles } from '../../themes/colors.js'; export type TagFarcasterChannelParams = { +communityID: string, }; type Props = { +navigation: TagFarcasterChannelNavigationProp<'TagFarcasterChannel'>, +route: NavigationRoute<'TagFarcasterChannel'>, }; function TagFarcasterChannel(props: Props): React.Node { const { route } = props; const { communityID } = route.params; const communityInfo: ?CommunityInfo = useSelector( state => state.communityStore.communityInfos[communityID], ); const styles = useStyles(unboundStyles); const [error, setError] = React.useState(null); const errorMessage = React.useMemo(() => { if (!error) { return null; } return ( {tagFarcasterChannelErrorMessages[error] ?? 'Unknown error.'} ); }, [error, styles.error]); const channelNameTextContent = React.useMemo(() => { if (!communityInfo?.farcasterChannelID) { return ( No Farcaster channel tagged ); } return ( {`/${communityInfo.farcasterChannelID}`} ); }, [ communityInfo?.farcasterChannelID, styles.channelNameText, styles.noChannelText, ]); + const sectionButton = React.useMemo( + () => + communityInfo?.farcasterChannelID ? ( + + ) : ( + + ), + [communityID, communityInfo?.farcasterChannelID], + ); + const tagFarcasterChannel = React.useMemo( () => ( Tag a Farcaster channel so followers can find your Comm community! FARCASTER CHANNEL Selected channel: {channelNameTextContent} - + {sectionButton} {errorMessage} ), [ styles.panelSectionContainer, styles.sectionText, styles.sectionHeaderText, styles.channelNameContainer, styles.errorContainer, channelNameTextContent, - communityID, + sectionButton, errorMessage, ], ); return tagFarcasterChannel; } const unboundStyles = { panelSectionContainer: { backgroundColor: 'panelForeground', padding: 16, borderBottomColor: 'panelSeparator', borderBottomWidth: 1, borderTopColor: 'panelSeparator', borderTopWidth: 1, }, sectionText: { color: 'panelForegroundLabel', fontSize: 14, }, sectionHeaderText: { fontSize: 14, fontWeight: '400', lineHeight: 20, color: 'panelForegroundLabel', paddingHorizontal: 16, paddingBottom: 4, marginTop: 24, }, channelNameContainer: { marginTop: 8, marginBottom: 24, height: 20, }, channelNameText: { fontSize: 16, fontWeight: '600', color: 'panelForegroundLabel', }, noChannelText: { fontSize: 16, color: 'panelForegroundLabel', }, errorContainer: { height: 18, }, error: { fontSize: 12, fontWeight: '400', lineHeight: 18, textAlign: 'center', color: 'redText', }, }; export default TagFarcasterChannel;