Show What's New dialog in app via Help -> Go to release notes
This commit is contained in:
parent
3e38a4b761
commit
191bfee18c
14 changed files with 249 additions and 142 deletions
|
@ -865,6 +865,11 @@ function openJoinTheBeta() {
|
|||
}
|
||||
|
||||
function openReleaseNotes() {
|
||||
if (mainWindow && mainWindow.isVisible()) {
|
||||
mainWindow.webContents.send('show-release-notes');
|
||||
return;
|
||||
}
|
||||
|
||||
shell.openExternal(
|
||||
`https://github.com/signalapp/Signal-Desktop/releases/tag/v${app.getVersion()}`
|
||||
);
|
||||
|
|
|
@ -56,7 +56,7 @@ const {
|
|||
const {
|
||||
SystemTraySettingsCheckboxes,
|
||||
} = require('../../ts/components/conversation/SystemTraySettingsCheckboxes');
|
||||
const { WhatsNew } = require('../../ts/components/WhatsNew');
|
||||
const { WhatsNewLink } = require('../../ts/components/WhatsNewLink');
|
||||
|
||||
// State
|
||||
const {
|
||||
|
@ -338,7 +338,7 @@ exports.setup = (options = {}) => {
|
|||
StagedLinkPreview,
|
||||
DisappearingTimeDialog,
|
||||
SystemTraySettingsCheckboxes,
|
||||
WhatsNew,
|
||||
WhatsNewLink,
|
||||
};
|
||||
|
||||
const Roots = {
|
||||
|
|
|
@ -340,6 +340,13 @@ try {
|
|||
}
|
||||
});
|
||||
|
||||
ipc.on('show-release-notes', () => {
|
||||
const { showReleaseNotes } = window.Events;
|
||||
if (showReleaseNotes) {
|
||||
showReleaseNotes();
|
||||
}
|
||||
});
|
||||
|
||||
window.addSetupMenuItems = () => ipc.send('add-setup-menu-items');
|
||||
window.removeSetupMenuItems = () => ipc.send('remove-setup-menu-items');
|
||||
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { ContactModalStateType } from '../state/ducks/globalModals';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
|
||||
import { WhatsNewModal } from './WhatsNewModal';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
// ContactModal
|
||||
contactModalState?: ContactModalStateType;
|
||||
renderContactModal: () => JSX.Element;
|
||||
|
@ -13,9 +18,13 @@ type PropsType = {
|
|||
// SafetyNumberModal
|
||||
safetyNumberModalContactId?: string;
|
||||
renderSafetyNumber: () => JSX.Element;
|
||||
// WhatsNewModal
|
||||
isWhatsNewVisible: boolean;
|
||||
hideWhatsNewModal: () => unknown;
|
||||
};
|
||||
|
||||
export const GlobalModalContainer = ({
|
||||
i18n,
|
||||
// ContactModal
|
||||
contactModalState,
|
||||
renderContactModal,
|
||||
|
@ -25,6 +34,9 @@ export const GlobalModalContainer = ({
|
|||
// SafetyNumberModal
|
||||
safetyNumberModalContactId,
|
||||
renderSafetyNumber,
|
||||
// WhatsNewModal
|
||||
hideWhatsNewModal,
|
||||
isWhatsNewVisible,
|
||||
}: PropsType): JSX.Element | null => {
|
||||
if (safetyNumberModalContactId) {
|
||||
return renderSafetyNumber();
|
||||
|
@ -38,5 +50,9 @@ export const GlobalModalContainer = ({
|
|||
return renderProfileEditor();
|
||||
}
|
||||
|
||||
if (isWhatsNewVisible) {
|
||||
return <WhatsNewModal hideWhatsNewModal={hideWhatsNewModal} i18n={i18n} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactChild, ReactNode, useState } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { Modal } from './Modal';
|
||||
import { Intl, IntlComponentsType } from './Intl';
|
||||
import { Emojify } from './conversation/Emojify';
|
||||
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||
|
||||
export type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
};
|
||||
|
||||
type ReleaseNotesType = {
|
||||
date: Date;
|
||||
version: string;
|
||||
features: Array<{ key: string; components: IntlComponentsType }>;
|
||||
};
|
||||
|
||||
const renderText: RenderTextCallbackType = ({ key, text }) => (
|
||||
<Emojify key={key} text={text} />
|
||||
);
|
||||
|
||||
export const WhatsNew = ({ i18n }: PropsType): JSX.Element => {
|
||||
const [releaseNotes, setReleaseNotes] = useState<
|
||||
ReleaseNotesType | undefined
|
||||
>();
|
||||
|
||||
const viewReleaseNotes = () => {
|
||||
setReleaseNotes({
|
||||
date: new Date(window.getBuildCreation?.() || Date.now()),
|
||||
version: window.getVersion(),
|
||||
features: [
|
||||
{
|
||||
key: 'WhatsNew__v5.22',
|
||||
components: undefined,
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
let modalNode: ReactNode;
|
||||
if (releaseNotes) {
|
||||
let contentNode: ReactChild;
|
||||
if (releaseNotes.features.length === 1) {
|
||||
const { key, components } = releaseNotes.features[0];
|
||||
contentNode = (
|
||||
<p>
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id={key}
|
||||
renderText={renderText}
|
||||
components={components}
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
} else {
|
||||
contentNode = (
|
||||
<ul>
|
||||
{releaseNotes.features.map(({ key, components }) => (
|
||||
<li key={key}>
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id={key}
|
||||
renderText={renderText}
|
||||
components={components}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
modalNode = (
|
||||
<Modal
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
onClose={() => setReleaseNotes(undefined)}
|
||||
title={i18n('WhatsNew__modal-title')}
|
||||
>
|
||||
<>
|
||||
<span>
|
||||
{moment(releaseNotes.date).format('LL')} ·{' '}
|
||||
{releaseNotes.version}
|
||||
</span>
|
||||
{contentNode}
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{modalNode}
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="whatsNew"
|
||||
components={[
|
||||
<button className="WhatsNew" type="button" onClick={viewReleaseNotes}>
|
||||
{i18n('viewReleaseNotes')}
|
||||
</button>,
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
29
ts/components/WhatsNewLink.tsx
Normal file
29
ts/components/WhatsNewLink.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { Intl } from './Intl';
|
||||
|
||||
import { LocalizerType } from '../types/Util';
|
||||
|
||||
export type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
showWhatsNewModal: () => unknown;
|
||||
};
|
||||
|
||||
export const WhatsNewLink = (props: PropsType): JSX.Element => {
|
||||
const { i18n, showWhatsNewModal } = props;
|
||||
|
||||
return (
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id="whatsNew"
|
||||
components={[
|
||||
<button className="WhatsNew" type="button" onClick={showWhatsNewModal}>
|
||||
{i18n('viewReleaseNotes')}
|
||||
</button>,
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
89
ts/components/WhatsNewModal.tsx
Normal file
89
ts/components/WhatsNewModal.tsx
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React, { ReactChild } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { Modal } from './Modal';
|
||||
import { Intl, IntlComponentsType } from './Intl';
|
||||
import { Emojify } from './conversation/Emojify';
|
||||
import type { LocalizerType, RenderTextCallbackType } from '../types/Util';
|
||||
|
||||
export type PropsType = {
|
||||
hideWhatsNewModal: () => unknown;
|
||||
i18n: LocalizerType;
|
||||
};
|
||||
|
||||
type ReleaseNotesType = {
|
||||
date: Date;
|
||||
version: string;
|
||||
features: Array<{ key: string; components: IntlComponentsType }>;
|
||||
};
|
||||
|
||||
const renderText: RenderTextCallbackType = ({ key, text }) => (
|
||||
<Emojify key={key} text={text} />
|
||||
);
|
||||
|
||||
const releaseNotes: ReleaseNotesType = {
|
||||
date: new Date(window.getBuildCreation?.() || Date.now()),
|
||||
version: window.getVersion(),
|
||||
features: [
|
||||
{
|
||||
key: 'WhatsNew__v5.22',
|
||||
components: undefined,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const WhatsNewModal = ({
|
||||
i18n,
|
||||
hideWhatsNewModal,
|
||||
}: PropsType): JSX.Element => {
|
||||
let contentNode: ReactChild;
|
||||
|
||||
if (releaseNotes.features.length === 1) {
|
||||
const { key, components } = releaseNotes.features[0];
|
||||
contentNode = (
|
||||
<p>
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id={key}
|
||||
renderText={renderText}
|
||||
components={components}
|
||||
/>
|
||||
</p>
|
||||
);
|
||||
} else {
|
||||
contentNode = (
|
||||
<ul>
|
||||
{releaseNotes.features.map(({ key, components }) => (
|
||||
<li key={key}>
|
||||
<Intl
|
||||
i18n={i18n}
|
||||
id={key}
|
||||
renderText={renderText}
|
||||
components={components}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
hasXButton
|
||||
i18n={i18n}
|
||||
onClose={hideWhatsNewModal}
|
||||
title={i18n('WhatsNew__modal-title')}
|
||||
>
|
||||
<>
|
||||
<span>
|
||||
{moment(releaseNotes.date).format('LL')} ·{' '}
|
||||
{releaseNotes.version}
|
||||
</span>
|
||||
{contentNode}
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
};
|
|
@ -8,12 +8,15 @@ export type GlobalModalsStateType = {
|
|||
readonly isProfileEditorVisible: boolean;
|
||||
readonly profileEditorHasError: boolean;
|
||||
readonly safetyNumberModalContactId?: string;
|
||||
readonly isWhatsNewVisible: boolean;
|
||||
};
|
||||
|
||||
// Actions
|
||||
|
||||
const HIDE_CONTACT_MODAL = 'globalModals/HIDE_CONTACT_MODAL';
|
||||
const SHOW_CONTACT_MODAL = 'globalModals/SHOW_CONTACT_MODAL';
|
||||
const SHOW_WHATS_NEW_MODAL = 'globalModals/SHOW_WHATS_NEW_MODAL_MODAL';
|
||||
const HIDE_WHATS_NEW_MODAL = 'globalModals/HIDE_WHATS_NEW_MODAL_MODAL';
|
||||
const TOGGLE_PROFILE_EDITOR = 'globalModals/TOGGLE_PROFILE_EDITOR';
|
||||
export const TOGGLE_PROFILE_EDITOR_ERROR =
|
||||
'globalModals/TOGGLE_PROFILE_EDITOR_ERROR';
|
||||
|
@ -33,6 +36,14 @@ type ShowContactModalActionType = {
|
|||
payload: ContactModalStateType;
|
||||
};
|
||||
|
||||
type HideWhatsNewModalActionType = {
|
||||
type: typeof HIDE_WHATS_NEW_MODAL;
|
||||
};
|
||||
|
||||
type ShowWhatsNewModalActionType = {
|
||||
type: typeof SHOW_WHATS_NEW_MODAL;
|
||||
};
|
||||
|
||||
type ToggleProfileEditorActionType = {
|
||||
type: typeof TOGGLE_PROFILE_EDITOR;
|
||||
};
|
||||
|
@ -49,6 +60,8 @@ type ToggleSafetyNumberModalActionType = {
|
|||
export type GlobalModalsActionType =
|
||||
| HideContactModalActionType
|
||||
| ShowContactModalActionType
|
||||
| HideWhatsNewModalActionType
|
||||
| ShowWhatsNewModalActionType
|
||||
| ToggleProfileEditorActionType
|
||||
| ToggleProfileEditorErrorActionType
|
||||
| ToggleSafetyNumberModalActionType;
|
||||
|
@ -58,6 +71,8 @@ export type GlobalModalsActionType =
|
|||
export const actions = {
|
||||
hideContactModal,
|
||||
showContactModal,
|
||||
hideWhatsNewModal,
|
||||
showWhatsNewModal,
|
||||
toggleProfileEditor,
|
||||
toggleProfileEditorHasError,
|
||||
toggleSafetyNumberModal,
|
||||
|
@ -82,6 +97,18 @@ function showContactModal(
|
|||
};
|
||||
}
|
||||
|
||||
function hideWhatsNewModal(): HideWhatsNewModalActionType {
|
||||
return {
|
||||
type: HIDE_WHATS_NEW_MODAL,
|
||||
};
|
||||
}
|
||||
|
||||
function showWhatsNewModal(): ShowWhatsNewModalActionType {
|
||||
return {
|
||||
type: SHOW_WHATS_NEW_MODAL,
|
||||
};
|
||||
}
|
||||
|
||||
function toggleProfileEditor(): ToggleProfileEditorActionType {
|
||||
return { type: TOGGLE_PROFILE_EDITOR };
|
||||
}
|
||||
|
@ -105,6 +132,7 @@ export function getEmptyState(): GlobalModalsStateType {
|
|||
return {
|
||||
isProfileEditorVisible: false,
|
||||
profileEditorHasError: false,
|
||||
isWhatsNewVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -126,6 +154,20 @@ export function reducer(
|
|||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_WHATS_NEW_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
isWhatsNewVisible: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === HIDE_WHATS_NEW_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
isWhatsNewVisible: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_CONTACT_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
|
|
|
@ -10,6 +10,8 @@ import { SmartProfileEditorModal } from './ProfileEditorModal';
|
|||
import { SmartContactModal } from './ContactModal';
|
||||
import { SmartSafetyNumberModal } from './SafetyNumberModal';
|
||||
|
||||
import { getIntl } from '../selectors/user';
|
||||
|
||||
const FilteredSmartProfileEditorModal = SmartProfileEditorModal;
|
||||
|
||||
function renderProfileEditor(): JSX.Element {
|
||||
|
@ -21,8 +23,11 @@ function renderContactModal(): JSX.Element {
|
|||
}
|
||||
|
||||
const mapStateToProps = (state: StateType) => {
|
||||
const i18n = getIntl(state);
|
||||
|
||||
return {
|
||||
...state.globalModals,
|
||||
i18n,
|
||||
renderContactModal,
|
||||
renderProfileEditor,
|
||||
renderSafetyNumber: () => (
|
||||
|
|
|
@ -24,4 +24,19 @@ describe('both/state/ducks/globalModals', () => {
|
|||
assert.isFalse(nextNextState.isProfileEditorVisible);
|
||||
});
|
||||
});
|
||||
|
||||
describe('showWhatsNewModal/hideWhatsNewModal', () => {
|
||||
const { showWhatsNewModal, hideWhatsNewModal } = actions;
|
||||
|
||||
it('toggles isWhatsNewVisible to true', () => {
|
||||
const state = getEmptyState();
|
||||
const nextState = reducer(state, showWhatsNewModal());
|
||||
|
||||
assert.isTrue(nextState.isWhatsNewVisible);
|
||||
|
||||
const nextNextState = reducer(nextState, hideWhatsNewModal());
|
||||
|
||||
assert.isFalse(nextNextState.isWhatsNewVisible);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -99,6 +99,7 @@ export type IPCEventsCallbacksType = {
|
|||
showConversationViaSignalDotMe: (hash: string) => void;
|
||||
showKeyboardShortcuts: () => void;
|
||||
showGroupViaLink: (x: string) => Promise<void>;
|
||||
showReleaseNotes: () => void;
|
||||
showStickerPack: (packId: string, key: string) => void;
|
||||
shutdown: () => Promise<void>;
|
||||
unknownSignalLink: () => void;
|
||||
|
@ -505,6 +506,10 @@ export function createIPCEvents(
|
|||
},
|
||||
|
||||
shutdown: () => Promise.resolve(),
|
||||
showReleaseNotes: () => {
|
||||
const { showWhatsNewModal } = window.reduxActions.globalModals;
|
||||
showWhatsNewModal();
|
||||
},
|
||||
|
||||
getMediaPermissions: window.getMediaPermissions,
|
||||
getMediaCameraPermissions: window.getMediaCameraPermissions,
|
||||
|
|
|
@ -12784,14 +12784,6 @@
|
|||
"updated": "2020-08-28T16:12:19.904Z",
|
||||
"reasonDetail": "Used to reference popup menu"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||
"line": " this.menuTriggerRef = React.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-05-20T20:10:43.540Z",
|
||||
"reasonDetail": "Used to reference popup menu"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.js",
|
||||
|
@ -12800,6 +12792,14 @@
|
|||
"updated": "2021-01-18T22:24:05.937Z",
|
||||
"reasonDetail": "Used to reference popup menu boundaries element"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||
"line": " this.menuTriggerRef = React.createRef();",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-05-20T20:10:43.540Z",
|
||||
"reasonDetail": "Used to reference popup menu"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/ConversationHeader.tsx",
|
||||
|
@ -13329,13 +13329,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewView.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
|
@ -13350,12 +13343,19 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-08T17:40:22.770Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/views/inbox_view.js",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewView.el);",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
|
@ -13413,13 +13413,6 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewView.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
|
@ -13434,12 +13427,19 @@
|
|||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-08T17:40:22.770Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-$(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-append(",
|
||||
"path": "ts/views/inbox_view.ts",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewView.el);",
|
||||
"line": " this.$('.whats-new-placeholder').append(this.whatsNewLink.el);",
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2021-09-15T21:07:50.995Z"
|
||||
"updated": "2021-10-22T20:58:48.103Z"
|
||||
},
|
||||
{
|
||||
"rule": "jQuery-appendTo(",
|
||||
|
|
|
@ -160,16 +160,18 @@ Whisper.InboxView = Whisper.View.extend({
|
|||
click: 'onClick',
|
||||
},
|
||||
renderWhatsNew() {
|
||||
if (this.whatsNewView) {
|
||||
if (this.whatsNewLink) {
|
||||
return;
|
||||
}
|
||||
this.whatsNewView = new Whisper.ReactWrapperView({
|
||||
Component: window.Signal.Components.WhatsNew,
|
||||
const { showWhatsNewModal } = window.reduxActions.globalModals;
|
||||
this.whatsNewLink = new Whisper.ReactWrapperView({
|
||||
Component: window.Signal.Components.WhatsNewLink,
|
||||
props: {
|
||||
i18n: window.i18n,
|
||||
showWhatsNewModal,
|
||||
},
|
||||
});
|
||||
this.$('.whats-new-placeholder').append(this.whatsNewView.el);
|
||||
this.$('.whats-new-placeholder').append(this.whatsNewLink.el);
|
||||
},
|
||||
setupLeftPane() {
|
||||
if (this.leftPaneView) {
|
||||
|
|
4
ts/window.d.ts
vendored
4
ts/window.d.ts
vendored
|
@ -92,7 +92,7 @@ import { ProgressModal } from './components/ProgressModal';
|
|||
import { Quote } from './components/conversation/Quote';
|
||||
import { StagedLinkPreview } from './components/conversation/StagedLinkPreview';
|
||||
import { DisappearingTimeDialog } from './components/DisappearingTimeDialog';
|
||||
import { WhatsNew } from './components/WhatsNew';
|
||||
import { WhatsNewLink } from './components/WhatsNewLink';
|
||||
import { MIMEType } from './types/MIME';
|
||||
import { DownloadedAttachmentType } from './types/Attachment';
|
||||
import { ElectronLocaleType } from './util/mapToSupportLocale';
|
||||
|
@ -403,7 +403,7 @@ declare global {
|
|||
ProgressModal: typeof ProgressModal;
|
||||
Quote: typeof Quote;
|
||||
StagedLinkPreview: typeof StagedLinkPreview;
|
||||
WhatsNew: typeof WhatsNew;
|
||||
WhatsNewLink: typeof WhatsNewLink;
|
||||
};
|
||||
OS: typeof OS;
|
||||
Workflow: {
|
||||
|
|
Loading…
Reference in a new issue