mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-07-09 12:26:34 +00:00
Implemented the Network tab.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
This commit is contained in:
parent
e957ac4331
commit
68b1f8d4f2
@ -41,6 +41,7 @@
|
|||||||
"@types/ncp": "^2.0.4",
|
"@types/ncp": "^2.0.4",
|
||||||
"@types/ps-tree": "^1.1.0",
|
"@types/ps-tree": "^1.1.0",
|
||||||
"@types/react-select": "^3.0.0",
|
"@types/react-select": "^3.0.0",
|
||||||
|
"@types/react-tabs": "^2.3.2",
|
||||||
"@types/sinon": "^7.5.2",
|
"@types/sinon": "^7.5.2",
|
||||||
"@types/temp": "^0.8.34",
|
"@types/temp": "^0.8.34",
|
||||||
"@types/which": "^1.3.1",
|
"@types/which": "^1.3.1",
|
||||||
@ -56,7 +57,9 @@
|
|||||||
"ncp": "^2.0.0",
|
"ncp": "^2.0.0",
|
||||||
"p-queue": "^5.0.0",
|
"p-queue": "^5.0.0",
|
||||||
"ps-tree": "^1.2.0",
|
"ps-tree": "^1.2.0",
|
||||||
|
"react-disable": "^0.1.0",
|
||||||
"react-select": "^3.0.4",
|
"react-select": "^3.0.4",
|
||||||
|
"react-tabs": "^3.1.2",
|
||||||
"semver": "^7.3.2",
|
"semver": "^7.3.2",
|
||||||
"string-natural-compare": "^2.0.3",
|
"string-natural-compare": "^2.0.3",
|
||||||
"temp": "^0.9.1",
|
"temp": "^0.9.1",
|
||||||
@ -120,7 +123,7 @@
|
|||||||
],
|
],
|
||||||
"arduino": {
|
"arduino": {
|
||||||
"cli": {
|
"cli": {
|
||||||
"version": "0.15.0-rc1"
|
"version": "20210203"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@ import * as React from 'react';
|
|||||||
import { injectable, inject, postConstruct } from 'inversify';
|
import { injectable, inject, postConstruct } from 'inversify';
|
||||||
import { Widget } from '@phosphor/widgets';
|
import { Widget } from '@phosphor/widgets';
|
||||||
import { Message } from '@phosphor/messaging';
|
import { Message } from '@phosphor/messaging';
|
||||||
|
import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
||||||
|
import 'react-tabs/style/react-tabs.css';
|
||||||
|
import { Disable } from 'react-disable';
|
||||||
import URI from '@theia/core/lib/common/uri';
|
import URI from '@theia/core/lib/common/uri';
|
||||||
import { Emitter } from '@theia/core/lib/common/event';
|
import { Emitter } from '@theia/core/lib/common/event';
|
||||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||||
@ -15,7 +18,7 @@ import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
|||||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||||
import { AbstractDialog, DialogProps, PreferenceService, PreferenceScope, DialogError, ReactWidget } from '@theia/core/lib/browser';
|
import { AbstractDialog, DialogProps, PreferenceService, PreferenceScope, DialogError, ReactWidget } from '@theia/core/lib/browser';
|
||||||
import { Index } from '../common/types';
|
import { Index } from '../common/types';
|
||||||
import { ConfigService, FileSystemExt } from '../common/protocol';
|
import { ConfigService, FileSystemExt, Network, ProxySettings } from '../common/protocol';
|
||||||
|
|
||||||
export interface Settings extends Index {
|
export interface Settings extends Index {
|
||||||
editorFontSize: number; // `editor.fontSize`
|
editorFontSize: number; // `editor.fontSize`
|
||||||
@ -32,6 +35,7 @@ export interface Settings extends Index {
|
|||||||
|
|
||||||
sketchbookPath: string; // CLI
|
sketchbookPath: string; // CLI
|
||||||
additionalUrls: string[]; // CLI
|
additionalUrls: string[]; // CLI
|
||||||
|
network: Network; // CLI
|
||||||
}
|
}
|
||||||
export namespace Settings {
|
export namespace Settings {
|
||||||
|
|
||||||
@ -40,7 +44,6 @@ export namespace Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
export type SettingsKey = keyof Settings;
|
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class SettingsService {
|
export class SettingsService {
|
||||||
@ -101,7 +104,7 @@ export class SettingsService {
|
|||||||
this.preferenceService.get<boolean>('arduino.language.log', true),
|
this.preferenceService.get<boolean>('arduino.language.log', true),
|
||||||
this.configService.getConfiguration()
|
this.configService.getConfiguration()
|
||||||
]);
|
]);
|
||||||
const { additionalUrls, sketchDirUri } = cliConfig;
|
const { additionalUrls, sketchDirUri, network } = cliConfig;
|
||||||
const sketchbookPath = await this.fileService.fsPath(new URI(sketchDirUri));
|
const sketchbookPath = await this.fileService.fsPath(new URI(sketchDirUri));
|
||||||
return {
|
return {
|
||||||
editorFontSize,
|
editorFontSize,
|
||||||
@ -115,7 +118,8 @@ export class SettingsService {
|
|||||||
verifyAfterUpload,
|
verifyAfterUpload,
|
||||||
enableLsLogs,
|
enableLsLogs,
|
||||||
additionalUrls,
|
additionalUrls,
|
||||||
sketchbookPath
|
sketchbookPath,
|
||||||
|
network
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +179,8 @@ export class SettingsService {
|
|||||||
verifyAfterUpload,
|
verifyAfterUpload,
|
||||||
enableLsLogs,
|
enableLsLogs,
|
||||||
sketchbookPath,
|
sketchbookPath,
|
||||||
additionalUrls
|
additionalUrls,
|
||||||
|
network
|
||||||
} = this._settings;
|
} = this._settings;
|
||||||
const [config, sketchDirUri] = await Promise.all([
|
const [config, sketchDirUri] = await Promise.all([
|
||||||
this.configService.getConfiguration(),
|
this.configService.getConfiguration(),
|
||||||
@ -183,6 +188,7 @@ export class SettingsService {
|
|||||||
]);
|
]);
|
||||||
(config as any).additionalUrls = additionalUrls;
|
(config as any).additionalUrls = additionalUrls;
|
||||||
(config as any).sketchDirUri = sketchDirUri;
|
(config as any).sketchDirUri = sketchDirUri;
|
||||||
|
(config as any).network = network;
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.preferenceService.set('editor.fontSize', editorFontSize, PreferenceScope.User),
|
this.preferenceService.set('editor.fontSize', editorFontSize, PreferenceScope.User),
|
||||||
@ -230,6 +236,21 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
|
|||||||
if (!this.state) {
|
if (!this.state) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
return <Tabs>
|
||||||
|
<TabList>
|
||||||
|
<Tab>Settings</Tab>
|
||||||
|
<Tab>Network</Tab>
|
||||||
|
</TabList>
|
||||||
|
<TabPanel>
|
||||||
|
{this.renderSettings()}
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
{this.renderNetwork()}
|
||||||
|
</TabPanel>
|
||||||
|
</Tabs>;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected renderSettings(): React.ReactNode {
|
||||||
return <div className='content noselect'>
|
return <div className='content noselect'>
|
||||||
Sketchbook location:
|
Sketchbook location:
|
||||||
<div className='flex-line'>
|
<div className='flex-line'>
|
||||||
@ -343,12 +364,106 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
|
|||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected renderNetwork(): React.ReactNode {
|
||||||
|
return <div className='content noselect'>
|
||||||
|
<form>
|
||||||
|
<label className='flex-line'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.network === 'none'}
|
||||||
|
onChange={this.noProxyDidChange} />
|
||||||
|
No proxy
|
||||||
|
</label>
|
||||||
|
<label className='flex-line'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.network !== 'none'}
|
||||||
|
onChange={this.manualProxyDidChange} />
|
||||||
|
Manual proxy configuration
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
{this.renderProxySettings()}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected renderProxySettings(): React.ReactNode {
|
||||||
|
const disabled = this.state.network === 'none';
|
||||||
|
return <Disable disabled={disabled}>
|
||||||
|
<div className='proxy-settings' aria-disabled={disabled}>
|
||||||
|
<form className='flex-line'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.network === 'none' ? true : this.state.network.protocol === 'http'}
|
||||||
|
onChange={this.httpProtocolDidChange} />
|
||||||
|
HTTP
|
||||||
|
<label className='flex-line'>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.network === 'none' ? false : this.state.network.protocol !== 'http'}
|
||||||
|
onChange={this.socksProtocolDidChange} />
|
||||||
|
SOCKS
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
<div className='flex-line proxy-settings'>
|
||||||
|
<div className='column'>
|
||||||
|
<div className='flex-line'>Host name:</div>
|
||||||
|
<div className='flex-line'>Port number:</div>
|
||||||
|
<div className='flex-line'>Username:</div>
|
||||||
|
<div className='flex-line'>Password:</div>
|
||||||
|
</div>
|
||||||
|
<div className='column stretch'>
|
||||||
|
<div className='flex-line'>
|
||||||
|
<input
|
||||||
|
className='theia-input stretch with-margin'
|
||||||
|
type='text'
|
||||||
|
value={this.state.network === 'none' ? '' : this.state.network.hostname}
|
||||||
|
onChange={this.hostnameDidChange} />
|
||||||
|
</div>
|
||||||
|
<div className='flex-line'>
|
||||||
|
<input
|
||||||
|
className='theia-input small with-margin'
|
||||||
|
type='number'
|
||||||
|
pattern='[0-9]'
|
||||||
|
value={this.state.network === 'none' ? '' : this.state.network.port}
|
||||||
|
onKeyDown={this.numbersOnlyKeyDown}
|
||||||
|
onChange={this.portDidChange} />
|
||||||
|
</div>
|
||||||
|
<div className='flex-line'>
|
||||||
|
<input
|
||||||
|
className='theia-input stretch with-margin'
|
||||||
|
type='text'
|
||||||
|
value={this.state.network === 'none' ? '' : this.state.network.username}
|
||||||
|
onChange={this.usernameDidChange} />
|
||||||
|
</div>
|
||||||
|
<div className='flex-line'>
|
||||||
|
<input
|
||||||
|
className='theia-input stretch with-margin'
|
||||||
|
type='password'
|
||||||
|
value={this.state.network === 'none' ? '' : this.state.network.password}
|
||||||
|
onChange={this.passwordDidChange} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Disable>;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isControlKey(event: React.KeyboardEvent<HTMLInputElement>): boolean {
|
||||||
|
return !!event.key && ['tab', 'delete', 'backspace', 'arrowleft', 'arrowright'].some(key => event.key.toLocaleLowerCase() === key);
|
||||||
|
}
|
||||||
|
|
||||||
protected noopKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
protected noopKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (this.isControlKey(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
event.nativeEvent.preventDefault();
|
event.nativeEvent.preventDefault();
|
||||||
event.nativeEvent.returnValue = false;
|
event.nativeEvent.returnValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected numbersOnlyKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
protected numbersOnlyKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (this.isControlKey(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const key = Number(event.key)
|
const key = Number(event.key)
|
||||||
if (isNaN(key) || event.key === null || event.key === ' ') {
|
if (isNaN(key) || event.key === null || event.key === ' ') {
|
||||||
event.nativeEvent.preventDefault();
|
event.nativeEvent.preventDefault();
|
||||||
@ -444,6 +559,79 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
protected noProxyDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (event.target.checked) {
|
||||||
|
this.setState({ network: 'none' });
|
||||||
|
} else {
|
||||||
|
this.setState({ network: Network.Default() });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected manualProxyDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (event.target.checked) {
|
||||||
|
this.setState({ network: Network.Default() });
|
||||||
|
} else {
|
||||||
|
this.setState({ network: 'none' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected httpProtocolDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.protocol = event.target.checked ? 'http' : 'socks';
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected socksProtocolDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.protocol = event.target.checked ? 'socks' : 'http';
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected hostnameDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.hostname = event.target.value;
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected portDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.port = event.target.value;
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected usernameDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.username = event.target.value;
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected passwordDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (this.state.network !== 'none') {
|
||||||
|
const network = this.cloneProxySettings;
|
||||||
|
network.password = event.target.value;
|
||||||
|
this.setState({ network });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private get cloneProxySettings(): ProxySettings {
|
||||||
|
const { network } = this.state;
|
||||||
|
if (network === 'none') {
|
||||||
|
throw new Error('Must be called when proxy is enabled.');
|
||||||
|
}
|
||||||
|
const copyNetwork = deepClone(network);
|
||||||
|
return copyNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
export namespace SettingsComponent {
|
export namespace SettingsComponent {
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
.arduino-settings-dialog .content {
|
.arduino-settings-dialog .content {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-settings-dialog .flex-line {
|
.arduino-settings-dialog .flex-line {
|
||||||
@ -25,19 +26,32 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.arduino-settings-dialog .stretch {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.arduino-settings-dialog .flex-line .theia-button.shrink {
|
.arduino-settings-dialog .flex-line .theia-button.shrink {
|
||||||
min-width: unset;
|
min-width: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-settings-dialog .theia-input.stretch {
|
.arduino-settings-dialog .proxy-settings {
|
||||||
width: 100% !important;
|
margin: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arduino-settings-dialog input[type="radio"] {
|
||||||
|
margin: 3px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arduino-settings-dialog .theia-input.small {
|
.arduino-settings-dialog .theia-input.small {
|
||||||
max-width: 40px;
|
max-width: 50px;
|
||||||
width: 40px;
|
width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.additional-urls-dialog .link:hover {
|
.additional-urls-dialog .link:hover {
|
||||||
color: var(--theia-textLink-activeForeground);
|
color: var(--theia-textLink-activeForeground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.arduino-settings-dialog .react-tabs__tab-list {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
@ -8,11 +8,79 @@ export interface ConfigService {
|
|||||||
isInSketchDir(uri: string): Promise<boolean>;
|
isInSketchDir(uri: string): Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ProxySettings {
|
||||||
|
protocol: string;
|
||||||
|
hostname: string;
|
||||||
|
port: string;
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
export type Network = 'none' | ProxySettings;
|
||||||
|
export namespace Network {
|
||||||
|
|
||||||
|
export function Default(): Network {
|
||||||
|
return {
|
||||||
|
protocol: 'http',
|
||||||
|
hostname: '',
|
||||||
|
port: '',
|
||||||
|
username: '',
|
||||||
|
password: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parse(raw: string | undefined): Network {
|
||||||
|
if (!raw) {
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Patter: PROTOCOL://USER:PASS@HOSTNAME:PORT/
|
||||||
|
const { protocol, hostname, password, username, port } = new URL(raw);
|
||||||
|
return {
|
||||||
|
protocol,
|
||||||
|
hostname,
|
||||||
|
password,
|
||||||
|
username,
|
||||||
|
port
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function stringify(network: Network): string | undefined {
|
||||||
|
if (network === 'none') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const { protocol, hostname, password, username, port } = network;
|
||||||
|
try {
|
||||||
|
const defaultUrl = new URL(`${protocol ? protocol : 'http'}://${hostname ? hostname : '_'}`);
|
||||||
|
return Object.assign(defaultUrl, { protocol, hostname, password, username, port }).toString();
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sameAs(left: Network, right: Network): boolean {
|
||||||
|
if (left === 'none') {
|
||||||
|
return right === 'none';
|
||||||
|
}
|
||||||
|
if (right === 'none') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return left.hostname === right.hostname
|
||||||
|
&& left.password === right.password
|
||||||
|
&& left.protocol === right.protocol
|
||||||
|
&& left.username === right.username;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export interface Config {
|
export interface Config {
|
||||||
readonly sketchDirUri: string;
|
readonly sketchDirUri: string;
|
||||||
readonly dataDirUri: string;
|
readonly dataDirUri: string;
|
||||||
readonly downloadsDirUri: string;
|
readonly downloadsDirUri: string;
|
||||||
readonly additionalUrls: string[];
|
readonly additionalUrls: string[];
|
||||||
|
readonly network: Network;
|
||||||
}
|
}
|
||||||
export namespace Config {
|
export namespace Config {
|
||||||
export function sameAs(left: Config, right: Config): boolean {
|
export function sameAs(left: Config, right: Config): boolean {
|
||||||
@ -28,6 +96,7 @@ export namespace Config {
|
|||||||
}
|
}
|
||||||
return left.dataDirUri === right.dataDirUri
|
return left.dataDirUri === right.dataDirUri
|
||||||
&& left.downloadsDirUri === right.downloadsDirUri
|
&& left.downloadsDirUri === right.downloadsDirUri
|
||||||
&& left.sketchDirUri === right.sketchDirUri;
|
&& left.sketchDirUri === right.sketchDirUri
|
||||||
|
&& Network.sameAs(left.network, right.network);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,11 +92,16 @@ export namespace Logging {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Network {
|
||||||
|
proxy?: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Arduino CLI config scheme
|
// Arduino CLI config scheme
|
||||||
export interface CliConfig {
|
export interface CliConfig {
|
||||||
board_manager?: RecursivePartial<BoardManager>;
|
board_manager?: RecursivePartial<BoardManager>;
|
||||||
directories?: RecursivePartial<Directories>;
|
directories?: RecursivePartial<Directories>;
|
||||||
logging?: RecursivePartial<Logging>;
|
logging?: RecursivePartial<Logging>;
|
||||||
|
network?: RecursivePartial<Network>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bare minimum required CLI config.
|
// Bare minimum required CLI config.
|
||||||
|
@ -11,9 +11,9 @@ import { ILogger } from '@theia/core/lib/common/logger';
|
|||||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||||
import { Event, Emitter } from '@theia/core/lib/common/event';
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||||
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
||||||
import { ConfigService, Config, NotificationServiceServer } from '../common/protocol';
|
import { ConfigService, Config, NotificationServiceServer, Network } from '../common/protocol';
|
||||||
import { spawnCommand } from './exec-util';
|
import { spawnCommand } from './exec-util';
|
||||||
import { RawData, WriteRequest } from './cli-protocol/settings/settings_pb';
|
import { WriteRequest, RawData } from './cli-protocol/settings/settings_pb';
|
||||||
import { SettingsClient } from './cli-protocol/settings/settings_grpc_pb';
|
import { SettingsClient } from './cli-protocol/settings/settings_grpc_pb';
|
||||||
import * as serviceGrpcPb from './cli-protocol/settings/settings_grpc_pb';
|
import * as serviceGrpcPb from './cli-protocol/settings/settings_grpc_pb';
|
||||||
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
|
import { ArduinoDaemonImpl } from './arduino-daemon-impl';
|
||||||
@ -78,7 +78,7 @@ export class ConfigServiceImpl implements BackendApplicationContribution, Config
|
|||||||
if (!copyDefaultCliConfig) {
|
if (!copyDefaultCliConfig) {
|
||||||
copyDefaultCliConfig = await this.getFallbackCliConfig();
|
copyDefaultCliConfig = await this.getFallbackCliConfig();
|
||||||
}
|
}
|
||||||
const { additionalUrls, dataDirUri, downloadsDirUri, sketchDirUri } = config;
|
const { additionalUrls, dataDirUri, downloadsDirUri, sketchDirUri, network } = config;
|
||||||
copyDefaultCliConfig.directories = {
|
copyDefaultCliConfig.directories = {
|
||||||
data: FileUri.fsPath(dataDirUri),
|
data: FileUri.fsPath(dataDirUri),
|
||||||
downloads: FileUri.fsPath(downloadsDirUri),
|
downloads: FileUri.fsPath(downloadsDirUri),
|
||||||
@ -89,6 +89,8 @@ export class ConfigServiceImpl implements BackendApplicationContribution, Config
|
|||||||
...additionalUrls
|
...additionalUrls
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
const proxy = Network.stringify(network);
|
||||||
|
copyDefaultCliConfig.network = { proxy };
|
||||||
const { port } = copyDefaultCliConfig.daemon;
|
const { port } = copyDefaultCliConfig.daemon;
|
||||||
await this.updateDaemon(port, copyDefaultCliConfig);
|
await this.updateDaemon(port, copyDefaultCliConfig);
|
||||||
await this.writeDaemonState(port);
|
await this.writeDaemonState(port);
|
||||||
@ -175,11 +177,13 @@ export class ConfigServiceImpl implements BackendApplicationContribution, Config
|
|||||||
if (cliConfig.board_manager && cliConfig.board_manager.additional_urls) {
|
if (cliConfig.board_manager && cliConfig.board_manager.additional_urls) {
|
||||||
additionalUrls.push(...Array.from(new Set(cliConfig.board_manager.additional_urls)));
|
additionalUrls.push(...Array.from(new Set(cliConfig.board_manager.additional_urls)));
|
||||||
}
|
}
|
||||||
|
const network = Network.parse(cliConfig.network?.proxy);
|
||||||
return {
|
return {
|
||||||
dataDirUri: FileUri.create(data).toString(),
|
dataDirUri: FileUri.create(data).toString(),
|
||||||
sketchDirUri: FileUri.create(user).toString(),
|
sketchDirUri: FileUri.create(user).toString(),
|
||||||
downloadsDirUri: FileUri.create(downloads).toString(),
|
downloadsDirUri: FileUri.create(downloads).toString(),
|
||||||
additionalUrls,
|
additionalUrls,
|
||||||
|
network
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +199,9 @@ export class ConfigServiceImpl implements BackendApplicationContribution, Config
|
|||||||
protected async updateDaemon(port: string | number, config: DefaultCliConfig): Promise<void> {
|
protected async updateDaemon(port: string | number, config: DefaultCliConfig): Promise<void> {
|
||||||
const client = this.createClient(port);
|
const client = this.createClient(port);
|
||||||
const data = new RawData();
|
const data = new RawData();
|
||||||
data.setJsondata(JSON.stringify(config, null, 2));
|
const json = JSON.stringify(config, null, 2);
|
||||||
|
data.setJsondata(json);
|
||||||
|
console.log(`Updating daemon with 'data': ${json}`);
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
client.merge(data, error => {
|
client.merge(data, error => {
|
||||||
try {
|
try {
|
||||||
|
24
yarn.lock
24
yarn.lock
@ -2825,6 +2825,13 @@
|
|||||||
"@types/react-dom" "*"
|
"@types/react-dom" "*"
|
||||||
"@types/react-transition-group" "*"
|
"@types/react-transition-group" "*"
|
||||||
|
|
||||||
|
"@types/react-tabs@^2.3.2":
|
||||||
|
version "2.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-tabs/-/react-tabs-2.3.2.tgz#99fb6866bbc6912d44f7bbc99eca03fbbd217960"
|
||||||
|
integrity sha512-QfMelaJSdMcp+CenKhATp12XFFqqUcLXILgwpX3dgWfVYNZPtsLXZDDCRsVn+kwmBOWB+DFPKpQorxbUhnXINw==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react-transition-group@*":
|
"@types/react-transition-group@*":
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"
|
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d"
|
||||||
@ -5527,7 +5534,7 @@ cloneable-readable@^1.0.0:
|
|||||||
process-nextick-args "^2.0.0"
|
process-nextick-args "^2.0.0"
|
||||||
readable-stream "^2.3.5"
|
readable-stream "^2.3.5"
|
||||||
|
|
||||||
clsx@^1.0.4:
|
clsx@^1.0.4, clsx@^1.1.0:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||||
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
|
||||||
@ -12290,7 +12297,7 @@ promzard@^0.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
read "1"
|
read "1"
|
||||||
|
|
||||||
prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
prop-types@^15.5.0, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||||
version "15.7.2"
|
version "15.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||||
@ -12560,6 +12567,11 @@ react-autosize-textarea@^7.0.0:
|
|||||||
line-height "^0.3.1"
|
line-height "^0.3.1"
|
||||||
prop-types "^15.5.6"
|
prop-types "^15.5.6"
|
||||||
|
|
||||||
|
react-disable@^0.1.0:
|
||||||
|
version "0.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-disable/-/react-disable-0.1.0.tgz#e3474aefcb2b91fcb534693c66b7497fb28b85af"
|
||||||
|
integrity sha512-3RbSYuUtakIy1ulCfDf6yoJAsjHFNLv467bSBwyxkNDyez/z7CbcTZ6QUWCrhfybvfm81IN6QT3pUfDoKcvaFQ==
|
||||||
|
|
||||||
react-dom@^16.8.0:
|
react-dom@^16.8.0:
|
||||||
version "16.14.0"
|
version "16.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
|
||||||
@ -12609,6 +12621,14 @@ react-select@^3.0.4:
|
|||||||
react-input-autosize "^2.2.2"
|
react-input-autosize "^2.2.2"
|
||||||
react-transition-group "^4.3.0"
|
react-transition-group "^4.3.0"
|
||||||
|
|
||||||
|
react-tabs@^3.1.2:
|
||||||
|
version "3.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-3.1.2.tgz#9047ad7d8a53d357a67c14ad4c4a64cc16660fa8"
|
||||||
|
integrity sha512-OKS1l7QzSNcn+L2uFsxyGFHdXp9YsPGf/YOURWcImp7xLN36n0Wz+/j9HwlwGtlXCZexwshScR5BrcFbw/3P9Q==
|
||||||
|
dependencies:
|
||||||
|
clsx "^1.1.0"
|
||||||
|
prop-types "^15.5.0"
|
||||||
|
|
||||||
react-transition-group@^4.3.0:
|
react-transition-group@^4.3.0:
|
||||||
version "4.4.1"
|
version "4.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user