From fc8f9b63dea967e55667d2a3bd2211bc07ffac96 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Wed, 11 Feb 2026 14:13:58 +0100 Subject: [PATCH 1/3] Allow copying link to CAPTCHA on registration page --- .../InstallScreenCaptchaStep.dom.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ts/components/installScreen/InstallScreenCaptchaStep.dom.tsx b/ts/components/installScreen/InstallScreenCaptchaStep.dom.tsx index 4b9fed19b..81e670f40 100644 --- a/ts/components/installScreen/InstallScreenCaptchaStep.dom.tsx +++ b/ts/components/installScreen/InstallScreenCaptchaStep.dom.tsx @@ -2,6 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import React, { type ReactElement, useState, useCallback } from 'react'; +import copyText from 'copy-text-to-clipboard'; import { Button, ButtonVariant } from '../Button.dom.js'; import { TitlebarDragArea } from '../TitlebarDragArea.dom.js'; @@ -30,6 +31,7 @@ export function InstallScreenCaptchaStep({ }: Props): ReactElement { const [isWaitingForCaptcha, setIsWaitingForCaptcha] = useState(false); const [captchaError, setCaptchaError] = useState(null); + const [isCopied, setIsCopied] = useState(false); const handleOpenCaptcha = useCallback(async () => { setIsWaitingForCaptcha(true); @@ -49,6 +51,12 @@ export function InstallScreenCaptchaStep({ } }, [requestCaptcha, onCaptchaComplete]); + const handleCopyUrl = useCallback(() => { + copyText(CAPTCHA_URL); + setIsCopied(true); + setTimeout(() => setIsCopied(false), 2000); + }, []); + return (
@@ -74,7 +82,7 @@ export function InstallScreenCaptchaStep({
- Complete the captcha in your browser, then click "Open + Complete the CAPTCHA in your browser, then click "Open Signal"
@@ -86,7 +94,14 @@ export function InstallScreenCaptchaStep({ variant={ButtonVariant.Primary} disabled={isSubmitting || isWaitingForCaptcha} > - {isWaitingForCaptcha ? 'Waiting for captcha...' : 'Open Captcha'} + {isWaitingForCaptcha ? 'Waiting for captcha...' : 'Open CAPTCHA'} + + diff --git a/ts/components/installScreen/InstallScreenProfileNameStep.dom.tsx b/ts/components/installScreen/InstallScreenProfileNameStep.dom.tsx index 1e6f6c15c..68dcd98fa 100644 --- a/ts/components/installScreen/InstallScreenProfileNameStep.dom.tsx +++ b/ts/components/installScreen/InstallScreenProfileNameStep.dom.tsx @@ -42,11 +42,12 @@ export function InstallScreenProfileNameStep({

- Set up your profile + Set up your Observer Vault profile

- Enter your name to complete registration. This is how you'll - appear to others. + Enter a name for your Observer Vault's Signal account. If + you're not sure what to use, just set the first name to + "Observer Vault".

- We sent a code to {phoneNumber} + Signal sent a code to {phoneNumber}

{error && ( From ee14982947333d2f500da9a77cb9d242e4653a74 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Wed, 11 Feb 2026 14:46:20 +0100 Subject: [PATCH 3/3] Fix startup error when disabling stories in settings --- ts/util/stories.preload.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ts/util/stories.preload.ts b/ts/util/stories.preload.ts index e698145f7..36ed2af89 100644 --- a/ts/util/stories.preload.ts +++ b/ts/util/stories.preload.ts @@ -8,8 +8,18 @@ export const getStoriesDisabled = (): boolean => export const setStoriesDisabled = async (value: boolean): Promise => { await itemStorage.put('hasStoriesDisabled', value); - const account = window.ConversationController.getOurConversationOrThrow(); - account.captureChange('hasStoriesDisabled'); + + // Only update the conversation if it exists and the controller is ready + try { + const account = window.ConversationController.getOurConversation(); + if (account) { + account.captureChange('hasStoriesDisabled'); + } + } catch (error) { + // ConversationController may not be ready yet (e.g., during app startup) + // The setting is still saved to storage, so it will be applied when ready + } + onHasStoriesDisabledChange(value); };