From 1d8685a4ef7898a02b41d1778d1e9b8cdd9cf7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Thu, 6 Nov 2025 11:21:26 +0100 Subject: [PATCH 01/20] stylesheets: Tweak CSS for mobile --- stylesheets/components/Droidian.scss | 131 +++++++++++++++++++++++++ stylesheets/components/NavSidebar.scss | 31 +----- stylesheets/manifest.scss | 2 + 3 files changed, 136 insertions(+), 28 deletions(-) create mode 100644 stylesheets/components/Droidian.scss diff --git a/stylesheets/components/Droidian.scss b/stylesheets/components/Droidian.scss new file mode 100644 index 000000000..b86e99aea --- /dev/null +++ b/stylesheets/components/Droidian.scss @@ -0,0 +1,131 @@ +.Preferences > .NavSidebar { + &:has(.NavSidebar__Header) { + max-width: 70px !important; + } +} + +.module-ConversationHeader__header { + justify-content: center; +} + +.module-ConversationHeader__button.module-ConversationHeader__button--video { + display: none !important; +} +.module-conversation-list__item--contact-or-conversation__avatar-container { + margin-left: 4px !important; + .module-conversation-list__item--contact-or-conversation__unread-indicator { + margin-right: 4px !important; + } +} +::-webkit-scrollbar { + display: none !important; +} +.module-reaction-viewer { + width: 220px !important; + height: 220px !important; +} +.Preferences__page-selector { + min-width: 48px !important; + padding-top: 0px !important; +} +.Preferences__button { + font-size: 0px !important; + width: 48px !important; +} +.Preferences__profile-chip { + margin-inline-start: 8px !important; + padding-inline-start: 8px !important; +} +.Preferences { + width: 100% !important; +} +.Preferences__control { + flex-direction: column !important; +} +.ConversationDetails-panel-row__root { + flex-direction: column !important; + align-items: stretch !important; +} + +.module-message--incoming { + .module-message__buttons { + opacity: 1 !important; + } +} +.module-sticker-manager__preview-modal__modal.module-Modal { + width: initial !important; +} +.react-contextmenu-submenu { + >.react-contextmenu { + right: 10px !important; + } +} +.module-InstallScreenQrCodeNotScannedStep__contents { + flex-direction: column !important; + top: 44px !important; +} +.module-InstallScreenQrCodeNotScannedStep__qr-code { + margin-inline: 50% !important; +} + +.Lightbox__main-container { + min-height: 100% !important; +} +.Lightbox__zoomable-container { + margin-inline: 0px !important; +} + +.CompositionArea__button-cell:first-child { + margin-inline-start: 5px !important; +} + +.CompositionArea__button-cell { + margin-inline: 1px !important; +} + +.CompositionArea__toggle-large { + display: none; +} + +.NavTabs__Container { + flex-direction: column-reverse !important; +} + +.NavTabs { + height: initial !important; + width: 100% !important; + flex-direction: row !important; +} + +.NavTabs__Item.NavTabs__Toggle { + display: none !important; +} + +.NavTabs__TabList { + display: flex !important; + flex-direction: row !important; +} + +.NavTabs__TabPanel { + overflow: hidden !important; +} + +.CallsTab__EmptyState { + display: none !important; +} + +.CallsTab__ConversationCallDetails { + display: none !important; +} + +.Stories__placeholder { + display: none !important; +} + +.NavSidebar { + width: 100% !important; +} + +.module-tooltip { + display: none !important; +} diff --git a/stylesheets/components/NavSidebar.scss b/stylesheets/components/NavSidebar.scss index ba5f39d48..21540684c 100644 --- a/stylesheets/components/NavSidebar.scss +++ b/stylesheets/components/NavSidebar.scss @@ -143,37 +143,12 @@ flex-direction: column; } -.NavSidebar__DragHandle { - position: absolute; - z-index: variables.$z-index-above-above-base; - top: 0; - bottom: 0; - inset-inline-start: 100%; - width: 8px; - background: transparent; +.NavSidebar__document--draggingHandle { cursor: col-resize; - // Disable browser handling of gestures so element can be dragged with touch events - touch-action: none; - - &:focus { - outline: none; - @include mixins.keyboard-mode { - box-shadow: inset 0 0 0 2px variables.$color-ultramarine; - } - } } -.NavSidebar__DragHandle--dragging { - @include mixins.light-theme { - background-color: variables.$color-black-alpha-12; - } - @include mixins.dark-theme { - background-color: variables.$color-white-alpha-12; - } -} - -.NavSidebar__document--draggingHandle { - cursor: col-resize; +#LeftPane { + width: 100%; } .NavSidebar__HeaderActions { diff --git a/stylesheets/manifest.scss b/stylesheets/manifest.scss index 953f4987e..76983e70b 100644 --- a/stylesheets/manifest.scss +++ b/stylesheets/manifest.scss @@ -203,3 +203,5 @@ @use 'components/UsernameMegaphone.scss'; @use 'components/UsernameOnboardingModal.scss'; @use 'components/WhatsNew.scss'; + +@use 'components/Droidian.scss'; From 270ba60abed7e1456e04903a489d9ec320ec491c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Thu, 6 Nov 2025 11:29:55 +0100 Subject: [PATCH 02/20] ts: Tweak conversation view for mobile phones --- ts/components/ChatsTab.dom.tsx | 58 ++---- ts/components/NavSidebar.dom.tsx | 192 +++++------------- ts/components/Preferences.dom.tsx | 2 +- .../conversation/ConversationHeader.dom.tsx | 16 ++ ts/state/ducks/conversations.preload.ts | 9 +- ts/state/selectors/items.dom.ts | 2 +- 6 files changed, 95 insertions(+), 184 deletions(-) diff --git a/ts/components/ChatsTab.dom.tsx b/ts/components/ChatsTab.dom.tsx index 636acc482..62ec8d615 100644 --- a/ts/components/ChatsTab.dom.tsx +++ b/ts/components/ChatsTab.dom.tsx @@ -42,45 +42,31 @@ export function ChatsTab({ }: ChatsTabProps): React.JSX.Element { return ( <> -
- {renderLeftPane({ - otherTabsUnreadStats, - collapsed: navTabsCollapsed, - hasPendingUpdate, - hasFailedStorySends, - onToggleCollapse: onToggleNavTabsCollapse, - })} -
+ + {!selectedConversationId && +
+ {renderLeftPane({ + otherTabsUnreadStats, + hasPendingUpdate, + hasFailedStorySends, + onToggleCollapse: onToggleNavTabsCollapse, + })} +
+ } + + {selectedConversationId &&
- {selectedConversationId ? ( -
- {renderConversationView({ selectedConversationId })} -
- ) : ( -
- {renderMiniPlayer({ shouldFlow: false })} -
-

- {isStaging - ? 'THIS IS A STAGING DESKTOP' - : i18n('icu:welcomeToSignal')} -

-

- -

-
-
- {i18n('icu:signalNonProfit')} -
-
- )} +
+ {renderConversationView({ selectedConversationId })} +
+ } ); } diff --git a/ts/components/NavSidebar.dom.tsx b/ts/components/NavSidebar.dom.tsx index 42e3b9829..14cc780d5 100644 --- a/ts/components/NavSidebar.dom.tsx +++ b/ts/components/NavSidebar.dom.tsx @@ -88,159 +88,61 @@ export function NavSidebar({ renderToastManager, }: NavSidebarProps): React.JSX.Element { const isRTL = i18n.getLocaleDirection() === 'rtl'; - const [dragState, setDragState] = useState(DragState.INITIAL); - - const [preferredWidth, setPreferredWidth] = useState(() => { - return getWidthFromPreferredWidth(preferredLeftPaneWidth, { - requiresFullWidth, - }); - }); - - const width = getWidthFromPreferredWidth(preferredWidth, { - requiresFullWidth, - }); - - const widthBreakpoint = getNavSidebarWidthBreakpoint(width); - - const expandNarrowLeftPane = useCallback(() => { - if (preferredWidth < MIN_FULL_WIDTH) { - setPreferredWidth(MIN_FULL_WIDTH); - savePreferredLeftPaneWidth(MIN_FULL_WIDTH); - } - }, [preferredWidth, savePreferredLeftPaneWidth]); - - // `useMove` gives us keyboard and mouse dragging support. - const { moveProps } = useMove({ - onMoveStart() { - setDragState(DragState.DRAGGING); - }, - onMoveEnd() { - setDragState(DragState.DRAGEND); - }, - onMove(event) { - const { shiftKey, pointerType } = event; - const deltaX = isRTL ? -event.deltaX : event.deltaX; - const isKeyboard = pointerType === 'keyboard'; - const increment = isKeyboard && shiftKey ? 10 : 1; - setPreferredWidth(prevWidth => { - // Jump minimize for keyboard users - if (isKeyboard && prevWidth === MIN_FULL_WIDTH && deltaX < 0) { - return MIN_WIDTH; - } - // Jump maximize for keyboard users - if (isKeyboard && prevWidth === MIN_WIDTH && deltaX > 0) { - return MIN_FULL_WIDTH; - } - return prevWidth + deltaX * increment; - }); - }, - }); - - useEffect(() => { - // Save the preferred width when the drag ends. We can't do this in onMoveEnd - // because the width is not updated yet. - if (dragState === DragState.DRAGEND) { - setPreferredWidth(width); - savePreferredLeftPaneWidth(width); - setDragState(DragState.INITIAL); - } - }, [ - dragState, - preferredLeftPaneWidth, - preferredWidth, - savePreferredLeftPaneWidth, - width, - ]); - - useEffect(() => { - // This effect helps keep the pointer `col-resize` even when you drag past the handle. - const className = 'NavSidebar__document--draggingHandle'; - if (dragState === DragState.DRAGGING) { - document.body.classList.add(className); - return () => { - document.body.classList.remove(className); - }; - } - return undefined; - }, [dragState]); return ( - -
- {!hideHeader && ( -
- {onBack == null && navTabsCollapsed && ( - +
+ {!hideHeader && ( +
+ {onBack == null && navTabsCollapsed && ( + + )} +
+ {onBack != null && ( + )} -
- {onBack != null && ( - - )} -

- {title} -

- {actions && ( -
{actions}
- )} -
+ {title} + + {actions && ( +
{actions}
+ )}
- )} +
+ )} -
{children}
+
{children}
-
- - {renderToastManager({ - containerWidthBreakpoint: widthBreakpoint, - expandNarrowLeftPane, - })} -
- + {renderToastManager({ containerWidthBreakpoint: 400 })} +
); } diff --git a/ts/components/Preferences.dom.tsx b/ts/components/Preferences.dom.tsx index 8f6857426..c5afb4ad9 100644 --- a/ts/components/Preferences.dom.tsx +++ b/ts/components/Preferences.dom.tsx @@ -2338,7 +2338,7 @@ export function Preferences({
void; onViewConversationDetails: () => void; }) { + const dispatch = useDispatch(); + const onBackButton = () => { + dispatch(showConversation({ conversationId: undefined })); + }; + let onClick: undefined | (() => void); const { type } = conversation; switch (type) { @@ -556,6 +564,13 @@ function HeaderContent({ if (onClick) { return ( + <> +
+ ); } diff --git a/ts/state/ducks/conversations.preload.ts b/ts/state/ducks/conversations.preload.ts index eaeb31d52..a577a7214 100644 --- a/ts/state/ducks/conversations.preload.ts +++ b/ts/state/ducks/conversations.preload.ts @@ -4796,7 +4796,7 @@ type ShowConversationArgsType = ReadonlyDeep<{ export type ShowConversationType = ReadonlyDeep< (options: ShowConversationArgsType) => unknown >; - +export { showConversation }; function showConversation({ conversationId, messageId, @@ -4869,6 +4869,13 @@ function showConversation({ return; } + const navtabs = document.getElementsByClassName('NavTabs') as HTMLElement; + if (conversationId == undefined) { + navtabs[0].style.display = 'block'; + } else { + navtabs[0].style.display = 'none'; + } + // notify composer in case we need to stop recording a voice note if ( originalLocation.tab === NavTab.Chats && diff --git a/ts/state/selectors/items.dom.ts b/ts/state/selectors/items.dom.ts index 6e71b4038..d83a0a0dc 100644 --- a/ts/state/selectors/items.dom.ts +++ b/ts/state/selectors/items.dom.ts @@ -258,7 +258,7 @@ export const getTextFormattingEnabled = createSelector( export const getNavTabsCollapsed = createSelector( getItems, - (state: ItemsStateType): boolean => Boolean(state.navTabsCollapsed ?? false) + (state: ItemsStateType): boolean => Boolean(false) ); export const getShowStickersIntroduction = createSelector( From 19398a51bf81f01778876dcdfe3d6ec95ed2a3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 5 Nov 2025 18:18:32 +0100 Subject: [PATCH 03/20] app: main: Simplify second instance startup Really slow on a phone, this commit does not really fix the issue :( --- app/main.main.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/app/main.main.ts b/app/main.main.ts index a906a6beb..4ffa78639 100644 --- a/app/main.main.ts +++ b/app/main.main.ts @@ -263,20 +263,7 @@ if (!process.mas) { app.exit(); } else { app.on('second-instance', (_e: Electron.Event, argv: Array) => { - // Workaround to let AllowSetForegroundWindow succeed. - // See https://www.npmjs.com/package/@signalapp/windows-dummy-keystroke for a full explanation of why this is needed. - if (OS.isWindows()) { - sendDummyKeystroke(); - } - - // Someone tried to run a second instance, we should focus our window - if (mainWindow) { - if (mainWindow.isMinimized()) { - mainWindow.restore(); - } - - showWindow(); - } + showWindow(); const route = maybeGetIncomingSignalRoute(argv); if (route != null) { From 5bac4c0204c61dca786908ff3b120b0548f78b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 30 Jul 2025 23:46:21 +0200 Subject: [PATCH 04/20] ts: components: SimpleQuillWrapper: Prevent auto-focus on mount for mobile When entering a conversation, signal-quill-cjs automatically focuses the editor, triggering the on-screen keyboard on mobile devices. This behavior is undesirable, as it suggests immediate typing is required. To prevent this: - The editor is now initially rendered with the inert attribute, making it non-focusable and non-interactive. - The inert attribute is removed on user click, allowing interaction and manual focus. This improves the user experience on mobile by preventing the keyboard from appearing until explicitly needed. --- ts/components/SimpleQuillWrapper.dom.tsx | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/ts/components/SimpleQuillWrapper.dom.tsx b/ts/components/SimpleQuillWrapper.dom.tsx index 7ac9ad413..9d928de72 100644 --- a/ts/components/SimpleQuillWrapper.dom.tsx +++ b/ts/components/SimpleQuillWrapper.dom.tsx @@ -1,7 +1,7 @@ // Copyright 2025 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import React, { createRef } from 'react'; +import React, { createRef, useCallback } from 'react'; import Quill from '@signalapp/quill-cjs'; import Emitter from '@signalapp/quill-cjs/core/emitter.js'; import type { Delta } from '@signalapp/quill-cjs'; @@ -62,7 +62,7 @@ export class SimpleQuillWrapper extends React.Component { formats: this.props.formats, modules: this.props.modules, placeholder: this.props.placeholder, - readOnly: this.props.readOnly, + readOnly: true }); } @@ -71,10 +71,24 @@ export class SimpleQuillWrapper extends React.Component { return this.quill; } + handleClick = () => { + const el = this.quillElement.current; + if (el) { + el.removeAttribute('inert'); + } + // Focus the Quill editor programmatically + if (this.quill) { + this.quill.focus(); + } + }; + override render(): React.JSX.Element { return ( -
-
+
+
); } From e3a5b444bbb27ac71b7f8712a32fd88bdeb85c6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Fri, 1 Aug 2025 15:34:08 +0200 Subject: [PATCH 05/20] ts: ActiveWindowService: consider screensaver state in isActive() Subscribe to the `ActiveChanged` signal from `org.gnome.ScreenSaver` via DBus and maintain internal state to reflect screensaver activity. The `isActive()` method now returns `false` when the screensaver is active, ensuring that application logic properly respects user inactivity. Useful for improving notifications behavior when the user is away. Only GNOME is supported at this stage; other desktop environments could be added later. --- package.json | 1 + ts/services/ActiveWindowService.std.ts | 34 +++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 633ec1e10..a6ab6cd97 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,7 @@ "country-codes-list": "2.0.0", "credit-card-type": "10.0.2", "dashdash": "2.0.0", + "dbus-native": "0.4.0", "direction": "1.0.4", "dom-accessibility-api": "0.7.0", "emoji-datasource": "16.0.0", diff --git a/ts/services/ActiveWindowService.std.ts b/ts/services/ActiveWindowService.std.ts index 5cf84aa37..3e4a62afc 100644 --- a/ts/services/ActiveWindowService.std.ts +++ b/ts/services/ActiveWindowService.std.ts @@ -3,6 +3,7 @@ import { SECOND } from '../util/durations/constants.std.js'; import { throttle } from '../util/throttle.std.js'; +import dbus from 'dbus-native'; // Idle timer - you're active for ACTIVE_TIMEOUT after one of these events const ACTIVE_TIMEOUT = 15 * SECOND; @@ -31,6 +32,8 @@ class ActiveWindowService { #isInitialized = false; #isFocused = false; + #screenSaverIface = null; + #screensaverActive: boolean = false; #activeCallbacks: Array<() => void> = []; #changeCallbacks: Array<(isActive: boolean) => void> = []; #lastActiveEventAt = -Infinity; @@ -53,6 +56,31 @@ class ActiveWindowService { } this.#isInitialized = true; + const sessionBus = dbus.sessionBus(); + const service = sessionBus.getService('org.gnome.ScreenSaver'); + + service.getInterface( + '/org/gnome/ScreenSaver', + 'org.gnome.ScreenSaver', + (err: Error | null, iface: any) => { + if (err) { + log.warn('Failed to connect to org.gnome.ScreenSaver:', err); + return; + } + this.#screenSaverIface = iface; + + iface.GetActive((err: Error | null, active: boolean) => { + if (!err) { + this.#screensaverActive = active; + } + }); + + iface.on('ActiveChanged', (active: boolean) => { + this.#screensaverActive = active; + }); + } + ); + this.#lastActiveEventAt = Date.now(); const onActiveEvent = this.#onActiveEvent.bind(this); @@ -67,7 +95,7 @@ class ActiveWindowService { } isActive(): boolean { - if (this.#isFocused) { + if (this.#isFocused && !this.#screensaverActive) { return Date.now() < this.#lastActiveEventAt + ACTIVE_TIMEOUT; } @@ -77,9 +105,7 @@ class ActiveWindowService { } return ( - Date.now() < - this.#lastActiveNonFocusingEventAt + - ACTIVE_AFTER_NON_FOCUSING_EVENT_TIMEOUT + !this.#screensaverActive ); } From c4c2397364a54e27412770585de64fedd4ae8d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Sat, 2 Aug 2025 16:35:49 +0200 Subject: [PATCH 06/20] app: Add D-Bus interface and wrapper to speed up secondary instance handling When Signal is minimized to the system tray, launching a second instance causes Electron to go through a full startup cycle before signaling the main instance to show the window. This results in a noticeable delay (~2 seconds). To avoid this, a lightweight D-Bus interface (`org.signal.Signal`) has been added. It exposes a `ShowWindow` method to allow the window to be shown immediately without full app startup. A wrapper script (`signal-desktop-mobile`) now attempts to call this method via `gdbus`. If the main instance is not running, it falls back to launching a new Electron process. This approach significantly reduces perceived startup time when the app is already running but hidden. --- app/main.main.ts | 44 +++++++++++++++++++++++++++++++++++++++++++ signal-desktop-mobile | 3 +++ 2 files changed, 47 insertions(+) create mode 100644 signal-desktop-mobile diff --git a/app/main.main.ts b/app/main.main.ts index 4ffa78639..90ec71f31 100644 --- a/app/main.main.ts +++ b/app/main.main.ts @@ -7,6 +7,7 @@ import * as os from 'node:os'; import fsExtra from 'fs-extra'; import { randomBytes } from 'node:crypto'; import { createParser } from 'dashdash'; +import dbus from 'dbus-native'; import fastGlob from 'fast-glob'; import PQueue from 'p-queue'; @@ -177,6 +178,47 @@ function getMainWindow() { return mainWindow; } +function setupDbus() { + const sessionBus = dbus.sessionBus(); + + if (!sessionBus) { + log.error('Could not connect to D-Bus session bus.'); + return; + } + + const serviceName = 'org.signal.Signal'; + const objectPath = '/org/signal/Signal'; + const interfaceName = 'org.signal.Signal'; + + sessionBus.requestName(serviceName, 0x4, (err, retCode) => { + if (err) { + log.error('Failed to request D-Bus name:', err); + return; + } + if (retCode !== 1) { + log.error('D-Bus name already taken.'); + return; + } + + const obj = { + 'org.signal.Signal': { + ShowWindow(callback: () => void) { + showWindow(); + }, + }, + }; + + sessionBus.exportInterface(obj['org.signal.Signal'], objectPath, { + name: interfaceName, + methods: { + ShowWindow: ['', '', [], []], + }, + signals: {}, + properties: {}, + }); + }); +} + const development = getEnvironment() === Environment.Development || getEnvironment() === Environment.Staging; @@ -784,6 +826,8 @@ async function createWindow() { systemTrayService.setMainWindow(mainWindow); } + setupDbus(); + function saveWindowStats() { if (!windowConfig) { return; diff --git a/signal-desktop-mobile b/signal-desktop-mobile new file mode 100644 index 000000000..5350b82ce --- /dev/null +++ b/signal-desktop-mobile @@ -0,0 +1,3 @@ +#!/bin/sh + +gdbus call -e -d org.signal.Signal -o /org/signal/Signal -m org.signal.Signal.ShowWindow >/dev/null 2>&1|| /usr/lib/signal-desktop/signal-desktop --enable-features=UseOzonePlatform --ozone-platform=wayland --enable-wayland-ime --wayland-text-input-version=3 $@ From e81a619f21835ae5817a91703d8c14fd6ccf62ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 5 Nov 2025 18:24:49 +0100 Subject: [PATCH 07/20] ts: util: buildExperiation: Never expire --- ts/util/buildExpiration.std.ts | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/ts/util/buildExpiration.std.ts b/ts/util/buildExpiration.std.ts index 530443ec7..693d6e4db 100644 --- a/ts/util/buildExpiration.std.ts +++ b/ts/util/buildExpiration.std.ts @@ -59,30 +59,5 @@ export function hasBuildExpired({ now, logger, }: HasBuildExpiredOptionsType): boolean { - if ( - getEnvironment() !== Environment.PackagedApp && - buildExpirationTimestamp === 0 - ) { - return false; - } - - if (isInPast(buildExpirationTimestamp)) { - return true; - } - - const safeExpirationMs = autoDownloadUpdate - ? NINETY_ONE_DAYS - : THIRTY_ONE_DAYS; - - const buildExpirationDuration = buildExpirationTimestamp - now; - const tooFarIntoFuture = buildExpirationDuration > safeExpirationMs; - - if (tooFarIntoFuture) { - logger.error( - 'Build expiration is set too far into the future', - buildExpirationTimestamp - ); - } - - return tooFarIntoFuture || isInPast(buildExpirationTimestamp); + return false; } From 8284d3e12f2eac27b4338a5097490dea5211031d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 5 Nov 2025 18:25:56 +0100 Subject: [PATCH 08/20] ts: services: notifications: Show one notification per conversation --- ts/services/notifications.preload.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/ts/services/notifications.preload.ts b/ts/services/notifications.preload.ts index 03ad822da..e6d9c5eba 100644 --- a/ts/services/notifications.preload.ts +++ b/ts/services/notifications.preload.ts @@ -82,7 +82,6 @@ class NotificationService extends EventEmitter { public isEnabled = false; - #lastNotification: null | Notification = null; #notificationData: null | NotificationDataType = null; #tokenData: { token: string; data: NotificationClickData } | undefined; @@ -192,13 +191,11 @@ class NotificationService extends EventEmitter { }) ); } else { - this.#lastNotification?.close(); - const notification = new window.Notification(title, { body: OS.isLinux() ? filterNotificationText(message) : message, icon: iconUrl, silent: true, - tag: messageId, + tag: conversationId }); notification.onclick = () => { @@ -230,8 +227,6 @@ class NotificationService extends EventEmitter { throw missingCaseError(type); } }; - - this.#lastNotification = notification; } if (!silent) { @@ -344,9 +339,6 @@ class NotificationService extends EventEmitter { this.#tokenData = undefined; drop(window.IPC.clearAllWindowsNotifications()); } - } else if (this.#lastNotification) { - this.#lastNotification.close(); - this.#lastNotification = null; } // This isn't a boolean because TypeScript isn't smart enough to know that, if From 9162ead8124a16a1077ca499e2f15567cb7ffdf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 5 Nov 2025 18:35:08 +0100 Subject: [PATCH 09/20] ts: components: fun: Disable autofocus --- ts/components/fun/base/FunSearch.dom.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ts/components/fun/base/FunSearch.dom.tsx b/ts/components/fun/base/FunSearch.dom.tsx index 6f0cb1b87..f15ce63e2 100644 --- a/ts/components/fun/base/FunSearch.dom.tsx +++ b/ts/components/fun/base/FunSearch.dom.tsx @@ -53,7 +53,7 @@ export function FunSearch(props: FunSearchProps): React.JSX.Element { onBlur={handleBlur} placeholder={props.placeholder} // eslint-disable-next-line jsx-a11y/no-autofocus - autoFocus={shouldAutoFocus} + autoFocus={false} /> {props.searchInput !== '' && (
From ec0524b90f34bc0c37c5de7702db6ad3fdfc8e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 4 Dec 2024 14:16:23 +0100 Subject: [PATCH 17/20] circleci: Initial config --- .circleci/config.yml | 26 ++++++++++++++++++++++++++ debian/changelog | 5 +++++ debian/control | 21 +++++++++++++++++++++ debian/rules | 34 ++++++++++++++++++++++++++++++++++ debian/source/format | 1 + 5 files changed, 87 insertions(+) create mode 100644 .circleci/config.yml create mode 100644 debian/changelog create mode 100644 debian/control create mode 100755 debian/rules create mode 100644 debian/source/format diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 000000000..5285e5390 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,26 @@ +version: 2.1 + +setup: true + +orbs: + continuation: circleci/continuation@0.1.2 + droidian-buildd: droidian-releng/droidian-buildd-orb@volatile + +jobs: + setup: + executor: continuation/default + resource_class: small + steps: + - droidian-buildd/checkout + - droidian-buildd/generate + - continuation/continue: + configuration_path: generated_config.yml + +workflows: + setup: + jobs: + - setup: + filters: + tags: + only: /^droidian\/.*\/.*/ + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..3d73598b8 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,5 @@ +signal-desktop (7.35-1) unstable; urgency=medium + + * Initial release. + + -- Cédric Bellegarde Fri, 10 May 2024 19:10:29 +0100 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..c37c0b916 --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: signal-desktop +Section: utils +Priority: optional +Maintainer: Cédric Bellegarde +Rules-Requires-Root: no +Build-Depends: + debhelper-compat (= 13), + build-essential, + nodejs, + npm, + git +Standards-Version: 4.6.2 +Homepage: https://github.com/bellegarde-c/Signal-Desktop + +Package: signal-desktop +Architecture: any +Depends: + dbus, + ${shlibs:Depends}, + ${misc:Depends}, +Description: A private messenger for Windows, macOS, and Linux. diff --git a/debian/rules b/debian/rules new file mode 100755 index 000000000..2682f28db --- /dev/null +++ b/debian/rules @@ -0,0 +1,34 @@ +#!/usr/bin/make -f + +# See debhelper(7) (uncomment to enable). +# Output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# See FEATURE AREAS in dpkg-buildflags(1). +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# See ENVIRONMENT in dpkg-buildflags(1). +# Package maintainers to append CFLAGS. +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# Package maintainers to append LDFLAGS. +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + +override_dh_auto_build: + git lfs install + sed 's#"node": "#&>=#' -i package.json + npm --prefix ./sticker-creator/ install + npm install --ignore-engines + npm --prefix ./sticker-creator/ run build + npm run build + ls -l + +%: + dh $@ + + +# dh_make generated override targets. +# This is an example for Cmake (see ). +#override_dh_auto_configure: +# dh_auto_configure -- \ +# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 000000000..163aaf8d8 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) From 2c41255ef78b117e9ac16b8e68b5228697f1cf92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Thu, 5 Dec 2024 09:46:17 +0100 Subject: [PATCH 18/20] debian: Create package --- debian/control | 16 +++++++++++++--- debian/rules | 27 ++++++++++++++++++++++----- package.json | 16 +--------------- signal-desktop.desktop | 12 ++++++++++++ 4 files changed, 48 insertions(+), 23 deletions(-) create mode 100644 signal-desktop.desktop diff --git a/debian/control b/debian/control index c37c0b916..53ca58dc0 100644 --- a/debian/control +++ b/debian/control @@ -8,14 +8,24 @@ Build-Depends: build-essential, nodejs, npm, - git + git, + git-lfs, + libnotify4, + libxtst6, + libnss3, + libasound2t64, + libpulse0, + libxss1, + libc6 (>= 2.31), + libgtk-3-0, + libgbm1, + libx11-xcb1 Standards-Version: 4.6.2 -Homepage: https://github.com/bellegarde-c/Signal-Desktop +Homepage: https://github.com/droidian/Signal-Desktop Package: signal-desktop Architecture: any Depends: - dbus, ${shlibs:Depends}, ${misc:Depends}, Description: A private messenger for Windows, macOS, and Linux. diff --git a/debian/rules b/debian/rules index 2682f28db..b3834e136 100755 --- a/debian/rules +++ b/debian/rules @@ -14,14 +14,31 @@ # Package maintainers to append LDFLAGS. #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed +export PATH := /tmp/signal-desktop/node_modules/.bin:$(PATH) + +override_dh_dwz: + +override_dh_shlibdeps: + dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + + override_dh_auto_build: git lfs install sed 's#"node": "#&>=#' -i package.json - npm --prefix ./sticker-creator/ install - npm install --ignore-engines - npm --prefix ./sticker-creator/ run build - npm run build - ls -l + npm install --prefix /tmp/signal-desktop pnpm + pnpm install --dir ./sticker-creator/ + pnpm install + pnpm run build + +override_dh_auto_install: + install -d debian/signal-desktop/usr/bin + install -d debian/signal-desktop/usr/lib + mv release/linux-unpacked debian/signal-desktop/usr/lib/signal-desktop || true + mv release/linux-arm64-unpacked debian/signal-desktop/usr/lib/signal-desktop || true + ln -s /usr/lib/signal-desktop/signal-desktop debian/signal-desktop/usr/bin/signal-desktop-mobile + chmod u+s debian/signal-desktop/usr/lib/signal-desktop/chrome-sandbox + for i in 16 24 32 48 64 128 256 512 1024; do install -Dm 644 "build/icons/png/$${i}x$${i}.png" "debian/signal-desktop/usr/share/icons/hicolor/$${i}x$${i}/apps/signal-desktop.png"; done + install -Dm 644 ./signal-desktop.desktop -t debian/signal-desktop/usr/share/applications %: dh $@ diff --git a/package.json b/package.json index a6ab6cd97..42a1d6d6a 100644 --- a/package.json +++ b/package.json @@ -528,7 +528,7 @@ }, "artifactName": "${name}_${version}_${arch}.${ext}", "target": [ - "deb" + "dir" ], "icon": "build/icons/png", "publish": [ @@ -552,20 +552,6 @@ } ] }, - "deb": { - "depends": [ - "libnotify4", - "libxtst6", - "libnss3", - "libasound2", - "libpulse0", - "libxss1", - "libc6 (>= 2.34)", - "libgtk-3-0", - "libgbm1", - "libx11-xcb1" - ] - }, "protocols": { "name": "sgnl-url-scheme", "schemes": [ diff --git a/signal-desktop.desktop b/signal-desktop.desktop new file mode 100644 index 000000000..6104ca923 --- /dev/null +++ b/signal-desktop.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +Name=Signal +Comment=Signal Messenger +Icon=signal-desktop +Exec=/usr/bin/signal-desktop-mobile --enable-features=UseOzonePlatform --ozone-platform=wayland --enable-wayland-ime --wayland-text-input-version=3 -- %u +Terminal=false +Categories=Network;InstantMessaging; +StartupWMClass=signal +MimeType=x-scheme-handler/sgnl;x-scheme-handler/signalcaptcha; +Keywords=sgnl;chat;im;messaging;messenger;security;privat; +X-GNOME-UsesNotifications=true From 5dc4f0937b291083a8ddd0b838cd21129b2ec057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Wed, 11 Mar 2026 22:30:56 +0100 Subject: [PATCH 19/20] debian: Update desktop file --- debian/rules | 2 +- signal-desktop.desktop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/rules b/debian/rules index b3834e136..e5df58bdf 100755 --- a/debian/rules +++ b/debian/rules @@ -35,10 +35,10 @@ override_dh_auto_install: install -d debian/signal-desktop/usr/lib mv release/linux-unpacked debian/signal-desktop/usr/lib/signal-desktop || true mv release/linux-arm64-unpacked debian/signal-desktop/usr/lib/signal-desktop || true - ln -s /usr/lib/signal-desktop/signal-desktop debian/signal-desktop/usr/bin/signal-desktop-mobile chmod u+s debian/signal-desktop/usr/lib/signal-desktop/chrome-sandbox for i in 16 24 32 48 64 128 256 512 1024; do install -Dm 644 "build/icons/png/$${i}x$${i}.png" "debian/signal-desktop/usr/share/icons/hicolor/$${i}x$${i}/apps/signal-desktop.png"; done install -Dm 644 ./signal-desktop.desktop -t debian/signal-desktop/usr/share/applications + install -Dm 755 ./signal-desktop-mobile -t debian/signal-desktop/usr/bin %: dh $@ diff --git a/signal-desktop.desktop b/signal-desktop.desktop index 6104ca923..424b72e52 100644 --- a/signal-desktop.desktop +++ b/signal-desktop.desktop @@ -3,7 +3,7 @@ Type=Application Name=Signal Comment=Signal Messenger Icon=signal-desktop -Exec=/usr/bin/signal-desktop-mobile --enable-features=UseOzonePlatform --ozone-platform=wayland --enable-wayland-ime --wayland-text-input-version=3 -- %u +Exec=/usr/bin/signal-desktop-mobile %u Terminal=false Categories=Network;InstantMessaging; StartupWMClass=signal From 5b72c143a492c3f971da167a466c98f197b78bc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 21:44:47 +0000 Subject: [PATCH 20/20] Bump electron from 39.2.7 to 41.0.0 Dependabot couldn't find the original pull request head commit, 43332d95309acfe084a068b67465eec30aefa52d. --- package.json | 2 +- pnpm-lock.yaml | 199 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 175 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 42a1d6d6a..0cf044e5f 100644 --- a/package.json +++ b/package.json @@ -311,7 +311,7 @@ "csv-parse": "5.5.6", "danger": "12.3.3", "debug": "4.3.7", - "electron": "40.4.1", + "electron": "41.0.0", "electron-builder": "26.0.14", "electron-mocha": "13.0.1", "endanger": "7.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c62c130b9..59af48f03 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -194,6 +194,9 @@ importers: dashdash: specifier: 2.0.0 version: 2.0.0 + dbus-native: + specifier: 0.4.0 + version: 0.4.0 direction: specifier: 1.0.4 version: 1.0.4 @@ -652,8 +655,8 @@ importers: specifier: 4.3.7 version: 4.3.7(supports-color@8.1.1) electron: - specifier: 40.4.1 - version: 40.4.1 + specifier: 41.0.0 + version: 41.0.0 electron-builder: specifier: 26.0.14 version: 26.0.14(electron-builder-squirrel-windows@26.0.14) @@ -3533,6 +3536,9 @@ packages: '@sinonjs/text-encoding@0.7.3': resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + deprecated: |- + Deprecated: no longer maintained and no longer used by Sinon packages. See + https://github.com/sinonjs/nise/issues/243 for replacement details. '@storybook/addon-a11y@8.4.4': resolution: {integrity: sha512-xXNOG4Bw/v8rg2Zq/ZJnZSLWfpfkfnZjn0sQVLOe5JcDxavkh5o+WvQ6Tc2w/kK/ophCd7nbTotywrtdQYGNKw==} @@ -4144,11 +4150,8 @@ packages: '@types/node@22.13.4': resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} - '@types/node@22.19.1': - resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} - - '@types/node@24.10.9': - resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} + '@types/node@24.11.0': + resolution: {integrity: sha512-fPxQqz4VTgPI/IQ+lj9r0h+fDR66bzoeMGHp8ASee+32OSGIkeASsoZuJixsQoVef1QJbeubcPBxKk22QVoWdw==} '@types/normalize-path@3.0.2': resolution: {integrity: sha512-DO++toKYPaFn0Z8hQ7Tx+3iT9t77IJo/nDiqTXilgEP+kPNIYdpS9kh3fXuc53ugqwp9pxC1PVjCpV1tQDyqMA==} @@ -4497,6 +4500,12 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} + abstract-socket@2.1.1: + resolution: {integrity: sha512-YZJizsvS1aBua5Gd01woe4zuyYBGgSMeqDOB6/ChwdTI904KP6QGtJswXl4hcqWxbz86hQBe++HWV0hF1aGUtA==} + engines: {node: '>=4.0.0'} + os: [linux] + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -4836,6 +4845,7 @@ packages: basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} + deprecated: Security vulnerability fixed in 5.2.0, please upgrade batch@0.6.1: resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} @@ -5514,6 +5524,10 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dbus-native@0.4.0: + resolution: {integrity: sha512-i3zvY3tdPEOaMgmK4riwupjDYRJ53rcE1Kj8rAgnLOFmBd0DekUih59qv8v+Oyils/U9p+s4sSsaBzHWLztI+Q==} + hasBin: true + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -5800,6 +5814,9 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + duplexify@4.1.3: resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} @@ -5848,8 +5865,8 @@ packages: engines: {node: '>= 12.20.55'} hasBin: true - electron@40.4.1: - resolution: {integrity: sha512-N1ZXybQZL8kYemO8vAeh9nrk4mSvqlAO8xs0QCHkXIvRnuB/7VGwEehjvQbsU5/f4bmTKpG+2GQERe/zmKpudQ==} + electron@41.0.0: + resolution: {integrity: sha512-U7QueSj1cFj9QM0Qamgh/MK08662FVK555iMfapqU7mcAmIm4A8bZuZptpjMXrT4JNAMGjgWu9sOeO1+RPCJNw==} engines: {node: '>= 12.20.55'} hasBin: true @@ -6226,6 +6243,9 @@ packages: event-emitter@0.3.5: resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + event-stream@4.0.1: + resolution: {integrity: sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -6487,6 +6507,9 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fromentries@1.3.2: resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} @@ -6781,6 +6804,10 @@ packages: resolution: {integrity: sha512-NU+zsiDvdL+EebyTjrEqjkO2XYI7FgLhQzsbmO8dnnYce3S0PBSDm/ZyI4KpcGPXYEdb5W72vp/AQFuc4F8ASg==} engines: {node: '>=8.0.0'} + hexy@0.2.11: + resolution: {integrity: sha512-ciq6hFsSG/Bpt2DmrZJtv+56zpPdnq+NQ4ijEFrveKN0ZG1mhl/LdT1NQZ9se6ty1fACcI4d4vYqC9v8EYpH2A==} + hasBin: true + hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} @@ -7881,6 +7908,9 @@ packages: resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} engines: {node: '>= 0.6.0'} + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -7968,6 +7998,9 @@ packages: map-or-similar@1.5.0: resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + map-stream@0.0.7: + resolution: {integrity: sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==} + markdown-it-anchor@8.6.7: resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} peerDependencies: @@ -8192,6 +8225,9 @@ packages: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@0.0.10: + resolution: {integrity: sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -8285,6 +8321,9 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nan@2.25.0: + resolution: {integrity: sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -8513,6 +8552,9 @@ packages: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true + optimist@0.6.1: + resolution: {integrity: sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==} + optionator@0.8.3: resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} engines: {node: '>= 0.8.0'} @@ -8740,6 +8782,9 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + pe-library@0.4.1: resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} engines: {node: '>=12', npm: '>=6'} @@ -9096,6 +9141,9 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + pumpify@2.0.1: resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} @@ -9113,6 +9161,10 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + put@0.0.6: + resolution: {integrity: sha512-w0szIZ2NkqznMFqxYPRETCIi+q/S8UKis9F4yOl6/N9NDCZmbjZZT85aI4FgJf3vIPrzMPX60+odCLOaYxNWWw==} + engines: {node: '>=0.3.0'} + qrcode-generator@1.4.4: resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} @@ -9605,6 +9657,10 @@ packages: sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} @@ -9828,6 +9884,9 @@ packages: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -9874,6 +9933,9 @@ packages: prettier: optional: true + stream-combiner@0.2.2: + resolution: {integrity: sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==} + stream-shift@1.0.3: resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} @@ -10183,6 +10245,9 @@ packages: through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + thunky@1.1.0: resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} @@ -10399,9 +10464,6 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -10762,6 +10824,10 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@0.0.3: + resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==} + engines: {node: '>=0.4.0'} + workerpool@6.5.1: resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} @@ -10833,9 +10899,17 @@ packages: resolution: {integrity: sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==} engines: {node: '>=4'} + xml2js@0.4.23: + resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} + engines: {node: '>=4.0.0'} + xml@1.0.1: resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + xmlbuilder@15.1.1: resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} engines: {node: '>=8.0'} @@ -14421,7 +14495,7 @@ snapshots: '@storybook/builder-webpack5@8.4.4(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4)': dependencies: '@storybook/core-webpack': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) - '@types/node': 22.19.1 + '@types/node': 22.13.4 '@types/semver': 7.5.8 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 @@ -14478,7 +14552,7 @@ snapshots: '@storybook/core-webpack@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))': dependencies: - '@types/node': 22.19.1 + '@types/node': 22.13.4 storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) ts-dedent: 2.2.0 @@ -14523,7 +14597,7 @@ snapshots: '@storybook/core-webpack': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) '@storybook/react': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3) '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.6.3)(webpack@5.96.1) - '@types/node': 22.19.1 + '@types/node': 22.13.4 '@types/semver': 7.5.8 find-up: 5.0.0 magic-string: 0.30.17 @@ -15093,11 +15167,7 @@ snapshots: dependencies: undici-types: 6.20.0 - '@types/node@22.19.1': - dependencies: - undici-types: 6.21.0 - - '@types/node@24.10.9': + '@types/node@24.11.0': dependencies: undici-types: 7.16.0 @@ -15542,6 +15612,12 @@ snapshots: dependencies: event-target-shim: 5.0.1 + abstract-socket@2.1.1: + dependencies: + bindings: 1.5.0 + nan: 2.25.0 + optional: true + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -16734,6 +16810,18 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dbus-native@0.4.0: + dependencies: + event-stream: 4.0.1 + hexy: 0.2.11 + long: 4.0.0 + optimist: 0.6.1 + put: 0.0.6 + safe-buffer: 5.2.1 + xml2js: 0.4.23 + optionalDependencies: + abstract-socket: 2.1.1 + debug@2.6.9: dependencies: ms: 2.0.0 @@ -16994,6 +17082,8 @@ snapshots: duplexer3@0.1.5: {} + duplexer@0.1.2: {} + duplexify@4.1.3: dependencies: end-of-stream: 1.4.5 @@ -17087,10 +17177,10 @@ snapshots: transitivePeerDependencies: - supports-color - electron@40.4.1: + electron@41.0.0: dependencies: '@electron/get': 2.0.3 - '@types/node': 24.10.9 + '@types/node': 24.11.0 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -17741,6 +17831,16 @@ snapshots: d: 1.0.2 es5-ext: 0.10.64 + event-stream@4.0.1: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.0.7 + pause-stream: 0.0.11 + split: 1.0.1 + stream-combiner: 0.2.2 + through: 2.3.8 + event-target-shim@5.0.1: {} eventemitter3@4.0.7: {} @@ -18069,6 +18169,8 @@ snapshots: fresh@0.5.2: {} + from@0.1.7: {} + fromentries@1.3.2: {} fs-exists-sync@0.1.0: {} @@ -18198,7 +18300,7 @@ snapshots: get-stream@5.2.0: dependencies: - pump: 3.0.3 + pump: 3.0.4 get-stream@6.0.1: {} @@ -18418,6 +18520,8 @@ snapshots: dependencies: libheif-js: 1.18.2 + hexy@0.2.11: {} + hey-listen@1.0.8: {} hoist-non-react-statics@3.3.2: @@ -19730,6 +19834,8 @@ snapshots: loglevel@1.9.2: {} + long@4.0.0: {} + long@5.2.3: {} longest-streak@2.0.4: {} @@ -19839,6 +19945,8 @@ snapshots: map-or-similar@1.5.0: {} + map-stream@0.0.7: {} + markdown-it-anchor@8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.0): dependencies: '@types/markdown-it': 14.1.2 @@ -20095,6 +20203,8 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimist@0.0.10: {} + minimist@1.2.8: {} minipass-collect@1.0.2: @@ -20202,6 +20312,9 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nan@2.25.0: + optional: true + nanoid@3.3.11: {} nanoid@3.3.8: {} @@ -20452,6 +20565,11 @@ snapshots: opener@1.5.2: {} + optimist@0.6.1: + dependencies: + minimist: 0.0.10 + wordwrap: 0.0.3 + optionator@0.8.3: dependencies: deep-is: 0.1.4 @@ -20689,6 +20807,10 @@ snapshots: pathval@2.0.0: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + pe-library@0.4.1: {} pe-library@1.0.1: {} @@ -20992,6 +21114,11 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + pumpify@2.0.1: dependencies: duplexify: 4.1.3 @@ -21006,6 +21133,8 @@ snapshots: pure-rand@6.1.0: {} + put@0.0.6: {} + qrcode-generator@1.4.4(patch_hash=1f10c592d849ed4cfc9f81301196d39857b79240997ef5772138218cb3717e80): {} qs@6.13.0: @@ -21688,6 +21817,8 @@ snapshots: sax@1.4.1: {} + sax@1.4.4: {} + scheduler@0.23.2: dependencies: loose-envify: 1.4.0 @@ -21989,6 +22120,10 @@ snapshots: split2@4.2.0: {} + split@1.0.1: + dependencies: + through: 2.3.8 + sprintf-js@1.0.3: {} sprintf-js@1.1.3: {} @@ -22029,6 +22164,11 @@ snapshots: - supports-color - utf-8-validate + stream-combiner@0.2.2: + dependencies: + duplexer: 0.1.2 + through: 2.3.8 + stream-shift@1.0.3: {} streamsearch@1.1.0: {} @@ -22424,6 +22564,8 @@ snapshots: readable-stream: 2.3.8 xtend: 4.0.2 + through@2.3.8: {} + thunky@1.1.0: {} timed-out@4.0.1: {} @@ -22625,8 +22767,6 @@ snapshots: undici-types@6.20.0: {} - undici-types@6.21.0: {} - undici-types@7.16.0: {} unified@9.2.2: @@ -23090,6 +23230,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@0.0.3: {} + workerpool@6.5.1: {} wrap-ansi@5.1.0: @@ -23160,8 +23302,15 @@ snapshots: xdg-basedir@3.0.0: {} + xml2js@0.4.23: + dependencies: + sax: 1.4.4 + xmlbuilder: 11.0.1 + xml@1.0.1: {} + xmlbuilder@11.0.1: {} + xmlbuilder@15.1.1: {} xmlcreate@2.0.4: {}