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 @@ -1,7 +1,9 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { View, Text, Platform, ScrollView } from 'react-native'; +import uuid from 'uuid'; import { logOutActionTypes, @@ -13,7 +15,14 @@ import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; import { getOwnPrimaryDeviceID } from 'lib/selectors/user-selectors.js'; import { accountHasPassword } from 'lib/shared/account-utils.js'; +import { + type OutboundDMOperationSpecification, + dmOperationSpecificationTypes, +} from 'lib/shared/dm-ops/dm-op-utils.js'; +import { useProcessAndSendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js'; import type { LogOutResult } from 'lib/types/account-types.js'; +import type { DMCreateThreadOperation } from 'lib/types/dm-ops'; +import { nonSidebarThickThreadTypes } from 'lib/types/thread-types-enum.js'; import { type CurrentUserInfo } from 'lib/types/user-types.js'; import { getContentSigningKey } from 'lib/utils/crypto-utils.js'; import { @@ -168,6 +177,7 @@ +staffCanSee: boolean, +stringForUser: ?string, +isAccountWithPassword: boolean, + +onCreateDMThread: () => Promise, }; class ProfileScreen extends React.PureComponent { @@ -269,6 +279,18 @@ ); } + let dmActions; + if (staffCanSee) { + dmActions = ( + <> + + + ); + } + return ( {developerTools} {experimentalLogoutActions} + {dmActions} { this.props.navigation.navigate({ name: KeyserverSelectionListRouteName }); }; + + onPressCreateThread = () => { + void this.props.onCreateDMThread(); + }; } const logOutLoadingStatusSelector = @@ -542,6 +569,33 @@ accountHasPassword(state.currentUserInfo), ); + const userID = useSelector( + state => state.currentUserInfo && state.currentUserInfo.id, + ); + const processAndSendDMOperation = useProcessAndSendDMOperation(); + + const onCreateDMThread = React.useCallback(async () => { + invariant(userID, 'userID should be set'); + const op: DMCreateThreadOperation = { + type: 'create_thread', + threadID: uuid.v4(), + creatorID: userID, + time: Date.now(), + threadType: nonSidebarThickThreadTypes.LOCAL, + memberIDs: [], + roleID: uuid.v4(), + newMessageID: uuid.v4(), + }; + const specification: OutboundDMOperationSpecification = { + type: dmOperationSpecificationTypes.OUTBOUND, + op, + recipients: { + type: 'self_devices', + }, + }; + await processAndSendDMOperation(specification); + }, [processAndSendDMOperation, userID]); + return ( ); }); diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js --- a/web/settings/account-settings.react.js +++ b/web/settings/account-settings.react.js @@ -1,6 +1,8 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; +import uuid from 'uuid'; import { useLogOut, @@ -11,8 +13,15 @@ import SWMansionIcon from 'lib/components/swmansion-icon.react.js'; import { useStringForUser } from 'lib/hooks/ens-cache.js'; import { accountHasPassword } from 'lib/shared/account-utils.js'; +import { + dmOperationSpecificationTypes, + type OutboundDMOperationSpecification, +} from 'lib/shared/dm-ops/dm-op-utils.js'; +import { useProcessAndSendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js'; import { IdentityClientContext } from 'lib/shared/identity-client-context.js'; import { useTunnelbroker } from 'lib/tunnelbroker/tunnelbroker-context.js'; +import type { DMCreateThreadOperation } from 'lib/types/dm-ops.js'; +import { nonSidebarThickThreadTypes } from 'lib/types/thread-types-enum.js'; import { createOlmSessionsWithOwnDevices, getContentSigningKey, @@ -131,6 +140,29 @@ [popModal, pushModal], ); + const processAndSendDMOperation = useProcessAndSendDMOperation(); + const onCreateDMThread = React.useCallback(async () => { + invariant(userID, 'userID should be set'); + const op: DMCreateThreadOperation = { + type: 'create_thread', + threadID: uuid.v4(), + creatorID: userID, + time: Date.now(), + threadType: nonSidebarThickThreadTypes.LOCAL, + memberIDs: [], + roleID: uuid.v4(), + newMessageID: uuid.v4(), + }; + const specification: OutboundDMOperationSpecification = { + type: dmOperationSpecificationTypes.OUTBOUND, + op, + recipients: { + type: 'self_devices', + }, + }; + await processAndSendDMOperation(specification); + }, [processAndSendDMOperation, userID]); + const showAppearanceModal = React.useCallback( () => pushModal(), [pushModal], @@ -260,6 +292,24 @@ ); } + let dms; + if (staffCanSee) { + dms = ( +
+

DMs menu

+
+
    +
  • + Create local DM thread + +
  • +
+
+
+ ); + } return (
@@ -297,6 +347,7 @@ {tunnelbroker} {backup} {deviceData} + {dms}
);