Skip to content

Commit

Permalink
feat: introduce VersionWelcomeDialog
Browse files Browse the repository at this point in the history
Show donate dialog after the first time a first IDE version is loaded
  • Loading branch information
giacomocusinato committed Nov 27, 2024
1 parent 2ffe20d commit 7eae0db
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ import {
import { TreeViewDecoratorService } from '@theia/plugin-ext/lib/main/browser/view/tree-view-decorator-service';
import { PLUGIN_VIEW_DATA_FACTORY_ID } from '@theia/plugin-ext/lib/main/browser/view/plugin-view-registry';
import { TreeViewWidget } from './theia/plugin-ext/tree-view-widget';
import {
VersionWelcomeDialog,
VersionWelcomeDialogProps,
} from './dialogs/version-welcome-dialog';

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

bind(VersionWelcomeDialog).toSelf().inSingletonScope();
bind(VersionWelcomeDialogProps).toConstantValue({
title: 'VersionWelcomeDialog',
});

bind(UserFieldsDialog).toSelf().inSingletonScope();
bind(UserFieldsDialogProps).toConstantValue({
title: 'UserFields',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
import { inject, injectable } from '@theia/core/shared/inversify';
import {
IDEUpdater,
LAST_USED_IDE_VERSION,
SKIP_IDE_VERSION,
} from '../../common/protocol/ide-updater';
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
import { Contribution } from './contribution';
import { VersionWelcomeDialog } from '../dialogs/version-welcome-dialog';
import { AppService } from '../app-service';
import { SemVer, valid as validSemVer } from 'semver';

@injectable()
export class CheckForIDEUpdates extends Contribution {
Expand All @@ -16,9 +20,15 @@ export class CheckForIDEUpdates extends Contribution {
@inject(IDEUpdaterDialog)
private readonly updaterDialog: IDEUpdaterDialog;

@inject(VersionWelcomeDialog)
private readonly versionWelcomeDialog: VersionWelcomeDialog;

@inject(LocalStorageService)
private readonly localStorage: LocalStorageService;

@inject(AppService)
private readonly appService: AppService;

override onStart(): void {
this.preferences.onPreferenceChanged(
({ preferenceName, newValue, oldValue }) => {
Expand All @@ -36,7 +46,9 @@ export class CheckForIDEUpdates extends Contribution {
);
}

override onReady(): void {
override async onReady(): Promise<void> {
await this.setLastUsedIDEVersion();

this.updater
.init(
this.preferences.get('arduino.ide.updateChannel'),
Expand All @@ -49,7 +61,14 @@ export class CheckForIDEUpdates extends Contribution {
return this.updater.checkForUpdates(true);
})
.then(async (updateInfo) => {
if (!updateInfo) return;
if (!updateInfo) {
const isNewVersion = await this.isRunningNewIDEVersion();
if (isNewVersion) {
this.setLastUsedIDEVersion(true);
this.versionWelcomeDialog.open();
}
return;
}
const versionToSkip = await this.localStorage.getData<string>(
SKIP_IDE_VERSION
);
Expand All @@ -66,4 +85,26 @@ export class CheckForIDEUpdates extends Contribution {
);
});
}

private async setLastUsedIDEVersion(force = false): Promise<void> {
const { appVersion } = await this.appService.info();
const lastUsedIDEVersion = await this.localStorage.getData<string>(
LAST_USED_IDE_VERSION
);
if (validSemVer(appVersion) && (!lastUsedIDEVersion || force)) {
this.localStorage.setData(LAST_USED_IDE_VERSION, appVersion);
}
}

private async isRunningNewIDEVersion(): Promise<boolean> {
const { appVersion } = await this.appService.info();
const prevVersion = await this.localStorage.getData<string>(
LAST_USED_IDE_VERSION
);
try {
return !!prevVersion && new SemVer(appVersion).compare(prevVersion) === 1;
} catch (e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React from '@theia/core/shared/react';
import { inject, injectable } from '@theia/core/shared/inversify';
import { Message } from '@theia/core/shared/@phosphor/messaging';
import { ReactDialog } from '../theia/dialogs/dialogs';
import { nls } from '@theia/core';
import { DialogProps } from '@theia/core/lib/browser';
import { WindowService } from '@theia/core/lib/browser/window/window-service';
import { AppService } from '../app-service';

@injectable()
export class VersionWelcomeDialogProps extends DialogProps {}

@injectable()
export class VersionWelcomeDialog extends ReactDialog<void> {
@inject(AppService)
private readonly appService: AppService;

@inject(WindowService)
private readonly windowService: WindowService;

constructor(
@inject(VersionWelcomeDialogProps)
protected override readonly props: VersionWelcomeDialogProps
) {
super({ title: '' });

this.node.id = 'version-welcome-dialog-container';
this.contentNode.classList.add('version-welcome-dialog');
}

protected render(): React.ReactNode {
return (
<div>
<p>
{nls.localize(
'arduino/versionWelcome/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.'
)}
</p>
<p className="bold">
{nls.localize(
'arduino/versionWelcome/donateMessage2',
'Please consider supporting our efforts to keep Arduino IDE free.'
)}
</p>
</div>
);
}

override get value(): void {
return;
}

private appendButtons(): void {
const cancelButton = this.createButton(
nls.localize('arduino/versionWelcome/cancelButton', 'Maybe later')
);
cancelButton.classList.add('secondary');
cancelButton.classList.add('cancel-button');
this.addAction(cancelButton, this.close.bind(this), 'click');
this.controlPanel.appendChild(cancelButton);

const donateButton = this.createButton(
nls.localize('arduino/versionWelcome/donateButton', 'Donate now')
);
this.addAction(donateButton, this.openDonationPage.bind(this), 'click');
this.controlPanel.appendChild(donateButton);
donateButton.focus();
}

private readonly openDonationPage = () => {
const url = 'https://www.arduino.cc/en/donate';
this.windowService.openNewWindow(url, { external: true });
};

private async updateTitleVersion(): Promise<void> {
const appInfo = await this.appService.info();
const { appVersion } = appInfo;
const title = nls.localize(
'arduino/versionWelcome/versionWelcomeDialog',
`Welcome to the new Arduino IDE ${appVersion}!`,
appVersion
);
this.titleNode.innerHTML = title;
}

protected override onAfterAttach(msg: Message): void {
this.update();
this.appendButtons();
this.updateTitleVersion();
super.onAfterAttach(msg);
}
}
1 change: 1 addition & 0 deletions arduino-ide-extension/src/browser/style/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@import "./settings-dialog.css";
@import "./firmware-uploader-dialog.css";
@import "./ide-updater-dialog.css";
@import "./version-welcome-dialog.css";
@import "./certificate-uploader-dialog.css";
@import "./user-fields-dialog.css";
@import "./debug.css";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#version-welcome-dialog-container > .dialogBlock {
width: 546px;

.bold {
font-weight: bold;
}
}
1 change: 1 addition & 0 deletions arduino-ide-extension/src/common/protocol/ide-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,4 @@ export interface IDEUpdaterClient {
}

export const SKIP_IDE_VERSION = 'skipIDEVersion';
export const LAST_USED_IDE_VERSION = 'lastUsedIDEVersion';
6 changes: 6 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,12 @@
"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?",
"renameSketchFolderTitle": "Invalid sketch name"
},
"versionWelcome": {
"cancelButton": "Maybe later",
"donateButton": "Donate now",
"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.",
"donateMessage2": "Please consider supporting our efforts to keep Arduino IDE free."
},
"workspace": {
"alreadyExists": "'{0}' already exists."
}
Expand Down

0 comments on commit 7eae0db

Please sign in to comment.