Page MenuHomePhabricator

D13200.id43780.diff
No OneTemporary

D13200.id43780.diff

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 { thickThreadTypes } 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<void>,
};
class ProfileScreen extends React.PureComponent<Props> {
@@ -269,6 +279,18 @@
);
}
+ let dmActions;
+ if (staffCanSee) {
+ dmActions = (
+ <>
+ <ProfileRow
+ content="Create a new local DM thread"
+ onPress={this.onPressCreateThread}
+ />
+ </>
+ );
+ }
+
return (
<View style={this.props.styles.container}>
<ScrollView
@@ -321,6 +343,7 @@
<ProfileRow content="Build info" onPress={this.onPressBuildInfo} />
{developerTools}
{experimentalLogoutActions}
+ {dmActions}
</View>
<View style={this.props.styles.unpaddedSection}>
<ProfileRow
@@ -519,6 +542,10 @@
onPressKeyserverSelection = () => {
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: thickThreadTypes.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 (
<ProfileScreen
{...props}
@@ -557,6 +611,7 @@
staffCanSee={staffCanSee}
stringForUser={stringForUser}
isAccountWithPassword={isAccountWithPassword}
+ onCreateDMThread={onCreateDMThread}
/>
);
});
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 { thickThreadTypes } 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: thickThreadTypes.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(<AppearanceChangeModal />),
[pushModal],
@@ -260,6 +292,24 @@
</div>
);
}
+ let dms;
+ if (staffCanSee) {
+ dms = (
+ <div className={css.preferencesContainer}>
+ <h4 className={css.preferencesHeader}>DMs menu</h4>
+ <div className={css.content}>
+ <ul>
+ <li>
+ <span>Create a new local DM thread</span>
+ <Button variant="text" onClick={onCreateDMThread}>
+ <p className={css.buttonText}>Create</p>
+ </Button>
+ </li>
+ </ul>
+ </div>
+ </div>
+ );
+ }
return (
<div className={css.container}>
@@ -297,6 +347,7 @@
{tunnelbroker}
{backup}
{deviceData}
+ {dms}
</div>
</div>
);

File Metadata

Mime Type
text/plain
Expires
Sun, Sep 22, 10:35 AM (21 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2167978
Default Alt Text
D13200.id43780.diff (6 KB)

Event Timeline