diff --git a/lib/shared/community-utils.js b/lib/shared/community-utils.js
index 1cbc95d3f..f6f4f79ca 100644
--- a/lib/shared/community-utils.js
+++ b/lib/shared/community-utils.js
@@ -1,134 +1,142 @@
// @flow
import * as React from 'react';
import {
createOrUpdateFarcasterChannelTagActionTypes,
useCreateOrUpdateFarcasterChannelTag,
deleteFarcasterChannelTagActionTypes,
useDeleteFarcasterChannelTag,
} from '../actions/community-actions.js';
import { createLoadingStatusSelector } from '../selectors/loading-selectors.js';
import type { SetState } from '../types/hook-types.js';
import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
import { useSelector } from '../utils/redux-utils.js';
+const tagFarcasterChannelCopy = {
+ DESCRIPTION:
+ 'Tag a Farcaster channel so followers can find your Comm community!',
+ CHANNEL_NAME_HEADER: 'Selected channel:',
+ NO_CHANNEL_TAGGED: 'No Farcaster channel tagged',
+};
+
function farcasterChannelTagBlobHash(farcasterChannelID: string): string {
return `farcaster_channel_tag_${farcasterChannelID}`;
}
const createOrUpdateFarcasterChannelTagStatusSelector =
createLoadingStatusSelector(createOrUpdateFarcasterChannelTagActionTypes);
function useCreateFarcasterChannelTag(
commCommunityID: string,
setError: SetState,
onSuccessCallback?: () => mixed,
): {
+createTag: (farcasterChannelID: string) => mixed,
+isLoading: boolean,
} {
const dispatchActionPromise = useDispatchActionPromise();
const createOrUpdateFarcasterChannelTag =
useCreateOrUpdateFarcasterChannelTag();
const createCreateOrUpdateActionPromise = React.useCallback(
async (farcasterChannelID: string) => {
try {
const res = await createOrUpdateFarcasterChannelTag({
commCommunityID,
farcasterChannelID,
});
onSuccessCallback?.();
return res;
} catch (e) {
setError(e.message);
throw e;
}
},
[
commCommunityID,
createOrUpdateFarcasterChannelTag,
onSuccessCallback,
setError,
],
);
const createTag = React.useCallback(
(farcasterChannelID: string) => {
void dispatchActionPromise(
createOrUpdateFarcasterChannelTagActionTypes,
createCreateOrUpdateActionPromise(farcasterChannelID),
);
},
[createCreateOrUpdateActionPromise, dispatchActionPromise],
);
const createOrUpdateFarcasterChannelTagStatus = useSelector(
createOrUpdateFarcasterChannelTagStatusSelector,
);
const isLoading = createOrUpdateFarcasterChannelTagStatus === 'loading';
return {
createTag,
isLoading,
};
}
const deleteFarcasterChannelTagStatusSelector = createLoadingStatusSelector(
deleteFarcasterChannelTagActionTypes,
);
function useRemoveFarcasterChannelTag(
commCommunityID: string,
farcasterChannelID: string,
setError: SetState,
): {
+removeTag: () => mixed,
+isLoading: boolean,
} {
const dispatchActionPromise = useDispatchActionPromise();
const deleteFarcasterChannelTag = useDeleteFarcasterChannelTag();
const createDeleteActionPromise = React.useCallback(async () => {
try {
return await deleteFarcasterChannelTag({
commCommunityID,
farcasterChannelID,
});
} catch (e) {
setError(e.message);
throw e;
}
}, [
commCommunityID,
deleteFarcasterChannelTag,
farcasterChannelID,
setError,
]);
const removeTag = React.useCallback(() => {
void dispatchActionPromise(
deleteFarcasterChannelTagActionTypes,
createDeleteActionPromise(),
);
}, [createDeleteActionPromise, dispatchActionPromise]);
const deleteFarcasterChannelTagStatus = useSelector(
deleteFarcasterChannelTagStatusSelector,
);
const isLoading = deleteFarcasterChannelTagStatus === 'loading';
return {
removeTag,
isLoading,
};
}
export {
+ tagFarcasterChannelCopy,
farcasterChannelTagBlobHash,
useCreateFarcasterChannelTag,
useRemoveFarcasterChannelTag,
};
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 55563b97d..68257277e 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,164 +1,169 @@
// @flow
import * as React from 'react';
import { View, Text } from 'react-native';
+import { tagFarcasterChannelCopy } from 'lib/shared/community-utils.js';
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 (