diff --git a/ts/background.ts b/ts/background.ts index 073b921dec..e4156aa130 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -135,6 +135,7 @@ import { ToastConversationUnarchived } from './components/ToastConversationUnarc import { showToast } from './util/showToast'; import { startInteractionMode } from './windows/startInteractionMode'; import { deliveryReceiptsJobQueue } from './jobs/deliveryReceiptsJobQueue'; +import { updateOurUsername } from './util/updateOurUsername'; const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000; @@ -2137,13 +2138,16 @@ export async function startApp(): Promise { try { // Note: we always have to register our capabilities all at once, so we do this // after connect on every startup - await server.registerCapabilities({ - announcementGroup: true, - 'gv2-3': true, - 'gv1-migration': true, - senderKey: true, - changeNumber: true, - }); + await Promise.all([ + server.registerCapabilities({ + announcementGroup: true, + 'gv2-3': true, + 'gv1-migration': true, + senderKey: true, + changeNumber: true, + }), + updateOurUsername(), + ]); } catch (error) { log.error( 'Error: Unable to register our capabilities.', @@ -3458,7 +3462,7 @@ export async function startApp(): Promise { case FETCH_LATEST_ENUM.LOCAL_PROFILE: { const ourUuid = window.textsecure.storage.user.getUuid()?.toString(); const ourE164 = window.textsecure.storage.user.getNumber(); - await getProfile(ourUuid, ourE164); + await Promise.all([getProfile(ourUuid, ourE164), updateOurUsername()]); break; } case FETCH_LATEST_ENUM.STORAGE_MANIFEST: diff --git a/ts/components/Input.tsx b/ts/components/Input.tsx index 11a33835be..3786d32c23 100644 --- a/ts/components/Input.tsx +++ b/ts/components/Input.tsx @@ -18,15 +18,16 @@ import { refMerger } from '../util/refMerger'; import { byteLength } from '../Bytes'; export type PropsType = { - countLength?: (value: string) => number; countBytes?: (value: string) => number; + countLength?: (value: string) => number; disabled?: boolean; + disableSpellcheck?: boolean; expandable?: boolean; hasClearButton?: boolean; i18n: LocalizerType; icon?: ReactNode; - maxLengthCount?: number; maxByteCount?: number; + maxLengthCount?: number; moduleClassName?: string; onChange: (value: string) => unknown; onEnter?: () => unknown; @@ -58,15 +59,16 @@ export const Input = forwardRef< >( ( { - countLength = grapheme.count, countBytes = byteLength, + countLength = grapheme.count, disabled, + disableSpellcheck, expandable, hasClearButton, i18n, icon, - maxLengthCount = 0, maxByteCount = 0, + maxLengthCount = 0, moduleClassName, onChange, onEnter, @@ -201,6 +203,7 @@ export const Input = forwardRef< isLarge && getClassName('__input--large') ), disabled: Boolean(disabled), + spellcheck: disableSpellcheck ? 'false' : 'true', onChange: handleChange, onKeyDown: handleKeyDown, onPaste: handlePaste, diff --git a/ts/components/ProfileEditor.tsx b/ts/components/ProfileEditor.tsx index 28b4b6c34e..0e3c4302c2 100644 --- a/ts/components/ProfileEditor.tsx +++ b/ts/components/ProfileEditor.tsx @@ -617,6 +617,7 @@ export const ProfileEditor = ({ { setUsernameError(undefined); setNewUsername(changedUsername); diff --git a/ts/services/writeUsername.ts b/ts/services/writeUsername.ts index 7b2a430069..1de5b48c46 100644 --- a/ts/services/writeUsername.ts +++ b/ts/services/writeUsername.ts @@ -3,6 +3,7 @@ import dataInterface from '../sql/Client'; import { handleMessageSend } from '../util/handleMessageSend'; +import { updateOurUsername } from '../util/updateOurUsername'; export async function writeUsername({ username, @@ -12,7 +13,7 @@ export async function writeUsername({ previousUsername: string | undefined; }): Promise { const me = window.ConversationController.getOurConversationOrThrow(); - await me.getProfiles(); + await updateOurUsername(); if (me.get('username') !== previousUsername) { throw new Error('Username has changed on another device'); diff --git a/ts/state/ducks/conversations.ts b/ts/state/ducks/conversations.ts index 7aa73fe025..d5b5c4cf0d 100644 --- a/ts/state/ducks/conversations.ts +++ b/ts/state/ducks/conversations.ts @@ -1814,10 +1814,6 @@ async function checkForUsername( username ); - if (!profile.username || profile.username !== username) { - log.error("checkForUsername: Returned username didn't match searched"); - return; - } if (!profile.uuid) { log.error("checkForUsername: Returned profile didn't include a uuid"); return; @@ -1825,7 +1821,7 @@ async function checkForUsername( return { uuid: UUID.cast(profile.uuid), - username: profile.username, + username, }; } catch (error: unknown) { if (!isRecord(error)) { diff --git a/ts/textsecure/SendMessage.ts b/ts/textsecure/SendMessage.ts index 94419d02b4..952f6dbc94 100644 --- a/ts/textsecure/SendMessage.ts +++ b/ts/textsecure/SendMessage.ts @@ -2236,4 +2236,7 @@ export default class MessageSender { async deleteUsername(): Promise> { return this.server.deleteUsername(); } + async whoami(): Promise> { + return this.server.whoami(); + } } diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index 1c63737556..38b3acade8 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -715,7 +715,6 @@ export type ProfileType = Readonly<{ avatar?: string; unidentifiedAccess?: string; unrestrictedUnidentifiedAccess?: string; - username?: string; uuid?: string; credential?: string; capabilities?: CapabilitiesType; @@ -751,6 +750,7 @@ export type WhoamiResultType = Readonly<{ uuid?: UUIDStringType; pni?: UUIDStringType; number?: string; + username?: string; }>; export type ConfirmCodeResultType = Readonly<{ diff --git a/ts/util/getProfile.ts b/ts/util/getProfile.ts index c2f3401ffa..de08430dd4 100644 --- a/ts/util/getProfile.ts +++ b/ts/util/getProfile.ts @@ -174,13 +174,6 @@ export async function getProfile( }); } - const { username } = profile; - if (username) { - c.set({ username }); - } else { - c.unset('username'); - } - if (profile.about) { const key = c.get('profileKey'); if (key) { diff --git a/ts/util/updateOurUsername.ts b/ts/util/updateOurUsername.ts new file mode 100644 index 0000000000..845adba104 --- /dev/null +++ b/ts/util/updateOurUsername.ts @@ -0,0 +1,16 @@ +// Copyright 2021 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +export async function updateOurUsername(): Promise { + if (!window.textsecure.messaging) { + throw new Error( + 'updateOurUsername: window.textsecure.messaging not available' + ); + } + + const me = window.ConversationController.getOurConversationOrThrow(); + const { username } = await window.textsecure.messaging.whoami(); + + me.set({ username }); + window.Signal.Data.updateConversation(me.attributes); +}