mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-11-09 10:28:32 +00:00
Compare commits
1 Commits
remove-don
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e394a5b010 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -607,7 +607,7 @@ jobs:
|
|||||||
pattern: ${{ env.JOB_TRANSFER_ARTIFACT_PREFIX }}*
|
pattern: ${{ env.JOB_TRANSFER_ARTIFACT_PREFIX }}*
|
||||||
|
|
||||||
- name: Configure AWS Credentials for Nightly [S3]
|
- name: Configure AWS Credentials for Nightly [S3]
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
uses: aws-actions/configure-aws-credentials@v5
|
||||||
with:
|
with:
|
||||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
@@ -666,7 +666,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Configure AWS Credentials for Release [S3]
|
- name: Configure AWS Credentials for Release [S3]
|
||||||
if: needs.build-type-determination.outputs.publish-to-s3 == 'true'
|
if: needs.build-type-determination.outputs.publish-to-s3 == 'true'
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
uses: aws-actions/configure-aws-credentials@v5
|
||||||
with:
|
with:
|
||||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
|
|||||||
2
.github/workflows/compose-full-changelog.yml
vendored
2
.github/workflows/compose-full-changelog.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
|||||||
yarn run compose-changelog "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}/$CHANGELOG_FILE_NAME"
|
yarn run compose-changelog "${{ github.workspace }}/${{ env.CHANGELOG_ARTIFACTS }}/$CHANGELOG_FILE_NAME"
|
||||||
|
|
||||||
- name: Configure AWS Credentials for Changelog [S3]
|
- name: Configure AWS Credentials for Changelog [S3]
|
||||||
uses: aws-actions/configure-aws-credentials@v4
|
uses: aws-actions/configure-aws-credentials@v5
|
||||||
with:
|
with:
|
||||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ See [**the contributor guide**](docs/CONTRIBUTING.md#contributor-guide) for more
|
|||||||
|
|
||||||
See the [**development guide**](docs/development.md) for a technical overview of the application and instructions for building the code.
|
See the [**development guide**](docs/development.md) for a technical overview of the application and instructions for building the code.
|
||||||
|
|
||||||
### Support the project
|
## Donations
|
||||||
|
|
||||||
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [buying original Arduino boards](https://store.arduino.cc/) to support our work on the project.
|
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [donating](https://www.arduino.cc/en/donate/) or [sponsoring](https://github.com/sponsors/arduino) to support our work, as well as [buying original Arduino boards](https://store.arduino.cc/) which is the best way to make sure our effort can continue in the long term.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@
|
|||||||
"cross-fetch": "^3.1.5",
|
"cross-fetch": "^3.1.5",
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
"deepmerge": "^4.2.2",
|
"deepmerge": "^4.2.2",
|
||||||
|
"dompurify": "^2.4.7",
|
||||||
"drivelist": "^9.2.4",
|
"drivelist": "^9.2.4",
|
||||||
"electron-updater": "^4.6.5",
|
"electron-updater": "^4.6.5",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
|
|||||||
@@ -368,6 +368,10 @@ import { DebugConfigurationWidget } from './theia/debug/debug-configuration-widg
|
|||||||
import { DebugConfigurationWidget as TheiaDebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget';
|
import { DebugConfigurationWidget as TheiaDebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget';
|
||||||
import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
|
import { DebugToolBar } from '@theia/debug/lib/browser/view/debug-toolbar-widget';
|
||||||
|
|
||||||
|
import {
|
||||||
|
VersionWelcomeDialog,
|
||||||
|
VersionWelcomeDialogProps,
|
||||||
|
} from './dialogs/version-welcome-dialog';
|
||||||
import { TestViewContribution as TheiaTestViewContribution } from '@theia/test/lib/browser/view/test-view-contribution';
|
import { TestViewContribution as TheiaTestViewContribution } from '@theia/test/lib/browser/view/test-view-contribution';
|
||||||
import { TestViewContribution } from './theia/test/test-view-contribution';
|
import { TestViewContribution } from './theia/test/test-view-contribution';
|
||||||
|
|
||||||
@@ -983,6 +987,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|||||||
title: 'IDEUpdater',
|
title: 'IDEUpdater',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
bind(VersionWelcomeDialog).toSelf().inSingletonScope();
|
||||||
|
bind(VersionWelcomeDialogProps).toConstantValue({
|
||||||
|
title: 'VersionWelcomeDialog',
|
||||||
|
});
|
||||||
|
|
||||||
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
||||||
bind(UserFieldsDialogProps).toConstantValue({
|
bind(UserFieldsDialogProps).toConstantValue({
|
||||||
title: 'UserFields',
|
title: 'UserFields',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
} from '../../common/protocol/ide-updater';
|
} from '../../common/protocol/ide-updater';
|
||||||
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
import { IDEUpdaterDialog } from '../dialogs/ide-updater/ide-updater-dialog';
|
||||||
import { Contribution } from './contribution';
|
import { Contribution } from './contribution';
|
||||||
|
import { VersionWelcomeDialog } from '../dialogs/version-welcome-dialog';
|
||||||
import { AppService } from '../app-service';
|
import { AppService } from '../app-service';
|
||||||
import { SemVer } from 'semver';
|
import { SemVer } from 'semver';
|
||||||
|
|
||||||
@@ -19,6 +20,9 @@ export class CheckForIDEUpdates extends Contribution {
|
|||||||
@inject(IDEUpdaterDialog)
|
@inject(IDEUpdaterDialog)
|
||||||
private readonly updaterDialog: IDEUpdaterDialog;
|
private readonly updaterDialog: IDEUpdaterDialog;
|
||||||
|
|
||||||
|
@inject(VersionWelcomeDialog)
|
||||||
|
private readonly versionWelcomeDialog: VersionWelcomeDialog;
|
||||||
|
|
||||||
@inject(LocalStorageService)
|
@inject(LocalStorageService)
|
||||||
private readonly localStorage: LocalStorageService;
|
private readonly localStorage: LocalStorageService;
|
||||||
|
|
||||||
@@ -55,8 +59,13 @@ export class CheckForIDEUpdates extends Contribution {
|
|||||||
return this.updater.checkForUpdates(true);
|
return this.updater.checkForUpdates(true);
|
||||||
})
|
})
|
||||||
.then(async (updateInfo) => {
|
.then(async (updateInfo) => {
|
||||||
if (!updateInfo) return;
|
if (!updateInfo) {
|
||||||
|
const isNewVersion = await this.isNewStableVersion();
|
||||||
|
if (isNewVersion) {
|
||||||
|
this.versionWelcomeDialog.open();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
const versionToSkip = await this.localStorage.getData<string>(
|
const versionToSkip = await this.localStorage.getData<string>(
|
||||||
SKIP_IDE_VERSION
|
SKIP_IDE_VERSION
|
||||||
);
|
);
|
||||||
@@ -77,11 +86,6 @@ export class CheckForIDEUpdates extends Contribution {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This value is set in localStorage but currently not used.
|
|
||||||
* We keep this logic running anyway for eventual future needs
|
|
||||||
* (eg. show a new version welcome dialog)
|
|
||||||
*/
|
|
||||||
private async setCurrentIDEVersion(): Promise<void> {
|
private async setCurrentIDEVersion(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const { appVersion } = await this.appService.info();
|
const { appVersion } = await this.appService.info();
|
||||||
@@ -91,4 +95,29 @@ export class CheckForIDEUpdates extends Contribution {
|
|||||||
// ignore invalid versions
|
// ignore invalid versions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user is running a new IDE version for the first time.
|
||||||
|
* @returns true if the current IDE version is greater than the last used version
|
||||||
|
* and both are non-prerelease versions.
|
||||||
|
*/
|
||||||
|
private async isNewStableVersion(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const { appVersion } = await this.appService.info();
|
||||||
|
const prevVersion = await this.localStorage.getData<string>(
|
||||||
|
LAST_USED_IDE_VERSION
|
||||||
|
);
|
||||||
|
|
||||||
|
const prevSemVer = new SemVer(prevVersion ?? '');
|
||||||
|
const currSemVer = new SemVer(appVersion ?? '');
|
||||||
|
|
||||||
|
if (prevSemVer.prerelease.length || currSemVer.prerelease.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currSemVer.compare(prevSemVer) === 1;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
} from '../../../common/protocol/ide-updater';
|
} from '../../../common/protocol/ide-updater';
|
||||||
import { LocalStorageService } from '@theia/core/lib/browser';
|
import { LocalStorageService } from '@theia/core/lib/browser';
|
||||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||||
|
import { sanitize } from 'dompurify';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class IDEUpdaterDialogProps extends DialogProps {}
|
export class IDEUpdaterDialogProps extends DialogProps {}
|
||||||
@@ -165,6 +166,51 @@ export class IDEUpdaterDialog extends ReactDialog<UpdateInfo | undefined> {
|
|||||||
goToDownloadPageButton.focus();
|
goToDownloadPageButton.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private appendDonateFooter() {
|
||||||
|
const footer = document.createElement('div');
|
||||||
|
footer.classList.add('ide-updater-dialog--footer');
|
||||||
|
const footerContent = document.createElement('div');
|
||||||
|
footerContent.classList.add('ide-updater-dialog--footer-content');
|
||||||
|
footer.appendChild(footerContent);
|
||||||
|
|
||||||
|
const footerLink = document.createElement('a');
|
||||||
|
footerLink.innerText = sanitize(
|
||||||
|
nls.localize('arduino/ide-updater/donateLinkText', 'donate to support us')
|
||||||
|
);
|
||||||
|
footerLink.classList.add('ide-updater-dialog--footer-link');
|
||||||
|
footerLink.onclick = () =>
|
||||||
|
this.openExternal('https://www.arduino.cc/en/donate');
|
||||||
|
|
||||||
|
const footerLinkIcon = document.createElement('span');
|
||||||
|
footerLinkIcon.title = nls.localize(
|
||||||
|
'arduino/ide-updater/donateLinkIconTitle',
|
||||||
|
'open donation page'
|
||||||
|
);
|
||||||
|
footerLinkIcon.classList.add('ide-updater-dialog--footer-link-icon');
|
||||||
|
footerLink.appendChild(footerLinkIcon);
|
||||||
|
|
||||||
|
const placeholderKey = '%%link%%';
|
||||||
|
const footerText = sanitize(
|
||||||
|
nls.localize(
|
||||||
|
'arduino/ide-updater/donateText',
|
||||||
|
'Open source is love, {0}',
|
||||||
|
placeholderKey
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const placeholder = footerText.indexOf(placeholderKey);
|
||||||
|
if (placeholder !== -1) {
|
||||||
|
const parts = footerText.split(placeholderKey);
|
||||||
|
footerContent.appendChild(document.createTextNode(parts[0]));
|
||||||
|
footerContent.appendChild(footerLink);
|
||||||
|
footerContent.appendChild(document.createTextNode(parts[1]));
|
||||||
|
} else {
|
||||||
|
footerContent.appendChild(document.createTextNode(footerText));
|
||||||
|
footerContent.appendChild(footerLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.controlPanel.insertAdjacentElement('afterend', footer);
|
||||||
|
}
|
||||||
|
|
||||||
private openDownloadPage(): void {
|
private openDownloadPage(): void {
|
||||||
this.openExternal('https://www.arduino.cc/en/software');
|
this.openExternal('https://www.arduino.cc/en/software');
|
||||||
this.close();
|
this.close();
|
||||||
@@ -187,6 +233,7 @@ export class IDEUpdaterDialog extends ReactDialog<UpdateInfo | undefined> {
|
|||||||
downloadStarted: true,
|
downloadStarted: true,
|
||||||
});
|
});
|
||||||
this.clearButtons();
|
this.clearButtons();
|
||||||
|
this.appendDonateFooter();
|
||||||
this.updater.downloadUpdate();
|
this.updater.downloadUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
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';
|
||||||
|
import { sanitize } from 'dompurify';
|
||||||
|
|
||||||
|
@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: nls.localize(
|
||||||
|
'arduino/versionWelcome/title',
|
||||||
|
'Welcome to a new version of the Arduino IDE!'
|
||||||
|
),
|
||||||
|
});
|
||||||
|
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 work on the free open source Arduino IDE.'
|
||||||
|
)}
|
||||||
|
</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.onDonateButtonClick.bind(this), 'click');
|
||||||
|
this.controlPanel.appendChild(donateButton);
|
||||||
|
donateButton.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDonateButtonClick(): void {
|
||||||
|
this.openDonationPage();
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (appVersion) {
|
||||||
|
this.titleNode.innerText = sanitize(
|
||||||
|
nls.localize(
|
||||||
|
'arduino/versionWelcome/titleWithVersion',
|
||||||
|
'Welcome to the new Arduino IDE {0}!',
|
||||||
|
appVersion
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override onAfterAttach(msg: Message): void {
|
||||||
|
this.update();
|
||||||
|
this.appendButtons();
|
||||||
|
this.updateTitleVersion();
|
||||||
|
super.onAfterAttach(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,7 +67,3 @@ export function truncateLines(
|
|||||||
}
|
}
|
||||||
return [lines, charCount];
|
return [lines, charCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function joinLines(lines: Line[]): string {
|
|
||||||
return lines.map((line: Line) => line.message).join('');
|
|
||||||
}
|
|
||||||
@@ -52,9 +52,6 @@ export namespace SerialMonitor {
|
|||||||
},
|
},
|
||||||
'vscode/output.contribution/clearOutput.label'
|
'vscode/output.contribution/clearOutput.label'
|
||||||
);
|
);
|
||||||
export const COPY_OUTPUT = {
|
|
||||||
id: 'serial-monitor-copy-output',
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,12 +149,6 @@ export class MonitorViewContribution
|
|||||||
'Clear Output'
|
'Clear Output'
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
registry.registerItem({
|
|
||||||
id: SerialMonitor.Commands.COPY_OUTPUT.id,
|
|
||||||
command: SerialMonitor.Commands.COPY_OUTPUT.id,
|
|
||||||
icon: codicon('copy'),
|
|
||||||
tooltip: nls.localize('arduino/serial/copyOutput', 'Copy Output'),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override registerCommands(commands: CommandRegistry): void {
|
override registerCommands(commands: CommandRegistry): void {
|
||||||
@@ -170,15 +161,6 @@ export class MonitorViewContribution
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
commands.registerCommand(SerialMonitor.Commands.COPY_OUTPUT, {
|
|
||||||
isEnabled: (widget) => widget instanceof MonitorWidget,
|
|
||||||
isVisible: (widget) => widget instanceof MonitorWidget,
|
|
||||||
execute: (widget) => {
|
|
||||||
if (widget instanceof MonitorWidget) {
|
|
||||||
widget.copyOutput();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (this.toggleCommand) {
|
if (this.toggleCommand) {
|
||||||
commands.registerCommand(this.toggleCommand, {
|
commands.registerCommand(this.toggleCommand, {
|
||||||
execute: () => this.toggle(),
|
execute: () => this.toggle(),
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import {
|
|||||||
import { MonitorModel } from '../../monitor-model';
|
import { MonitorModel } from '../../monitor-model';
|
||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||||
import { serialMonitorWidgetLabel } from '../../../common/nls';
|
import { serialMonitorWidgetLabel } from '../../../common/nls';
|
||||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class MonitorWidget extends ReactWidget {
|
export class MonitorWidget extends ReactWidget {
|
||||||
@@ -48,7 +47,6 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
*/
|
*/
|
||||||
protected closing = false;
|
protected closing = false;
|
||||||
protected readonly clearOutputEmitter = new Emitter<void>();
|
protected readonly clearOutputEmitter = new Emitter<void>();
|
||||||
protected readonly copyOutputEmitter = new Emitter<void>();
|
|
||||||
|
|
||||||
@inject(MonitorModel)
|
@inject(MonitorModel)
|
||||||
private readonly monitorModel: MonitorModel;
|
private readonly monitorModel: MonitorModel;
|
||||||
@@ -58,8 +56,6 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||||
@inject(FrontendApplicationStateService)
|
@inject(FrontendApplicationStateService)
|
||||||
private readonly appStateService: FrontendApplicationStateService;
|
private readonly appStateService: FrontendApplicationStateService;
|
||||||
@inject(ClipboardService)
|
|
||||||
private readonly clipboardService: ClipboardService;
|
|
||||||
|
|
||||||
private readonly toDisposeOnReset: DisposableCollection;
|
private readonly toDisposeOnReset: DisposableCollection;
|
||||||
|
|
||||||
@@ -106,10 +102,6 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
this.clearOutputEmitter.fire(undefined);
|
this.clearOutputEmitter.fire(undefined);
|
||||||
this.update();
|
this.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
copyOutput(): void {
|
|
||||||
this.copyOutputEmitter.fire();
|
|
||||||
}
|
|
||||||
|
|
||||||
override dispose(): void {
|
override dispose(): void {
|
||||||
this.toDisposeOnReset.dispose();
|
this.toDisposeOnReset.dispose();
|
||||||
@@ -255,8 +247,6 @@ export class MonitorWidget extends ReactWidget {
|
|||||||
monitorModel={this.monitorModel}
|
monitorModel={this.monitorModel}
|
||||||
monitorManagerProxy={this.monitorManagerProxy}
|
monitorManagerProxy={this.monitorManagerProxy}
|
||||||
clearConsoleEvent={this.clearOutputEmitter.event}
|
clearConsoleEvent={this.clearOutputEmitter.event}
|
||||||
copyOutputEvent={this.copyOutputEmitter.event}
|
|
||||||
clipboardService={this.clipboardService}
|
|
||||||
height={Math.floor(this.widgetHeight - 50)}
|
height={Math.floor(this.widgetHeight - 50)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import { Event } from '@theia/core/lib/common/event';
|
|||||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||||
import { areEqual, FixedSizeList as List } from 'react-window';
|
import { areEqual, FixedSizeList as List } from 'react-window';
|
||||||
import dateFormat from 'dateformat';
|
import dateFormat from 'dateformat';
|
||||||
import { messagesToLines, truncateLines, joinLines } from './monitor-utils';
|
import { messagesToLines, truncateLines } from './monitor-utils';
|
||||||
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
import { MonitorManagerProxyClient } from '../../../common/protocol';
|
||||||
import { MonitorModel } from '../../monitor-model';
|
import { MonitorModel } from '../../monitor-model';
|
||||||
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
|
|
||||||
|
|
||||||
export type Line = { message: string; timestamp?: Date; lineLen: number };
|
export type Line = { message: string; timestamp?: Date; lineLen: number };
|
||||||
|
|
||||||
@@ -75,9 +74,6 @@ export class SerialMonitorOutput extends React.Component<
|
|||||||
this.props.clearConsoleEvent(() =>
|
this.props.clearConsoleEvent(() =>
|
||||||
this.setState({ lines: [], charCount: 0 })
|
this.setState({ lines: [], charCount: 0 })
|
||||||
),
|
),
|
||||||
this.props.copyOutputEvent(() =>
|
|
||||||
this.props.clipboardService.writeText(joinLines(this.state.lines))
|
|
||||||
),
|
|
||||||
this.props.monitorModel.onChange(({ property }) => {
|
this.props.monitorModel.onChange(({ property }) => {
|
||||||
if (property === 'timestamp') {
|
if (property === 'timestamp') {
|
||||||
const { timestamp } = this.props.monitorModel;
|
const { timestamp } = this.props.monitorModel;
|
||||||
@@ -134,8 +130,6 @@ export namespace SerialMonitorOutput {
|
|||||||
readonly monitorModel: MonitorModel;
|
readonly monitorModel: MonitorModel;
|
||||||
readonly monitorManagerProxy: MonitorManagerProxyClient;
|
readonly monitorManagerProxy: MonitorManagerProxyClient;
|
||||||
readonly clearConsoleEvent: Event<void>;
|
readonly clearConsoleEvent: Event<void>;
|
||||||
readonly copyOutputEvent: Event<void>;
|
|
||||||
readonly clipboardService: ClipboardService;
|
|
||||||
readonly height: number;
|
readonly height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,37 @@
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ide-updater-dialog--footer {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: -16px;
|
||||||
|
padding: 12px 0 24px 0;
|
||||||
|
border-top: 1px solid var(--theia-editorWidget-border);
|
||||||
|
}
|
||||||
|
.ide-updater-dialog--footer-content {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ide-updater-dialog--footer-link {
|
||||||
|
display: inline-block;
|
||||||
|
color: var(--theia-textLink-foreground);
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 13px;
|
||||||
|
}
|
||||||
|
.ide-updater-dialog--footer-link:hover {
|
||||||
|
color: var(--theia-textLink-foreground);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.ide-updater-dialog--footer-link-icon {
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-mask: url(../icons/link-open-icon.svg) center no-repeat;
|
||||||
|
background-color: var(--theia-textLink-foreground);
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transform: translateY(2px);
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.ide-updater-dialog .changelog {
|
.ide-updater-dialog .changelog {
|
||||||
color: var(--theia-editor-foreground);
|
color: var(--theia-editor-foreground);
|
||||||
background-color: var(--theia-editor-background);
|
background-color: var(--theia-editor-background);
|
||||||
@@ -109,6 +140,7 @@
|
|||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
padding-bottom: 20px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ide-updater-dialog-container .skip-version-button {
|
#ide-updater-dialog-container .skip-version-button {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
@import "./settings-dialog.css";
|
@import "./settings-dialog.css";
|
||||||
@import "./firmware-uploader-dialog.css";
|
@import "./firmware-uploader-dialog.css";
|
||||||
@import "./ide-updater-dialog.css";
|
@import "./ide-updater-dialog.css";
|
||||||
|
@import "./version-welcome-dialog.css";
|
||||||
@import "./certificate-uploader-dialog.css";
|
@import "./certificate-uploader-dialog.css";
|
||||||
@import "./user-fields-dialog.css";
|
@import "./user-fields-dialog.css";
|
||||||
@import "./debug.css";
|
@import "./debug.css";
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#version-welcome-dialog-container > .dialogBlock {
|
||||||
|
width: 546px;
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ import { expect } from 'chai';
|
|||||||
import {
|
import {
|
||||||
messagesToLines,
|
messagesToLines,
|
||||||
truncateLines,
|
truncateLines,
|
||||||
joinLines,
|
|
||||||
} from '../../browser/serial/monitor/monitor-utils';
|
} from '../../browser/serial/monitor/monitor-utils';
|
||||||
import { Line } from '../../browser/serial/monitor/serial-monitor-send-output';
|
import { Line } from '../../browser/serial/monitor/serial-monitor-send-output';
|
||||||
import { set, reset } from 'mockdate';
|
import { set, reset } from 'mockdate';
|
||||||
@@ -16,7 +15,6 @@ type TestLine = {
|
|||||||
charCount: number;
|
charCount: number;
|
||||||
maxCharacters?: number;
|
maxCharacters?: number;
|
||||||
};
|
};
|
||||||
expectedJoined?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
@@ -24,7 +22,6 @@ const testLines: TestLine[] = [
|
|||||||
{
|
{
|
||||||
messages: ['Hello'],
|
messages: ['Hello'],
|
||||||
expected: { lines: [{ message: 'Hello', lineLen: 5 }], charCount: 5 },
|
expected: { lines: [{ message: 'Hello', lineLen: 5 }], charCount: 5 },
|
||||||
expectedJoined: 'Hello',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
messages: ['Hello', 'Dog!'],
|
messages: ['Hello', 'Dog!'],
|
||||||
@@ -39,7 +36,6 @@ const testLines: TestLine[] = [
|
|||||||
],
|
],
|
||||||
charCount: 10,
|
charCount: 10,
|
||||||
},
|
},
|
||||||
expectedJoined: 'Hello\nDog!'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
messages: ['Dog!'],
|
messages: ['Dog!'],
|
||||||
@@ -71,7 +67,6 @@ const testLines: TestLine[] = [
|
|||||||
{ message: "You're a good boy!", lineLen: 8 },
|
{ message: "You're a good boy!", lineLen: 8 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
expectedJoined: "Hello Dog!\n Who's a good boy?\nYou're a good boy!",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
messages: ['boy?\n', "You're a good boy!"],
|
messages: ['boy?\n', "You're a good boy!"],
|
||||||
@@ -121,7 +116,6 @@ const testLines: TestLine[] = [
|
|||||||
{ message: 'Yo', lineLen: 2 },
|
{ message: 'Yo', lineLen: 2 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
expectedJoined: "Hello Dog!\nWho's a good boy?\nYo",
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -171,10 +165,6 @@ describe('Monitor Utils', () => {
|
|||||||
});
|
});
|
||||||
expect(totalCharCount).to.equal(charCount);
|
expect(totalCharCount).to.equal(charCount);
|
||||||
}
|
}
|
||||||
if (testLine.expectedJoined) {
|
|
||||||
const joined_str = joinLines(testLine.expected.lines);
|
|
||||||
expect(joined_str).to.equal(testLine.expectedJoined);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,20 +6,22 @@ Thanks for your interest in contributing to this project!
|
|||||||
|
|
||||||
There are several ways you can get involved:
|
There are several ways you can get involved:
|
||||||
|
|
||||||
| Type of contribution | Contribution method |
|
| Type of contribution | Contribution method |
|
||||||
| ----------------------------------------- | ---------------------------------------------------------------- |
|
| ----------------------------------------- | -------------------------------------------------------------------------------- |
|
||||||
| - Support<br/>- Question<br/>- Discussion | Post on the [**Arduino Forum**][forum] |
|
| - Support<br/>- Question<br/>- Discussion | Post on the [**Arduino Forum**][forum] |
|
||||||
| - Bug report<br/>- Feature request | Issue report (see the guide [**here**][issues]) |
|
| - Bug report<br/>- Feature request | Issue report (see the guide [**here**][issues]) |
|
||||||
| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) |
|
| Testing | Beta testing, PR review (see the guide [**here**][beta-testing]) |
|
||||||
| Translation | See the guide [**here**][translate] |
|
| Translation | See the guide [**here**][translate] |
|
||||||
| - Bug fix<br/>- Enhancement | Pull request (see the guide [**here**][prs]) |
|
| - Bug fix<br/>- Enhancement | Pull request (see the guide [**here**][prs]) |
|
||||||
| Monetary | [Buy official products][store] |
|
| Monetary | - [Donate][donate]<br/>- [Sponsor][sponsor]<br/>- [Buy official products][store] |
|
||||||
|
|
||||||
[forum]: https://forum.arduino.cc
|
[forum]: https://forum.arduino.cc
|
||||||
[issues]: contributor-guide/issues.md#issue-report-guide
|
[issues]: contributor-guide/issues.md#issue-report-guide
|
||||||
[beta-testing]: contributor-guide/beta-testing.md#beta-testing-guide
|
[beta-testing]: contributor-guide/beta-testing.md#beta-testing-guide
|
||||||
[translate]: contributor-guide/translation.md#translator-guide
|
[translate]: contributor-guide/translation.md#translator-guide
|
||||||
[prs]: contributor-guide/pull-requests.md#pull-request-guide
|
[prs]: contributor-guide/pull-requests.md#pull-request-guide
|
||||||
|
[donate]: https://www.arduino.cc/en/donate/
|
||||||
|
[sponsor]: https://github.com/sponsors/arduino
|
||||||
[store]: https://store.arduino.cc
|
[store]: https://store.arduino.cc
|
||||||
|
|
||||||
## Resources
|
## Resources
|
||||||
|
|||||||
12
i18n/en.json
12
i18n/en.json
@@ -275,6 +275,9 @@
|
|||||||
"checkForUpdates": "Check for Arduino IDE Updates",
|
"checkForUpdates": "Check for Arduino IDE Updates",
|
||||||
"closeAndInstallButton": "Close and Install",
|
"closeAndInstallButton": "Close and Install",
|
||||||
"closeToInstallNotice": "Close the software and install the update on your machine.",
|
"closeToInstallNotice": "Close the software and install the update on your machine.",
|
||||||
|
"donateLinkIconTitle": "open donation page",
|
||||||
|
"donateLinkText": "donate to support us",
|
||||||
|
"donateText": "Open source is love, {0}",
|
||||||
"downloadButton": "Download",
|
"downloadButton": "Download",
|
||||||
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
|
"downloadingNotice": "Downloading the latest version of the Arduino IDE.",
|
||||||
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
|
"errorCheckingForUpdates": "Error while checking for Arduino IDE updates.\n{0}",
|
||||||
@@ -432,7 +435,6 @@
|
|||||||
"autoscroll": "Autoscroll",
|
"autoscroll": "Autoscroll",
|
||||||
"carriageReturn": "Carriage Return",
|
"carriageReturn": "Carriage Return",
|
||||||
"connecting": "Connecting to '{0}' on '{1}'...",
|
"connecting": "Connecting to '{0}' on '{1}'...",
|
||||||
"copyOutput": "Copy Output",
|
|
||||||
"message": "Message (Enter to send message to '{0}' on '{1}')",
|
"message": "Message (Enter to send message to '{0}' on '{1}')",
|
||||||
"newLine": "New Line",
|
"newLine": "New Line",
|
||||||
"newLineCarriageReturn": "Both NL & CR",
|
"newLineCarriageReturn": "Both NL & CR",
|
||||||
@@ -520,6 +522,14 @@
|
|||||||
"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?",
|
"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"
|
"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 work on the free open source Arduino IDE.",
|
||||||
|
"title": "Welcome to a new version of the Arduino IDE!",
|
||||||
|
"titleWithVersion": "Welcome to the new Arduino IDE {0}!"
|
||||||
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"alreadyExists": "'{0}' already exists."
|
"alreadyExists": "'{0}' already exists."
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5912,7 +5912,7 @@ domexception@^4.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
webidl-conversions "^7.0.0"
|
webidl-conversions "^7.0.0"
|
||||||
|
|
||||||
dompurify@^2.2.9:
|
dompurify@^2.2.9, dompurify@^2.4.7:
|
||||||
version "2.5.8"
|
version "2.5.8"
|
||||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.8.tgz#2809d89d7e528dc7a071dea440d7376df676f824"
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.5.8.tgz#2809d89d7e528dc7a071dea440d7376df676f824"
|
||||||
integrity sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==
|
integrity sha512-o1vSNgrmYMQObbSSvF/1brBYEQPHhV1+gsmrusO7/GXtp1T9rCS8cXFqVxK/9crT1jA6Ccv+5MTSjBNqr7Sovw==
|
||||||
|
|||||||
Reference in New Issue
Block a user