Compare commits

...

9 Commits
main ... 5.59.x

Author SHA1 Message Date
Scott Nonnenberg 19f26cc423 v5.59.0 2022-09-14 17:57:35 -07:00
Scott Nonnenberg 60815fba6f Update strings 2022-09-14 17:57:02 -07:00
Jamie Kyle 51f7034cab
Fix storyviewer title for groups 2022-09-14 17:33:18 -07:00
automated-signal 3b33ec74a6
Separate flag for cdsi in beta channel
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-13 21:27:10 -07:00
Scott Nonnenberg 1f010c75c6
Improve logging in handleDataMessage and contact sync 2022-09-13 21:09:28 -07:00
automated-signal 4cb52b75f2
Center "Disappearing Messages" in Create Group
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-12 16:55:54 -07:00
automated-signal 0917f22f0a
Never pass negative speaker height to RingRTC
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-12 15:57:06 -06:00
automated-signal 2454432d92
Fixed positioning of emoji popper - avoids range error
Co-authored-by: Alvaro <110414366+alvaro-signal@users.noreply.github.com>
2022-09-12 09:11:10 -07:00
automated-signal dff3633257
Update electron to 20.1.3
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
2022-09-08 18:09:19 -07:00
15 changed files with 101 additions and 103 deletions

View File

@ -552,7 +552,7 @@
"description": "Alt text for staged attachments"
},
"cdsMirroringErrorToast": {
"message": "El Escritorio ha encontrado una inconsistencia del Servicio de descubrimiento de contactos.",
"message": "Desktop ha encontrado una inconsistencia del Servicio de descubrimiento de contactos.",
"description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
},
"decryptionErrorToast": {

View File

@ -552,7 +552,7 @@
"description": "Alt text for staged attachments"
},
"cdsMirroringErrorToast": {
"message": "Рабочий стол столкнулся с несогласованностью Службы обнаружения контактов.",
"message": "Signal Desktop столкнулся с несогласованностью Службы обнаружения контактов.",
"description": "An error popup when we discovered an inconsistency between mirrored Contact Discovery Service requests."
},
"decryptionErrorToast": {
@ -5568,7 +5568,7 @@
"description": "Button label to delete a story"
},
"SendStoryModal__confirm-remove-group": {
"message": "Удалить историю? Это приведет к удалению истории из вашего списка, но вы по-прежнему сможете просматривать истории этой группы.",
"message": "Удалить историю? Это приведёт к удалению истории из вашего списка, но вы по-прежнему сможете просматривать истории этой группы.",
"description": "Confirmation body for removing a group story"
},
"Stories__settings-toggle--title": {
@ -5604,7 +5604,7 @@
"description": "Aria label for unmuting stories"
},
"StoryViewer__views-off": {
"message": "Просмотр отключен",
"message": "Просмотры отключены",
"description": "When the user has read receipts turned off"
},
"StoryDetailsModal__sent-time": {

View File

@ -5360,15 +5360,15 @@
"description": "Additional information about signal connections and the stories they can see"
},
"Stories__title": {
"message": "Історії",
"message": "Сторіз",
"description": "Title for the stories list"
},
"Stories__mine": {
"message": "Мої історії",
"message": "Мої сторіз",
"description": "Label for your stories"
},
"Stories__add": {
"message": "Додати історію",
"message": "Додати сторі",
"description": "Description hint to add a story"
},
"Stories__add-story--text": {
@ -5380,15 +5380,15 @@
"description": "Label to create a new multimedia story"
},
"Stories__hidden-stories": {
"message": "Приховані історії",
"message": "Приховані сторіз",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Нових історій немає",
"message": "Нових сторіз немає",
"description": "Description for when there are no stories to show"
},
"Stories__placeholder--text": {
"message": "Клацніть для перегляду історії",
"message": "Клацніть для перегляду сторі",
"description": "Placeholder label for the story view"
},
"Stories__from-to-group": {
@ -5408,11 +5408,11 @@
"description": "Toast message"
},
"StoriesSettings__title": {
"message": "Налаштування історії",
"message": "Налаштування сторі",
"description": "Title for the story settings modal"
},
"StoriesSettings__new-list": {
"message": "Нова приватна історія",
"message": "Нова приватна сторі",
"description": "Label to create a new private story list"
},
"StoriesSettings__viewers--singular": {
@ -5424,7 +5424,7 @@
"description": "More than one viewer"
},
"StoriesSettings__who-can-see": {
"message": "Хто може бачити цю історію",
"message": "Хто може бачити цю сторі",
"description": "Title for the who can see this story section"
},
"StoriesSettings__add-viewer": {
@ -5440,7 +5440,7 @@
"description": "Title of the confirmation dialog, has a person's name"
},
"StoriesSettings__remove--body": {
"message": "Ця особа більше не бачитиме ваших історій.",
"message": "Ця особа більше не бачитиме вашу сторі.",
"description": "Body of the confirmation dialog to remove someone from a private distribution list"
},
"StoriesSettings__replies-reactions--title": {
@ -5456,7 +5456,7 @@
"description": "Description of checkbox to allow or disallow replies to your stories"
},
"StoriesSettings__delete-list": {
"message": "Видалити приватну історію",
"message": "Видалити приватну сторі",
"description": "Button label to delete a private distribution list"
},
"StoriesSettings__delete-list--confirm": {
@ -5472,11 +5472,11 @@
"description": "Modal title when naming a private distribution list"
},
"StoriesSettings__name-placeholder": {
"message": "Назва історії (обов'язкова)",
"message": "Назва сторі (обов'язкова)",
"description": "Placeholder for input field"
},
"StoriesSettings__hide-story": {
"message": "Сховати історію від",
"message": "Приховати сторі від",
"description": "Modal title when hiding people from my stories"
},
"StoriesSettings__mine__all--label": {
@ -5516,7 +5516,7 @@
"description": "Learn more link to learn about who can view your story"
},
"StoriesSettings__context-menu": {
"message": "Налаштування історії",
"message": "Налаштування сторі",
"description": "Button label to get to story settings"
},
"SendStoryModal__choose-who-can-view": {
@ -5536,7 +5536,7 @@
"description": "button to create a new distribution list to send story to"
},
"SendStoryModal__new-private--title": {
"message": "Нова приватна історія",
"message": "Нова приватна сторі",
"description": "Create a new distribution list"
},
"SendStoryModal__new-private--description": {
@ -5592,7 +5592,7 @@
"description": "Button label to reply to a story"
},
"StoryViewer__reply-group": {
"message": "Відповісти на історію групи",
"message": "Відповісти на сторі групи",
"description": "Button label to reply to a group story"
},
"StoryViewer__mute": {
@ -5636,23 +5636,23 @@
"description": "Title for replies tab"
},
"StoryViewsNRepliesModal__react": {
"message": "Реагувати на історію",
"message": "Реагувати на сторі",
"description": "aria-label for reaction button"
},
"StoryViewsNRepliesModal__reacted": {
"message": "Зреагував на історію",
"message": "Реагує на сторі",
"description": "Description of someone reacting to a story"
},
"StoryListItem__label": {
"message": "Історія",
"message": "Сторі",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Показати історії",
"message": "Показати сторіз",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Сховати історію",
"message": "Сховати сторі",
"description": "Label for menu item to hide the story"
},
"StoryListItem__go-to-chat": {
@ -5668,7 +5668,7 @@
"description": "Label for menu item to get a story's information"
},
"StoryListItem__hide-modal--body": {
"message": "Сховати історію? Оновлення історій від $name$ більше не з'являтимуться нагорі списку історій.",
"message": "Сховати сторі? Оновлення сторі від користувача $name$ більше не з'являтимуться нагорі списку сторіз.",
"description": "Body for the confirmation dialog for hiding a story"
},
"StoryListItem__hide-modal--confirm": {
@ -5768,15 +5768,15 @@
"description": "Title for the link preview tooltip"
},
"Quote__story": {
"message": "Історія",
"message": "Сторі",
"description": "Title for replies to stories"
},
"Quote__story-reaction": {
"message": "Реакція на історію від $name$",
"message": "Реакція на сторі від $name$",
"description": "Label for when a person reacts to a story"
},
"Quote__story-reaction--single": {
"message": "Реакції на історію",
"message": "Реакція на сторі",
"description": "Used whenever we can't find a user's first name"
},
"Quote__story-unavailable": {

View File

@ -4,7 +4,7 @@
"description": "Private messaging from your desktop",
"desktopName": "signal.desktop",
"repository": "https://github.com/signalapp/Signal-Desktop.git",
"version": "5.59.0-beta.1",
"version": "5.59.0",
"license": "AGPL-3.0-only",
"author": {
"name": "Signal Messenger, LLC",
@ -272,7 +272,7 @@
"cross-env": "5.2.0",
"css-loader": "3.2.0",
"debug": "4.3.3",
"electron": "20.1.0",
"electron": "20.1.3",
"electron-builder": "23.0.8",
"electron-mocha": "11.0.2",
"electron-notarize": "1.2.1",

View File

@ -5140,6 +5140,7 @@ button.module-image__border-overlay:focus {
&__expire-timer {
display: flex;
flex-direction: row;
align-items: center;
margin: 0 16px 16px 16px;

View File

@ -10,6 +10,7 @@ export type ConfigKeyType =
| 'desktop.announcementGroup'
| 'desktop.calling.audioLevelForSpeaking'
| 'desktop.cdsi'
| 'desktop.cdsi.beta'
| 'desktop.cdsi.returnAcisWithoutUaks'
| 'desktop.cdsi.mirroring'
| 'desktop.clientExpiration'

View File

@ -380,7 +380,10 @@ export const GroupCallRemoteParticipants: React.FC<PropsType> = ({
break;
}
setGroupCallVideoRequest(videoRequest, gridParticipantHeight);
setGroupCallVideoRequest(
videoRequest,
clamp(gridParticipantHeight, 0, MAX_FRAME_HEIGHT)
);
}, [
devicePixelRatio,
gridParticipantHeight,

View File

@ -584,12 +584,12 @@ export const StoryViewer = ({
/>
)}
<div className="StoryViewer__meta--title">
{group
? i18n('Stories__from-to-group', {
name: title,
group: group.title,
})
: title}
{(group &&
i18n('Stories__from-to-group', {
name: isMe ? i18n('you') : title,
group: group.title,
})) ||
(isMe ? i18n('you') : title)}
</div>
<MessageTimestamp
i18n={i18n}

View File

@ -2065,11 +2065,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const conversation = window.ConversationController.get(conversationId)!;
const idLog = conversation.idForLogging();
const idLog = `handleDataMessage/${conversation.idForLogging()} ${message.idForLogging()}`;
await conversation.queueJob('handleDataMessage', async () => {
log.info(
`handleDataMessage/${idLog}: processing message ${message.idForLogging()}`
);
log.info(`${idLog}: starting processing in queue`);
if (
isStory(message.attributes) &&
@ -2078,7 +2076,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
})
) {
log.info(
`handleDataMessage/${idLog}: dropping story from !accepted`,
`${idLog}: dropping story from !accepted`,
this.getSenderIdentifier()
);
confirm();
@ -2090,13 +2088,10 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.getSenderIdentifier()
)?.attributes;
if (inMemoryMessage) {
log.info(
`handleDataMessage/${idLog}: cache hit`,
this.getSenderIdentifier()
);
log.info(`${idLog}: cache hit`, this.getSenderIdentifier());
} else {
log.info(
`handleDataMessage/${idLog}: duplicate check db lookup needed`,
`${idLog}: duplicate check db lookup needed`,
this.getSenderIdentifier()
);
}
@ -2112,17 +2107,14 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
this.attributes.storyDistributionListId));
if (isDuplicateMessage) {
log.warn(
`handleDataMessage/${idLog}: Received duplicate message`,
this.idForLogging()
);
log.warn(`${idLog}: Received duplicate message`, this.idForLogging());
confirm();
return;
}
if (type === 'outgoing') {
if (isUpdate && existingMessage) {
log.info(
`handleDataMessage/${idLog}: Updating message ${message.idForLogging()} with received transcript`
`${idLog}: Updating message ${message.idForLogging()} with received transcript`
);
const toUpdate = window.MessageController.register(
@ -2198,7 +2190,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
if (isUpdate) {
log.warn(
`handleDataMessage/${idLog}: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.`
`${idLog}: Received update transcript, but no existing entry for message ${message.idForLogging()}. Dropping.`
);
confirm();
@ -2206,7 +2198,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
}
if (existingMessage) {
log.warn(
`handleDataMessage/${idLog}: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.`
`${idLog}: Received duplicate transcript for message ${message.idForLogging()}, but it was not an update transcript. Dropping.`
);
confirm();
@ -2273,7 +2265,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
} catch (error) {
const errorText = error && error.stack ? error.stack : error;
log.error(
`handleDataMessage/${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}`
`${idLog}: Failed to process group update as part of message ${message.idForLogging()}: ${errorText}`
);
throw error;
}
@ -2300,7 +2292,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
(sourceUuid && window.storage.blocked.isUuidBlocked(sourceUuid));
if (isBlocked) {
log.info(
`handleDataMessage/${idLog}: Dropping message from blocked sender. hasGroupV2Prop: ${hasGroupV2Prop}`
`${idLog}: Dropping message from blocked sender. hasGroupV2Prop: ${hasGroupV2Prop}`
);
confirm();
@ -2320,7 +2312,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
(sourceUuid && !conversation.hasMember(new UUID(sourceUuid))))
) {
log.warn(
`Received message destined for group ${conversation.idForLogging()}, which we or the sender are not a part of. Dropping.`
`${idLog}: Received message destined for group, which we or the sender are not a part of. Dropping.`
);
confirm();
return;
@ -2396,7 +2388,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (initialMessage.storyContext && !storyQuote) {
log.warn(
`handleDataMessage/${idLog}: Received storyContext message but no matching story. Dropping.`
`${idLog}: Received storyContext message but no matching story. Dropping.`
);
confirm();
@ -2518,7 +2510,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
hash = computeHash(loadedAttachment.data);
}
} catch (err) {
log.info('handleDataMessage: group avatar download failed');
log.info(`${idLog}: group avatar download failed`);
}
}
@ -2558,7 +2550,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
pendingGroupUpdate.avatarUpdated = true;
} else {
log.info(
'handleDataMessage: Group avatar hash matched; not replacing group avatar'
`${idLog}: Group avatar hash matched; not replacing group avatar`
);
}
@ -2588,7 +2580,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (!inGroup) {
const senderString = sender ? sender.idForLogging() : null;
log.info(
`Got 'left' message from someone not in group: ${senderString}. Dropping.`
`${idLog}: Got 'left' message from someone not in group: ${senderString}. Dropping.`
);
return;
}
@ -2614,9 +2606,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
// message.set call and after GroupV1 processing to make sure all possible
// properties are set before we determine that a message is empty.
if (message.isEmpty()) {
log.info(
`handleDataMessage: Dropping empty message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
);
log.info(`${idLog}: Dropping empty message`);
confirm();
return;
}
@ -2650,7 +2640,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
log.info('Incoming expirationTimerUpdate changed timer', {
id: conversation.idForLogging(),
expireTimer: dataMessage.expireTimer || 'disabled',
source: 'handleDataMessage/expirationTimerUpdate',
source: idLog,
});
conversation.set({
expireTimer: dataMessage.expireTimer,
@ -2668,7 +2658,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
receivedAtMS: message.get('received_at_ms'),
sentAt: message.get('sent_at'),
fromGroupUpdate: isGroupUpdate(message.attributes),
reason: `handleDataMessage(${this.idForLogging()})`,
reason: idLog,
});
} else if (
// We won't turn off timers for these kinds of messages:
@ -2680,7 +2670,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
receivedAt: message.get('received_at'),
receivedAtMS: message.get('received_at_ms'),
sentAt: message.get('sent_at'),
reason: `handleDataMessage(${this.idForLogging()})`,
reason: idLog,
});
}
}
@ -2714,7 +2704,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
!message.isValidTapToView()
) {
log.warn(
`Received tap to view message ${message.idForLogging()} with invalid data. Erasing contents.`
`${idLog}: Received tap to view message with invalid data. Erasing contents.`
);
message.set({
isTapToViewInvalid: true,
@ -2759,7 +2749,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
);
const { messaging } = window.textsecure;
if (!messaging) {
throw new Error('handleDataMessage: messaging is not available');
throw new Error(`${idLog}: messaging is not available`);
}
const response = await messaging.server.getBoostBadgesFromServer(
userLanguages
@ -2771,7 +2761,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const badge = boostBadgesByLevel[level];
if (!badge) {
log.error(
`handleDataMessage: gift badge with level ${level} not found on server`
`${idLog}: gift badge with level ${level} not found on server`
);
} else {
await window.reduxActions.badges.updateOrCreate([badge]);
@ -2806,7 +2796,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (window.attachmentDownloadQueue) {
window.attachmentDownloadQueue.unshift(message);
log.info(
'Adding to attachmentDownloadQueue',
`${idLog}: Adding to attachmentDownloadQueue`,
message.get('sent_at')
);
} else {
@ -2817,19 +2807,11 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const isFirstRun = true;
await this.modifyTargetMessage(conversation, isFirstRun);
log.info(
'handleDataMessage: Batching save for',
message.get('sent_at')
);
log.info(`${idLog}: Batching save`);
this.saveAndNotify(conversation, confirm);
} catch (error) {
const errorForLog = error && error.stack ? error.stack : error;
log.error(
'handleDataMessage',
message.idForLogging(),
'error:',
errorForLog
);
log.error(`${idLog}: error:`, errorForLog);
throw error;
}
});

View File

@ -281,21 +281,21 @@ export class EmojiCompletion {
range.collapse(true);
// if we can, position the popper at the beginning of the emoji text (:word)
const endContainerTextContent = range.endContainer.textContent;
const startOfEmojiText = endContainerTextContent?.lastIndexOf(':');
const textBeforeCursor = range.endContainer.textContent?.slice(
0,
range.startOffset
);
const startOfEmojiText = textBeforeCursor?.lastIndexOf(':');
if (
endContainerTextContent &&
textBeforeCursor &&
isNumber(startOfEmojiText) &&
startOfEmojiText !== -1
) {
range.setStart(
range.endContainer,
range.endOffset -
(endContainerTextContent.length - startOfEmojiText)
);
range.setStart(range.endContainer, startOfEmojiText);
} else {
log.warn(
`Could not find the beginning of the emoji word to be completed. startOfEmojiText=${startOfEmojiText}, endContainerTextContent.length=${endContainerTextContent?.length}, range.offsets=${range.startOffset}-${range.endOffset}`
`Could not find the beginning of the emoji word to be completed. startOfEmojiText=${startOfEmojiText}, textBeforeCursor.length=${textBeforeCursor?.length}, range.offsets=${range.startOffset}-${range.endOffset}`
);
}
return range.getClientRects()[0];

View File

@ -28,7 +28,8 @@ export function setIsInitialSync(newValue: boolean): void {
async function updateConversationFromContactSync(
conversation: ConversationModel,
details: ModifiedContactDetails,
receivedAtCounter: number
receivedAtCounter: number,
sentAt: number
): Promise<void> {
const { writeNewAttachmentData, deleteAttachmentData, doesAttachmentExist } =
window.Signal.Migrations;
@ -67,7 +68,7 @@ async function updateConversationFromContactSync(
receivedAt: receivedAtCounter,
fromSync: true,
isInitialSync,
reason: 'contact sync',
reason: `contact sync (sent=${sentAt})`,
});
window.Whisper.events.trigger('incrementProgress');
@ -79,6 +80,7 @@ async function doContactSync({
contacts,
complete,
receivedAtCounter,
sentAt,
}: ContactSyncEvent): Promise<void> {
// iOS sets `syncMessage.contacts.complete` flag to `true` unconditionally
// and so we have to employ tricks to figure out whether the sync is full or
@ -93,7 +95,7 @@ async function doContactSync({
window.storage.user.getUuid()?.toString()
);
const logId = `doContactSync(${receivedAtCounter}, isFullSync=${isFullSync})`;
const logId = `doContactSync(sent=${sentAt}, receivedAt=${receivedAtCounter}, isFullSync=${isFullSync})`;
log.info(`${logId}: got ${contacts.length} contacts`);
const updatedConversations = new Set<ConversationModel>();
@ -130,7 +132,8 @@ async function doContactSync({
await updateConversationFromContactSync(
conversation,
details,
receivedAtCounter
receivedAtCounter,
sentAt
);
updatedConversations.add(conversation);
@ -187,6 +190,8 @@ async function doContactSync({
}
export async function onContactSync(ev: ContactSyncEvent): Promise<void> {
log.info(`onContactSync(${ev.receivedAtCounter}): queueing sync`);
log.info(
`onContactSync(sent=${ev.sentAt}, receivedAt=${ev.receivedAtCounter}): queueing sync`
);
await queue.add(() => doContactSync(ev));
}

View File

@ -3071,7 +3071,8 @@ export default class MessageReceiver
const contactSync = new ContactSyncEvent(
Array.from(contactBuffer),
Boolean(contacts.complete),
envelope.receivedAtCounter
envelope.receivedAtCounter,
envelope.timestamp
);
await this.dispatchAndWait(contactSync);

View File

@ -77,7 +77,8 @@ export class ContactSyncEvent extends Event {
constructor(
public readonly contacts: ReadonlyArray<ModifiedContactDetails>,
public readonly complete: boolean,
public readonly receivedAtCounter: number
public readonly receivedAtCounter: number,
public readonly sentAt: number
) {
super('contactSync');
}

View File

@ -7,6 +7,7 @@ import type { UUIDStringType } from '../types/UUID';
import * as log from '../logging/log';
import { isEnabled } from '../RemoteConfig';
import { isDirectConversation, isMe } from './whatTypeOfConversation';
import { isBeta } from './version';
export async function getUuidsForE164s(
server: Pick<WebAPIType, 'cdsLookup'>,
@ -39,7 +40,10 @@ export async function getUuidsForE164s(
}
const returnAcisWithoutUaks = isEnabled('desktop.cdsi.returnAcisWithoutUaks');
const isCDSI = isEnabled('desktop.cdsi');
const isCDSI =
isEnabled('desktop.cdsi') ||
(isBeta(window.getVersion()) && isEnabled('desktop.cdsi.beta'));
const isMirroring = isEnabled('desktop.cdsi.mirroring');
log.info(

View File

@ -7233,10 +7233,10 @@ electron-window@^0.8.0:
dependencies:
is-electron-renderer "^2.0.0"
electron@20.1.0:
version "20.1.0"
resolved "https://registry.yarnpkg.com/electron/-/electron-20.1.0.tgz#2de079adc551dadc21f11d12a37c70873b9ffb40"
integrity sha512-gzl6fdZe5g0qmzCC6Ejxa1Oa8eqUSxs4+QLtrM7SyEVp+mEPJAOoDe0xD8ayRQqeXTBxLK1LFrKtc4c98iufsg==
electron@20.1.3:
version "20.1.3"
resolved "https://registry.yarnpkg.com/electron/-/electron-20.1.3.tgz#8a4e3f6945fa7ed06ba54d0f987737b0e057ceb4"
integrity sha512-DXBHzAwcpCor9MrxG9QA3Zt0sNcQbJ8ZJCYTC6xpuPe5wugBa6RF3hXqDUYdD2yOCUhjLbD3VASWn0+5LdYT3g==
dependencies:
"@electron/get" "^1.14.1"
"@types/node" "^16.11.26"