Merge pull request #2325 from oxen-io/ask-user-before-enabling-pruning

Ask user before enabling pruning
pull/2465/head v1.8.5
Audric Ackermann 3 years ago committed by GitHub
commit 7f8400f8c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -137,6 +137,13 @@
"typingIndicatorsSettingDescription": "See and share when messages are being typed (applies to all sessions).",
"typingIndicatorsSettingTitle": "Typing Indicators",
"zoomFactorSettingTitle": "Zoom Factor",
"pruneSettingTitle": "Prune Old Open Group Messages",
"pruneSettingDescription": "Prune messages older than 6 months from Open Groups on start",
"pruningOpengroupDialogTitle": "Open group pruning",
"pruningOpengroupDialogMessage": "Pruning old open group messages improves performance. Enable pruning for open group messages older than 6 months?",
"pruningOpengroupDialogSubMessage": "You can change this setting in the Session settings menu",
"enable": "Enable",
"keepDisabled": "Keep disabled",
"notificationSettingsDialog": "When messages arrive, display notifications that reveal...",
"disableNotifications": "Mute notifications",
"nameAndMessage": "Name and content",

@ -86,6 +86,28 @@ window.getStartInTray = async () => {
});
};
window.getOpengroupPruning = async () => {
return new Promise(resolve => {
ipc.once('get-opengroup-pruning-response', (_event, value) => {
resolve(value);
});
ipc.send('get-opengroup-pruning');
});
};
window.setOpengroupPruning = async opengroupPruning =>
new Promise((resolve, reject) => {
ipc.once('set-opengroup-pruning-response', (_event, error) => {
if (error) {
reject(error);
return;
}
resolve();
return;
});
ipc.send('set-opengroup-pruning', opengroupPruning);
});
window._ = require('lodash');
// We never do these in our code, so we'll prevent it everywhere

@ -551,7 +551,9 @@ label {
&-main-message {
font-size: $session-font-md;
line-height: 1.5;
}
&-sub-message {
text-align: center;
margin-top: 20px;

@ -127,6 +127,12 @@ export const SessionConfirm = (props: SessionConfirmDialogProps) => {
</div>
<div className="session-modal__button-group">
<SessionButton
text={okText}
buttonColor={okTheme}
onClick={onClickOkHandler}
dataTestId="session-confirm-ok-button"
/>
{!hideCancel && (
<SessionButton
text={cancelText}
@ -135,12 +141,6 @@ export const SessionConfirm = (props: SessionConfirmDialogProps) => {
dataTestId="session-confirm-cancel-button"
/>
)}
<SessionButton
text={okText}
buttonColor={okTheme}
onClick={onClickOkHandler}
dataTestId="session-confirm-ok-button"
/>
</div>
</SessionWrapperModal>
);

@ -30,7 +30,11 @@ import { cleanUpOldDecryptedMedias } from '../../session/crypto/DecryptedAttachm
import { DURATION } from '../../session/constants';
import { conversationChanged, conversationRemoved } from '../../state/ducks/conversations';
import { editProfileModal, onionPathModal } from '../../state/ducks/modalDialog';
import {
editProfileModal,
onionPathModal,
updateConfirmModal,
} from '../../state/ducks/modalDialog';
import { uploadOurAvatar } from '../../interactions/conversationInteractions';
import { ModalContainer } from '../dialog/ModalContainer';
import { debounce, isEmpty, isString } from 'lodash';
@ -54,6 +58,9 @@ import { getLatestDesktopReleaseFileToFsV2 } from '../../session/apis/file_serve
import { ipcRenderer } from 'electron';
import { UserUtils } from '../../session/utils';
import { Storage } from '../../util/storage';
import { SettingsKey } from '../../data/settings-key';
const Section = (props: { type: SectionType }) => {
const ourNumber = useSelector(getOurNumber);
const unreadMessageCount = useSelector(getUnreadMessageCount);
@ -251,6 +258,8 @@ const doAppStartUp = () => {
void loadDefaultRooms();
debounce(triggerAvatarReUploadIfNeeded, 200);
void askEnablingOpengroupPruningIfNeeded();
};
const CallContainer = () => {
@ -279,6 +288,36 @@ async function fetchReleaseFromFSAndUpdateMain() {
}
}
async function askEnablingOpengroupPruningIfNeeded() {
if (Storage.get(SettingsKey.settingsOpengroupPruning) === undefined) {
const setSettingsAndCloseDialog = async (valueToSetPruningTo: boolean) => {
window.setSettingValue(SettingsKey.settingsOpengroupPruning, valueToSetPruningTo);
await window.setOpengroupPruning(valueToSetPruningTo);
window.inboxStore?.dispatch(updateConfirmModal(null));
};
window.inboxStore?.dispatch(
updateConfirmModal({
onClickOk: async () => {
await setSettingsAndCloseDialog(true);
},
onClickClose: async () => {
await setSettingsAndCloseDialog(false);
},
onClickCancel: async () => {
await setSettingsAndCloseDialog(false);
},
title: window.i18n('pruningOpengroupDialogTitle'),
message: window.i18n('pruningOpengroupDialogMessage'),
messageSub: window.i18n('pruningOpengroupDialogSubMessage'),
okText: window.i18n('enable'),
cancelText: window.i18n('keepDisabled'),
})
);
return;
}
// otherwise nothing to do. the settings is already on or off, but as expected by the user
}
/**
* ActionsPanel is the far left banner (not the left pane).
* The panel with buttons to switch between the message/contact/settings/theme views

@ -4,6 +4,7 @@ import { useDispatch, useSelector } from 'react-redux';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
import { createOrUpdateItem, hasLinkPreviewPopupBeenDisplayed } from '../../../data/data';
import { SettingsKey } from '../../../data/settings-key';
import { ToastUtils } from '../../../session/utils';
import { updateConfirmModal } from '../../../state/ducks/modalDialog';
import { toggleAudioAutoplay } from '../../../state/ducks/userConfig';
@ -15,8 +16,8 @@ import { SessionSettingButtonItem, SessionToggleWithDescription } from '../Sessi
import { ZoomingSessionSlider } from '../ZoomingSessionSlider';
async function toggleLinkPreviews() {
const newValue = !window.getSettingValue('link-preview-setting');
window.setSettingValue('link-preview-setting', newValue);
const newValue = !window.getSettingValue(SettingsKey.settingsLinkPreview);
window.setSettingValue(SettingsKey.settingsLinkPreview, newValue);
if (!newValue) {
await createOrUpdateItem({ id: hasLinkPreviewPopupBeenDisplayed, value: false });
} else {
@ -35,7 +36,7 @@ async function toggleStartInTray() {
const newValue = !(await window.getStartInTray());
// make sure to write it here too, as this is the value used on the UI to mark the toggle as true/false
window.setSettingValue('start-in-tray-setting', newValue);
window.setSettingValue(SettingsKey.settingsStartInTray, newValue);
await window.setStartInTray(newValue);
if (!newValue) {
ToastUtils.pushRestartNeeded();
@ -45,11 +46,6 @@ async function toggleStartInTray() {
}
}
const settingsMenuBar = 'hide-menu-bar';
const settingsSpellCheck = 'spell-check';
const settingsLinkPreview = 'link-preview-setting';
const settingsStartInTray = 'start-in-tray-setting';
export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null }) => {
const dispatch = useDispatch();
const forceUpdate = useUpdate();
@ -57,17 +53,17 @@ export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null
if (props.hasPassword !== null) {
const isHideMenuBarActive =
window.getSettingValue(settingsMenuBar) === undefined
window.getSettingValue(SettingsKey.settingsMenuBar) === undefined
? true
: window.getSettingValue(settingsMenuBar);
: window.getSettingValue(SettingsKey.settingsMenuBar);
const isSpellCheckActive =
window.getSettingValue(settingsSpellCheck) === undefined
window.getSettingValue(SettingsKey.settingsSpellCheck) === undefined
? true
: window.getSettingValue(settingsSpellCheck);
: window.getSettingValue(SettingsKey.settingsSpellCheck);
const isLinkPreviewsOn = Boolean(window.getSettingValue(settingsLinkPreview));
const isStartInTrayActive = Boolean(window.getSettingValue(settingsStartInTray));
const isLinkPreviewsOn = Boolean(window.getSettingValue(SettingsKey.settingsLinkPreview));
const isStartInTrayActive = Boolean(window.getSettingValue(SettingsKey.settingsStartInTray));
return (
<>
@ -119,6 +115,7 @@ export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null
description={window.i18n('audioMessageAutoplayDescription')}
active={audioAutoPlay}
/>
<ZoomingSessionSlider />
<SessionSettingButtonItem
title={window.i18n('surveyTitle')}

@ -3,7 +3,7 @@ import { useDispatch, useSelector } from 'react-redux';
// tslint:disable-next-line: no-submodule-imports
import useUpdate from 'react-use/lib/useUpdate';
import { SettingsKey } from '../../../data/settings-key';
import { CallManager } from '../../../session/utils';
import { CallManager, ToastUtils } from '../../../session/utils';
import { sessionPassword, updateConfirmModal } from '../../../state/ducks/modalDialog';
import { toggleMessageRequests } from '../../../state/ducks/userConfig';
import { getHideMessageRequestBanner } from '../../../state/selectors/userConfig';
@ -50,13 +50,28 @@ function displayPasswordModal(
);
}
async function toggleOpengroupPruning() {
try {
const newValue = !(await window.getOpengroupPruning());
// make sure to write it here too, as this is the value used on the UI to mark the toggle as true/false
window.setSettingValue(SettingsKey.settingsOpengroupPruning, newValue);
await window.setOpengroupPruning(newValue);
ToastUtils.pushRestartNeeded();
} catch (e) {
window.log.warn('toggleOpengroupPruning change error:', e);
}
}
export const SettingsCategoryPrivacy = (props: {
hasPassword: boolean | null;
onPasswordUpdated: (action: string) => void;
}) => {
const forceUpdate = useUpdate();
const dispatch = useDispatch();
const isOpengroupPruningEnabled = Boolean(
window.getSettingValue(SettingsKey.settingsOpengroupPruning)
);
if (props.hasPassword !== null) {
return (
<>
@ -117,6 +132,15 @@ export const SettingsCategoryPrivacy = (props: {
description={window.i18n('hideRequestBannerDescription')}
active={useSelector(getHideMessageRequestBanner)}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleOpengroupPruning();
forceUpdate();
}}
title={window.i18n('pruneSettingTitle')}
description={window.i18n('pruneSettingDescription')}
active={isOpengroupPruningEnabled}
/>
{!props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('setAccountPasswordTitle')}

@ -2,4 +2,19 @@ const settingsReadReceipt = 'read-receipt-setting';
const settingsTypingIndicator = 'typing-indicators-setting';
const settingsAutoUpdate = 'auto-update';
export const SettingsKey = { settingsReadReceipt, settingsTypingIndicator, settingsAutoUpdate };
const settingsMenuBar = 'hide-menu-bar';
const settingsSpellCheck = 'spell-check';
const settingsLinkPreview = 'link-preview-setting';
const settingsStartInTray = 'start-in-tray-setting';
const settingsOpengroupPruning = 'prune-setting';
export const SettingsKey = {
settingsReadReceipt,
settingsTypingIndicator,
settingsAutoUpdate,
settingsMenuBar,
settingsSpellCheck,
settingsLinkPreview,
settingsStartInTray,
settingsOpengroupPruning,
};

@ -753,6 +753,8 @@ async function showMainWindow(sqlKey: string, passwordAttempt = false) {
appStartInitialSpellcheckSetting = await getSpellCheckSetting();
sqlChannels.initializeSqlChannel();
sqlNode.cleanUpOldOpengroups();
await initAttachmentsChannel({
userDataPath,
});
@ -926,6 +928,7 @@ ipc.on('password-window-login', async (event, passPhrase) => {
sendResponse(localisedError || 'Invalid password');
}
});
ipc.on('start-in-tray-on-start', (event, newValue) => {
try {
userConfig.set('startInTray', newValue);
@ -954,6 +957,24 @@ ipc.on('get-start-in-tray', event => {
}
});
ipc.on('get-opengroup-pruning', event => {
try {
const val = userConfig.get('opengroupPruning');
event.sender.send('get-opengroup-pruning-response', val);
} catch (e) {
event.sender.send('get-opengroup-pruning-response', false);
}
});
ipc.on('set-opengroup-pruning', (event, newValue) => {
try {
userConfig.set('opengroupPruning', newValue);
event.sender.send('set-opengroup-pruning-response', null);
} catch (e) {
event.sender.send('set-opengroup-pruning-response', e);
}
});
ipc.on('set-password', async (event, passPhrase, oldPhrase) => {
const sendResponse = (response: string | undefined) => {
event.sender.send('set-password-response', response);

@ -1551,6 +1551,7 @@ async function initializeSql({
console.info('total message count before cleaning: ', getMessageCount());
console.info('total conversation count before cleaning: ', getConversationCount());
cleanUpOldOpengroups();
cleanUpUnusedNodeForKeyEntries();
printDbStats();
@ -3411,11 +3412,26 @@ function cleanUpOldOpengroups() {
console.info('cleanUpOldOpengroups: ourNumber is not set');
return;
}
const pruneSetting = getItemById('prune-setting')?.value;
if (pruneSetting === undefined) {
console.info(
'Prune settings is undefined, skipping cleanUpOldOpengroups but we will need to ask user'
);
return;
}
if (!pruneSetting) {
console.info('Prune setting not enabled, skipping cleanUpOldOpengroups');
return;
}
const v2Convos = getAllOpenGroupV2Conversations();
if (!v2Convos || !v2Convos.length) {
console.info('cleanUpOldOpengroups: v2Convos is empty');
return;
}
// For each opengroups, if it has more than 1000 messages, we remove all the messages older than 2 months.
// So this does not limit the size of opengroup history to 1000 messages but to 2 months.
// This is the only way we can cleanup conversations objects from users which just sent messages a while ago and with whom we never interacted.
@ -3436,20 +3452,20 @@ function cleanUpOldOpengroups() {
if (messagesInConvoBefore >= maxMessagePerOpengroupConvo) {
const minute = 1000 * 60;
const sixMonths = minute * 60 * 24 * 30 * 6;
const messagesTimestampToRemove = Date.now() - sixMonths;
const limitTimestamp = Date.now() - sixMonths;
const countToRemove = assertGlobalInstance()
.prepare(
`SELECT count(*) from ${MESSAGES_TABLE} WHERE serverTimestamp <= $serverTimestamp AND conversationId = $conversationId;`
)
.get({ conversationId: convoId, serverTimestamp: Date.now() - sixMonths })['count(*)'];
.get({ conversationId: convoId, serverTimestamp: limitTimestamp })['count(*)'];
const start = Date.now();
assertGlobalInstance()
.prepare(
`
DELETE FROM ${MESSAGES_TABLE} WHERE serverTimestamp <= $serverTimestamp AND conversationId = $conversationId`
DELETE FROM ${MESSAGES_TABLE} WHERE serverTimestamp <= $serverTimestamp AND conversationId = $conversationId`
)
.run({ conversationId: convoId, serverTimestamp: messagesTimestampToRemove }); // delete messages older than sixMonths
.run({ conversationId: convoId, serverTimestamp: limitTimestamp }); // delete messages older than 6 months ago.
const messagesInConvoAfter = getMessagesCountByConversation(convoId);
console.info(
@ -3680,6 +3696,7 @@ export const sqlNode = {
getPubkeysInPublicConversation,
getAllGroupsInvolvingId,
removeAllConversations,
cleanUpOldOpengroups,
searchConversations,
searchMessages,

@ -7,6 +7,7 @@ export type LocalizerKeys =
| 'startedACall'
| 'mainMenuWindow'
| 'unblocked'
| 'keepDisabled'
| 'userAddedToModerators'
| 'to'
| 'sent'
@ -14,7 +15,9 @@ export type LocalizerKeys =
| 'closedGroupInviteFailMessage'
| 'noContactsForGroup'
| 'linkVisitWarningMessage'
| 'messageRequestAcceptedOurs'
| 'anonymous'
| 'youHaveANewFriendRequest'
| 'viewMenuZoomOut'
| 'dialogClearAllDataDeletionFailedDesc'
| 'timerOption_10_seconds_abbreviated'
@ -22,9 +25,11 @@ export type LocalizerKeys =
| 'connectToServerFail'
| 'disableNotifications'
| 'publicChatExists'
| 'noMediaUntilApproved'
| 'passwordViewTitle'
| 'joinOpenGroupAfterInvitationConfirmationTitle'
| 'notificationMostRecentFrom'
| 'messageRequestAccepted'
| 'timerOption_5_minutes'
| 'linkPreviewsConfirmMessage'
| 'notificationMostRecent'
@ -44,7 +49,6 @@ export type LocalizerKeys =
| 'viewMenuToggleDevTools'
| 'fileSizeWarning'
| 'openGroupURL'
| 'hideRequestBannerDescription'
| 'hideMenuBarDescription'
| 'pickClosedGroupMember'
| 'ByUsingThisService...'
@ -54,6 +58,7 @@ export type LocalizerKeys =
| 'typingAlt'
| 'orJoinOneOfThese'
| 'members'
| 'noMessageRequestsPending'
| 'sendRecoveryPhraseMessage'
| 'timerOption_1_hour'
| 'youGotKickedFromGroup'
@ -68,8 +73,10 @@ export type LocalizerKeys =
| 'addModerators'
| 'sessionMessenger'
| 'today'
| 'mustBeApproved'
| 'appMenuHideOthers'
| 'sendFailed'
| 'openMessageRequestInbox'
| 'enterPassword'
| 'enterSessionIDOfRecipient'
| 'dialogClearAllDataDeletionFailedMultiple'
@ -81,6 +88,7 @@ export type LocalizerKeys =
| 'requestsSubtitle'
| 'closedGroupInviteSuccessTitle'
| 'accept'
| 'hideBanner'
| 'setPasswordTitle'
| 'editMenuUndo'
| 'pinConversation'
@ -94,6 +102,7 @@ export type LocalizerKeys =
| 'autoUpdateNewVersionInstructions'
| 'appMenuUnhide'
| 'timerOption_30_minutes_abbreviated'
| 'pruneSettingDescription'
| 'voiceMessage'
| 'changePasswordTitle'
| 'copyMessage'
@ -101,12 +110,11 @@ export type LocalizerKeys =
| 'deleteJustForMe'
| 'changeAccountPasswordTitle'
| 'onionPathIndicatorDescription'
| 'timestamp_s'
| 'pruningOpengroupDialogSubMessage'
| 'mediaPermissionsTitle'
| 'replyingToMessage'
| 'welcomeToYourSession'
| 'editMenuCopy'
| 'timestamp_m'
| 'leftTheGroup'
| 'timerOption_30_minutes'
| 'nameOnly'
@ -116,6 +124,7 @@ export type LocalizerKeys =
| 'inviteContacts'
| 'callMediaPermissionsTitle'
| 'blocked'
| 'hideRequestBannerDescription'
| 'noBlockedContacts'
| 'leaveGroupConfirmation'
| 'banUserAndDeleteAll'
@ -197,6 +206,7 @@ export type LocalizerKeys =
| 'viewMenuResetZoom'
| 'startInTrayDescription'
| 'groupNamePlaceholder'
| 'messageRequestPending'
| 'stagedPreviewThumbnail'
| 'helpUsTranslateSession'
| 'editMenuDeleteGroup'
@ -208,6 +218,7 @@ export type LocalizerKeys =
| 'closedGroupInviteFailMessagePlural'
| 'noAudioInputFound'
| 'timerOption_10_seconds'
| 'openMessageRequestInboxDescription'
| 'noteToSelf'
| 'failedToAddAsModerator'
| 'disabledDisappearingMessages'
@ -219,7 +230,6 @@ export type LocalizerKeys =
| 'displayName'
| 'invalidSessionId'
| 'audioPermissionNeeded'
| 'timestamp_h'
| 'add'
| 'messageRequests'
| 'show'
@ -228,6 +238,7 @@ export type LocalizerKeys =
| 'goToSupportPage'
| 'passwordsDoNotMatch'
| 'createClosedGroupNamePrompt'
| 'pruningOpengroupDialogMessage'
| 'audioMessageAutoplayDescription'
| 'leaveAndRemoveForEveryone'
| 'previewThumbnail'
@ -236,9 +247,9 @@ export type LocalizerKeys =
| 'editMenuDeleteContact'
| 'hideMenuBarTitle'
| 'imageCaptionIconAlt'
| 'clearAll'
| 'sendRecoveryPhraseTitle'
| 'multipleJoinedTheGroup'
| 'messageRequestAcceptedOursNoName'
| 'databaseError'
| 'resend'
| 'copiedToClipboard'
@ -248,6 +259,7 @@ export type LocalizerKeys =
| 'unableToLoadAttachment'
| 'cameraPermissionNeededTitle'
| 'editMenuRedo'
| 'hideRequestBanner'
| 'changeNicknameMessage'
| 'close'
| 'deleteMessageQuestion'
@ -258,6 +270,7 @@ export type LocalizerKeys =
| 'getStarted'
| 'unblockUser'
| 'blockUser'
| 'clearAllConfirmationTitle'
| 'trustThisContactDialogTitle'
| 'received'
| 'trimDatabaseConfirmationBody'
@ -276,6 +289,7 @@ export type LocalizerKeys =
| 'timerOption_6_hours_abbreviated'
| 'timerOption_1_week_abbreviated'
| 'timerSetTo'
| 'enable'
| 'notificationSubtitle'
| 'youChangedTheTimer'
| 'updatedTheGroup'
@ -288,8 +302,10 @@ export type LocalizerKeys =
| 'noSearchResults'
| 'changeNickname'
| 'userUnbanned'
| 'respondingToRequestWarning'
| 'error'
| 'clearAllData'
| 'pruningOpengroupDialogTitle'
| 'contactAvatarAlt'
| 'disappearingMessages'
| 'autoUpdateNewVersionTitle'
@ -328,6 +344,7 @@ export type LocalizerKeys =
| 'markAllAsRead'
| 'failedResolveOns'
| 'showDebugLog'
| 'declineRequestMessage'
| 'autoUpdateDownloadButtonLabel'
| 'dialogClearAllDataDeletionFailedTitleQuestion'
| 'autoUpdateDownloadInstructions'
@ -353,6 +370,7 @@ export type LocalizerKeys =
| 'learnMore'
| 'passwordCharacterError'
| 'autoUpdateSettingTitle'
| 'documentsEmptyState'
| 'deleteForEveryone'
| 'createSessionID'
| 'multipleLeftTheGroup'
@ -376,9 +394,11 @@ export type LocalizerKeys =
| 'callMediaPermissionsDialogContent'
| 'timerOption_1_day_abbreviated'
| 'about'
| 'clearAllConfirmationBody'
| 'ok'
| 'multipleKickedFromTheGroup'
| 'trimDatabase'
| 'clearAll'
| 'recoveryPhraseSavePromptMain'
| 'editMenuPaste'
| 'areYouSureDeleteDeviceOnly'
@ -421,7 +441,7 @@ export type LocalizerKeys =
| 'recoveryPhrase'
| 'newMessages'
| 'you'
| 'documentsEmptyState'
| 'pruneSettingTitle'
| 'unbanUser'
| 'notificationForConvo_mentions_only'
| 'trustThisContactDialogDescription'
@ -429,22 +449,4 @@ export type LocalizerKeys =
| 'searchFor...'
| 'joinedTheGroup'
| 'editGroupName'
| 'trimDatabase'
| 'trimDatabaseDescription'
| 'trimDatabaseConfirmationBody'
| 'respondingToRequestWarning'
| 'messageRequestPending'
| 'messageRequestAccepted'
| 'messageRequestAcceptedOurs'
| 'messageRequestAcceptedOursNoName'
| 'declineRequestMessage'
| 'openMessageRequestInbox'
| 'hideRequestBanner'
| 'noMessageRequestsPending'
| 'noMediaUntilApproved'
| 'mustBeApproved'
| 'youHaveANewFriendRequest'
| 'clearAllConfirmationTitle'
| 'clearAllConfirmationBody'
| 'hideBanner'
| 'reportIssue';

@ -164,6 +164,10 @@ async function createAccount(identityKeyPair: any) {
// Enable typing indicators by default
await Storage.put(SettingsKey.settingsTypingIndicator, false);
// opengroups pruning in ON by default on new accounts, but you can change that from the settings
await Storage.put(SettingsKey.settingsOpengroupPruning, true);
await window.setOpengroupPruning(true);
await setLocalPubKey(pubKeyString);
}

2
ts/window.d.ts vendored

@ -91,6 +91,8 @@ declare global {
confirmationDialog: any;
setStartInTray: (val: boolean) => Promise<void>;
getStartInTray: () => Promise<boolean>;
getOpengroupPruning: () => Promise<boolean>;
setOpengroupPruning: (val: boolean) => Promise<void>;
closeAbout: () => void;
getAutoUpdateEnabled: () => boolean;
setAutoUpdateEnabled: (enabled: boolean) => void;

Loading…
Cancel
Save