diff --git a/native/community-settings/tag-farcaster-channel/tag-farcaster-channel-navigator.react.js b/native/community-settings/tag-farcaster-channel/tag-farcaster-channel-navigator.react.js new file mode 100644 --- /dev/null +++ b/native/community-settings/tag-farcaster-channel/tag-farcaster-channel-navigator.react.js @@ -0,0 +1,65 @@ +// @flow + +import type { + StackNavigationHelpers, + StackNavigationProp, +} from '@react-navigation/core'; +import { createStackNavigator } from '@react-navigation/stack'; +import * as React from 'react'; +import { SafeAreaView } from 'react-native-safe-area-context'; + +import TagFarcasterChannel from './tag-farcaster-channel.react.js'; +import type { RootNavigationProp } from '../../navigation/root-navigator.react'; +import { + TagFarcasterChannelRouteName, + type TagFarcasterChannelParamList, + type ScreenParamList, +} from '../../navigation/route-names.js'; +import { useStyles } from '../../themes/colors.js'; + +const safeAreaEdges = ['bottom']; + +export type TagFarcasterChannelNavigationProp< + RouteName: $Keys = $Keys, +> = StackNavigationProp; + +const TagFarcasterChannelStack = createStackNavigator< + ScreenParamList, + TagFarcasterChannelParamList, + StackNavigationHelpers, +>(); + +type Props = { + +navigation: RootNavigationProp<'TagFarcasterChannelNavigator'>, + ... +}; + +// eslint-disable-next-line no-unused-vars +function TagFarcasterChannelNavigator(props: Props): React.Node { + const styles = useStyles(unboundStyles); + + const tagFarcasterChannelNavigator = React.useMemo( + () => ( + + + + + + ), + [styles.container], + ); + + return tagFarcasterChannelNavigator; +} + +const unboundStyles = { + container: { + flex: 1, + backgroundColor: 'modalBackground', + }, +}; + +export default TagFarcasterChannelNavigator; 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 new file mode 100644 --- /dev/null +++ b/native/community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js @@ -0,0 +1,28 @@ +// @flow + +import * as React from 'react'; +import { View, Text } from 'react-native'; + +import type { TagFarcasterChannelNavigationProp } from './tag-farcaster-channel-navigator.react'; +import type { NavigationRoute } from '../../navigation/route-names'; + +type Props = { + +navigation: TagFarcasterChannelNavigationProp<'TagFarcasterChannel'>, + +route: NavigationRoute<'TagFarcasterChannel'>, +}; + +// eslint-disable-next-line no-unused-vars +function TagFarcasterChannel(props: Props): React.Node { + const tagFarcasterChannel = React.useMemo( + () => ( + + TagFarcasterChannel + + ), + [], + ); + + return tagFarcasterChannel; +} + +export default TagFarcasterChannel; diff --git a/native/components/community-actions-button.react.js b/native/components/community-actions-button.react.js --- a/native/components/community-actions-button.react.js +++ b/native/components/community-actions-button.react.js @@ -10,6 +10,9 @@ import { threadHasPermission } from 'lib/shared/thread-utils.js'; import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js'; import { threadPermissions } from 'lib/types/thread-permission-types.js'; +import { threadTypes } from 'lib/types/thread-types-enum.js'; +import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js'; +import { usingCommServicesAccessToken } from 'lib/utils/services-utils.js'; import SWMansionIcon from './swmansion-icon.react.js'; import { @@ -18,6 +21,8 @@ ManagePublicLinkRouteName, RolesNavigatorRouteName, ViewInviteLinksRouteName, + TagFarcasterChannelNavigatorRouteName, + TagFarcasterChannelRouteName, } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; import { useStyles } from '../themes/colors.js'; @@ -31,6 +36,9 @@ const inviteLink = useSelector(primaryInviteLinksSelector)[community.id]; const { navigate } = useNavigation(); + + const fid = useCurrentUserFID(); + const navigateToInviteLinksView = React.useCallback(() => { if (!inviteLink || !community) { return; @@ -42,6 +50,7 @@ }, }); }, [community, inviteLink, navigate]); + const navigateToManagePublicLinkView = React.useCallback(() => { navigate<'InviteLinkNavigator'>(InviteLinkNavigatorRouteName, { screen: ManagePublicLinkRouteName, @@ -50,6 +59,7 @@ }, }); }, [community, navigate]); + const navigateToCommunityRolesScreen = React.useCallback(() => { navigate<'RolesNavigator'>(RolesNavigatorRouteName, { screen: CommunityRolesScreenRouteName, @@ -59,6 +69,15 @@ }); }, [community, navigate]); + const navigateToTagFarcasterChannel = React.useCallback(() => { + navigate<'TagFarcasterChannelNavigator'>( + TagFarcasterChannelNavigatorRouteName, + { + screen: TagFarcasterChannelRouteName, + }, + ); + }, [navigate]); + const insets = useSafeAreaInsets(); const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme); const styles = useStyles(unboundStyles); @@ -99,6 +118,18 @@ }); } + const canTagFarcasterChannel = + fid && + community.type !== threadTypes.GENESIS && + (usingCommServicesAccessToken || __DEV__); + + if (canTagFarcasterChannel) { + result.push({ + label: 'Tag Farcaster channel', + action: navigateToTagFarcasterChannel, + }); + } + if (result.length > 0) { return result; } @@ -106,9 +137,11 @@ }, [ community, inviteLink, - navigateToInviteLinksView, + fid, navigateToManagePublicLinkView, + navigateToInviteLinksView, navigateToCommunityRolesScreen, + navigateToTagFarcasterChannel, ]); const openActionSheet = React.useCallback(() => { diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js --- a/native/navigation/root-navigator.react.js +++ b/native/navigation/root-navigator.react.js @@ -53,6 +53,7 @@ UserProfileBottomSheetNavigatorRouteName, KeyserverSelectionBottomSheetRouteName, ConnectFarcasterBottomSheetRouteName, + TagFarcasterChannelNavigatorRouteName, } from './route-names.js'; import LoggedOutModal from '../account/logged-out-modal.react.js'; import RegistrationNavigator from '../account/registration/registration-navigator.react.js'; @@ -66,6 +67,7 @@ import SidebarListModal from '../chat/sidebar-list-modal.react.js'; import SubchannelsListModal from '../chat/subchannels-list-modal.react.js'; import CommunityCreationNavigator from '../community-creation/community-creation-navigator.react.js'; +import TagFarcasterChannelNavigator from '../community-settings/tag-farcaster-channel/tag-farcaster-channel-navigator.react.js'; import ConnectFarcasterBottomSheet from '../components/connect-farcaster-bottom-sheet.react.js'; import InviteLinksNavigator from '../invite-links/invite-links-navigator.react.js'; import CustomServerModal from '../profile/custom-server-modal.react.js'; @@ -291,6 +293,10 @@ component={ConnectFarcasterBottomSheet} options={modalOverlayScreenOptions} /> + ); } diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js --- a/native/navigation/route-names.js +++ b/native/navigation/route-names.js @@ -151,6 +151,9 @@ export const FarcasterAccountSettingsRouteName = 'FarcasterAccountSettings'; export const ConnectFarcasterBottomSheetRouteName = 'ConnectFarcasterBottomSheet'; +export const TagFarcasterChannelNavigatorRouteName = + 'TagFarcasterChannelNavigator'; +export const TagFarcasterChannelRouteName = 'TagFarcasterChannel'; export type RootParamList = { +LoggedOutModal: void, @@ -175,6 +178,7 @@ +TunnelbrokerMenu: void, +KeyserverSelectionBottomSheet: KeyserverSelectionBottomSheetParams, +ConnectFarcasterBottomSheet: void, + +TagFarcasterChannelNavigator: void, }; export type MessageTooltipRouteNames = @@ -285,6 +289,10 @@ +CreateRolesScreen: CreateRolesScreenParams, }; +export type TagFarcasterChannelParamList = { + +TagFarcasterChannel: void, +}; + export type QRCodeSignInParamList = { +QRCodeScreen: void, }; @@ -309,6 +317,7 @@ ...RolesParamList, ...QRCodeSignInParamList, ...UserProfileBottomSheetParamList, + ...TagFarcasterChannelParamList, }; export type NavigationRoute> =