Skip to content

Commit 19cb517

Browse files
feat: introduce VersionWelcomeDialog
Show donate dialog after the first time a first IDE version is loaded
1 parent 504c12e commit 19cb517

File tree

7 files changed

+168
-2
lines changed

7 files changed

+168
-2
lines changed

arduino-ide-extension/src/browser/arduino-ide-frontend-module.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ import {
387387
import { TreeViewDecoratorService } from '@theia/plugin-ext/lib/main/browser/view/tree-view-decorator-service';
388388
import { PLUGIN_VIEW_DATA_FACTORY_ID } from '@theia/plugin-ext/lib/main/browser/view/plugin-view-registry';
389389
import { TreeViewWidget } from './theia/plugin-ext/tree-view-widget';
390+
import {
391+
VersionWelcomeDialog,
392+
VersionWelcomeDialogProps,
393+
} from './dialogs/version-welcome-dialog';
390394

391395
// Hack to fix copy/cut/paste issue after electron version update in Theia.
392396
// https://github.com/eclipse-theia/theia/issues/12487
@@ -1014,6 +1018,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
10141018
title: 'IDEUpdater',
10151019
});
10161020

1021+
bind(VersionWelcomeDialog).toSelf().inSingletonScope();
1022+
bind(VersionWelcomeDialogProps).toConstantValue({
1023+
title: 'VersionWelcomeDialog',
1024+
});
1025+
10171026
bind(UserFieldsDialog).toSelf().inSingletonScope();
10181027
bind(UserFieldsDialogProps).toConstantValue({
10191028
title: 'UserFields',

arduino-ide-extension/src/browser/contributions/check-for-ide-updates.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
33
import { inject, injectable } from '@theia/core/shared/inversify';
44
import {
55
IDEUpdater,
6+
LAST_USED_IDE_VERSION,
67
SKIP_IDE_VERSION,
78
} from '../../common/protocol/ide-updater';
89
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
910
import { Contribution } from './contribution';
11+
import { VersionWelcomeDialog } from '../dialogs/version-welcome-dialog';
12+
import { AppService } from '../app-service';
13+
import { SemVer, valid as validSemVer } from 'semver';
1014

1115
@injectable()
1216
export class CheckForIDEUpdates extends Contribution {
@@ -16,9 +20,15 @@ export class CheckForIDEUpdates extends Contribution {
1620
@inject(IDEUpdaterDialog)
1721
private readonly updaterDialog: IDEUpdaterDialog;
1822

23+
@inject(VersionWelcomeDialog)
24+
private readonly versionWelcomeDialog: VersionWelcomeDialog;
25+
1926
@inject(LocalStorageService)
2027
private readonly localStorage: LocalStorageService;
2128

29+
@inject(AppService)
30+
private readonly appService: AppService;
31+
2232
override onStart(): void {
2333
this.preferences.onPreferenceChanged(
2434
({ preferenceName, newValue, oldValue }) => {
@@ -36,7 +46,9 @@ export class CheckForIDEUpdates extends Contribution {
3646
);
3747
}
3848

39-
override onReady(): void {
49+
override async onReady(): Promise<void> {
50+
await this.setLastUsedIDEVersion();
51+
4052
this.updater
4153
.init(
4254
this.preferences.get('arduino.ide.updateChannel'),
@@ -49,7 +61,14 @@ export class CheckForIDEUpdates extends Contribution {
4961
return this.updater.checkForUpdates(true);
5062
})
5163
.then(async (updateInfo) => {
52-
if (!updateInfo) return;
64+
if (!updateInfo) {
65+
const isNewVersion = await this.isRunningNewIDEVersion();
66+
if (isNewVersion) {
67+
this.setLastUsedIDEVersion(true);
68+
this.versionWelcomeDialog.open();
69+
}
70+
return;
71+
}
5372
const versionToSkip = await this.localStorage.getData<string>(
5473
SKIP_IDE_VERSION
5574
);
@@ -66,4 +85,26 @@ export class CheckForIDEUpdates extends Contribution {
6685
);
6786
});
6887
}
88+
89+
private async setLastUsedIDEVersion(force = false): Promise<void> {
90+
const { appVersion } = await this.appService.info();
91+
const lastUsedIDEVersion = await this.localStorage.getData<string>(
92+
LAST_USED_IDE_VERSION
93+
);
94+
if (validSemVer(appVersion) && (!lastUsedIDEVersion || force)) {
95+
this.localStorage.setData(LAST_USED_IDE_VERSION, appVersion);
96+
}
97+
}
98+
99+
private async isRunningNewIDEVersion(): Promise<boolean> {
100+
const { appVersion } = await this.appService.info();
101+
const prevVersion = await this.localStorage.getData<string>(
102+
LAST_USED_IDE_VERSION
103+
);
104+
try {
105+
return !!prevVersion && new SemVer(appVersion).compare(prevVersion) === 1;
106+
} catch (e) {
107+
return false;
108+
}
109+
}
69110
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import React from '@theia/core/shared/react';
2+
import { inject, injectable } from '@theia/core/shared/inversify';
3+
import { Message } from '@theia/core/shared/@phosphor/messaging';
4+
import { ReactDialog } from '../theia/dialogs/dialogs';
5+
import { nls } from '@theia/core';
6+
import { DialogProps } from '@theia/core/lib/browser';
7+
import { WindowService } from '@theia/core/lib/browser/window/window-service';
8+
import { AppService } from '../app-service';
9+
10+
@injectable()
11+
export class VersionWelcomeDialogProps extends DialogProps {}
12+
13+
@injectable()
14+
export class VersionWelcomeDialog extends ReactDialog<void> {
15+
@inject(AppService)
16+
private readonly appService: AppService;
17+
18+
@inject(WindowService)
19+
private readonly windowService: WindowService;
20+
21+
constructor(
22+
@inject(VersionWelcomeDialogProps)
23+
protected override readonly props: VersionWelcomeDialogProps
24+
) {
25+
super({
26+
title: nls.localize(
27+
'arduino/versionWelcome/title',
28+
'Welcome to a new version of the Arduino IDE!'
29+
),
30+
});
31+
this.node.id = 'version-welcome-dialog-container';
32+
this.contentNode.classList.add('version-welcome-dialog');
33+
}
34+
35+
protected render(): React.ReactNode {
36+
return (
37+
<div>
38+
<p>
39+
{nls.localize(
40+
'arduino/versionWelcome/donateMessage',
41+
'Arduino is committed to keeping software free and open-source for everyone. Your donation helps us develop new features, improve libraries, and support millions of users worldwide.'
42+
)}
43+
</p>
44+
<p className="bold">
45+
{nls.localize(
46+
'arduino/versionWelcome/donateMessage2',
47+
'Please consider supporting our work on the free open source Arduino IDE.'
48+
)}
49+
</p>
50+
</div>
51+
);
52+
}
53+
54+
override get value(): void {
55+
return;
56+
}
57+
58+
private appendButtons(): void {
59+
const cancelButton = this.createButton(
60+
nls.localize('arduino/versionWelcome/cancelButton', 'Maybe later')
61+
);
62+
cancelButton.classList.add('secondary');
63+
cancelButton.classList.add('cancel-button');
64+
this.addAction(cancelButton, this.close.bind(this), 'click');
65+
this.controlPanel.appendChild(cancelButton);
66+
67+
const donateButton = this.createButton(
68+
nls.localize('arduino/versionWelcome/donateButton', 'Donate now')
69+
);
70+
this.addAction(donateButton, this.openDonationPage.bind(this), 'click');
71+
this.controlPanel.appendChild(donateButton);
72+
donateButton.focus();
73+
}
74+
75+
private readonly openDonationPage = () => {
76+
const url = 'https://www.arduino.cc/en/donate';
77+
this.windowService.openNewWindow(url, { external: true });
78+
};
79+
80+
private async updateTitleVersion(): Promise<void> {
81+
const appInfo = await this.appService.info();
82+
const { appVersion } = appInfo;
83+
84+
if (appVersion) {
85+
this.titleNode.innerHTML = nls.localize(
86+
'arduino/versionWelcome/titleWithVersion',
87+
'Welcome to the new Arduino IDE {0}!',
88+
appVersion
89+
);
90+
}
91+
}
92+
93+
protected override onAfterAttach(msg: Message): void {
94+
this.update();
95+
this.appendButtons();
96+
this.updateTitleVersion();
97+
super.onAfterAttach(msg);
98+
}
99+
}

arduino-ide-extension/src/browser/style/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
@import "./settings-dialog.css";
1111
@import "./firmware-uploader-dialog.css";
1212
@import "./ide-updater-dialog.css";
13+
@import "./version-welcome-dialog.css";
1314
@import "./certificate-uploader-dialog.css";
1415
@import "./user-fields-dialog.css";
1516
@import "./debug.css";
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#version-welcome-dialog-container > .dialogBlock {
2+
width: 546px;
3+
4+
.bold {
5+
font-weight: bold;
6+
}
7+
}

arduino-ide-extension/src/common/protocol/ide-updater.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ export interface IDEUpdaterClient {
7171
}
7272

7373
export const SKIP_IDE_VERSION = 'skipIDEVersion';
74+
export const LAST_USED_IDE_VERSION = 'lastUsedIDEVersion';

i18n/en.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@
528528
"renameSketchFolderMessage": "The sketch '{0}' cannot be used. {1} To get rid of this message, rename the sketch. Do you want to rename the sketch now?",
529529
"renameSketchFolderTitle": "Invalid sketch name"
530530
},
531+
"versionWelcome": {
532+
"cancelButton": "Maybe later",
533+
"donateButton": "Donate now",
534+
"donateMessage": "Arduino is committed to keeping software free and open-source for everyone. Your donation helps us develop new features, improve libraries, and support millions of users worldwide.",
535+
"donateMessage2": "Please consider supporting our work on the free open source Arduino IDE.",
536+
"title": "Welcome to a new version of the Arduino IDE!",
537+
"titleWithVersion": "Welcome to the new Arduino IDE {0}!"
538+
},
531539
"workspace": {
532540
"alreadyExists": "'{0}' already exists."
533541
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy