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 @@ -109,6 +109,7 @@ export const ThreadSettingsMemberTooltipModalRouteName = 'ThreadSettingsMemberTooltipModal'; export const ThreadSettingsRouteName = 'ThreadSettings'; +export const TunnelbrokerMenuRouteName = 'TunnelbrokerMenu'; export const UserAvatarCameraModalRouteName = 'UserAvatarCameraModal'; export const TogglePinModalRouteName = 'TogglePinModal'; export const VideoPlaybackModalRouteName = 'VideoPlaybackModal'; @@ -162,6 +163,7 @@ +RolesNavigator: void, +QRCodeSignInNavigator: void, +UserProfileBottomSheetNavigator: void, + +TunnelbrokerMenu: void, }; export type MessageTooltipRouteNames = @@ -234,6 +236,7 @@ +LinkedDevices: void, +SecondaryDeviceQRCodeScanner: void, +BackupMenu: void, + +TunnelbrokerMenu: void, +KeyserverSelectionList: void, +AddKeyserver: void, }; diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js --- a/native/profile/profile-screen.react.js +++ b/native/profile/profile-screen.react.js @@ -38,6 +38,7 @@ LinkedDevicesRouteName, BackupMenuRouteName, KeyserverSelectionListRouteName, + TunnelbrokerMenuRouteName, } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; import { type Colors, useColors, useStyles } from '../themes/colors.js'; @@ -88,7 +89,10 @@ } render() { - let developerTools, defaultNotifications, keyserverSelection; + let developerTools, + defaultNotifications, + keyserverSelection, + tunnelbrokerMenu; const { staffCanSee, isAccountWithPassword } = this.props; if (staffCanSee) { developerTools = ( @@ -108,6 +112,13 @@ onPress={this.onPressKeyserverSelection} /> ); + + tunnelbrokerMenu = ( + + ); } let backupMenu; @@ -187,6 +198,7 @@ {defaultNotifications} {backupMenu} + {tunnelbrokerMenu} {linkedDevices} @@ -324,6 +336,10 @@ this.navigateIfActive(BackupMenuRouteName); }; + onPressTunnelbrokerMenu = () => { + this.navigateIfActive(TunnelbrokerMenuRouteName); + }; + onPressKeyserverSelection = () => { this.navigateIfActive(KeyserverSelectionListRouteName); }; diff --git a/native/profile/profile.react.js b/native/profile/profile.react.js --- a/native/profile/profile.react.js +++ b/native/profile/profile.react.js @@ -27,6 +27,7 @@ import ProfileScreen from './profile-screen.react.js'; import RelationshipList from './relationship-list.react.js'; import SecondaryDeviceQRCodeScanner from './secondary-device-qr-code-scanner.react.js'; +import TunnelbrokerMenu from './tunnelbroker-menu.react.js'; import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js'; import CommunityDrawerButton from '../navigation/community-drawer-button.react.js'; import type { CommunityDrawerNavigationProp } from '../navigation/community-drawer-navigator.react.js'; @@ -50,6 +51,7 @@ AddKeyserverRouteName, type ScreenParamList, type ProfileParamList, + TunnelbrokerMenuRouteName, } from '../navigation/route-names.js'; import { useStyles, useColors } from '../themes/colors.js'; @@ -73,6 +75,7 @@ }; const addKeyserverOptions = { headerTitle: 'Add keyserver' }; const backupMenuOptions = { headerTitle: 'Backup menu' }; +const tunnelbrokerMenuOptions = { headerTitle: 'Tunnelbroker menu' }; const secondaryDeviceQRCodeScannerOptions = { headerTitle: '', headerBackTitleVisible: false, @@ -98,6 +101,7 @@ +navigation: CommunityDrawerNavigationProp<'TabNavigator'>, ... }; + function ProfileComponent(props: Props): React.Node { const styles = useStyles(unboundStyles); const colors = useColors(); @@ -177,6 +181,11 @@ component={BackupMenu} options={backupMenuOptions} /> + ([]); + const [recipient, setRecipient] = useState(''); + + const [message, setMessage] = useState(''); + + const listener = React.useCallback((msg: TunnelbrokerMessage) => { + setMessages(prev => [...prev, msg]); + }, []); + + React.useEffect(() => { + addListener(listener); + return () => removeListener(listener); + }, [addListener, listener, removeListener]); + + const onSubmit = React.useCallback(async () => { + try { + await sendMessage({ deviceID: recipient, payload: message }); + } catch (e) { + console.error(e.message); + } + }, [message, recipient, sendMessage]); + + return ( + + INFO + + + Connected + {connected.toString()} + + + + SEND MESSAGE + + + + Recipient + + + + Message + + + + + + MESSAGES + {messages.map(msg => ( + + {JSON.stringify(msg)} + + ))} + + ); +} + +const unboundStyles = { + scrollViewContentContainer: { + paddingTop: 24, + }, + scrollView: { + backgroundColor: 'panelBackground', + }, + section: { + backgroundColor: 'panelForeground', + borderBottomWidth: 1, + borderColor: 'panelForegroundBorder', + borderTopWidth: 1, + marginBottom: 24, + marginVertical: 2, + }, + header: { + color: 'panelBackgroundLabel', + fontSize: 12, + fontWeight: '400', + paddingBottom: 3, + paddingHorizontal: 24, + }, + submenuButton: { + flexDirection: 'row', + paddingHorizontal: 24, + paddingVertical: 10, + alignItems: 'center', + }, + submenuText: { + color: 'panelForegroundLabel', + flex: 1, + fontSize: 16, + }, + text: { + color: 'panelForegroundLabel', + fontSize: 16, + }, + row: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingHorizontal: 24, + paddingVertical: 14, + }, + textInput: { + color: 'modalBackgroundLabel', + flex: 1, + fontSize: 16, + margin: 0, + padding: 0, + borderBottomColor: 'transparent', + }, +}; + +export default TunnelbrokerMenu;