Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release of v4.10.1. #294

Merged
merged 4 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"*.{css,sass,scss}.d.ts": true
},
"cSpell.words": [
"abcdefghijklmnopqurstuvwxyz",
"Applyable",
"autorun",
"autoscroll",
Expand Down
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

## [4.10.1] - 2023-11-13

### Fixed

- Fixed bug which caused fatal error in JS if app was opened after local storage was cleared.
- Fixed MobX console warning.

### Changed

- If no configs exist in the browser's local store, default-created config will be saved back to store even if no changes are made.
- Removed unneeded console.log messages.

## [4.10.0] - 2023-11-12

### Added
Expand Down Expand Up @@ -576,7 +588,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added auto-scroll to TX pane, closes #89.
- Added special delete behaviour for backspace button when in "send on enter" mode, closes #90.

[unreleased]: https://github.com/gbmhunter/NinjaTerm/compare/v4.10.0...HEAD
[unreleased]: https://github.com/gbmhunter/NinjaTerm/compare/v4.10.1...HEAD
[4.10.1]: https://github.com/gbmhunter/NinjaTerm/compare/v4.9.0...v4.10.1
[4.10.0]: https://github.com/gbmhunter/NinjaTerm/compare/v4.9.0...v4.10.0
[4.9.0]: https://github.com/gbmhunter/NinjaTerm/compare/v4.8.0...v4.9.0
[4.8.0]: https://github.com/gbmhunter/NinjaTerm/compare/v4.7.0...v4.8.0
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ninjaterm",
"version": "4.10.0",
"version": "4.10.1",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
Expand Down
50 changes: 13 additions & 37 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,15 @@ export class App {
// getPorts() returns ports that the user has previously approved
// this app to be able to access
let approvedPorts = await navigator.serial.getPorts();
console.log('ports: ', approvedPorts);

// const lastUsedSerialPort = this.appStorage.data.lastUsedSerialPort;
const lastUsedSerialPort: LastUsedSerialPort = this.appStorage.getData('lastUsedSerialPort') as LastUsedSerialPort;
if (lastUsedSerialPort === null) {
console.log('Did not find last used serial port in local storage.');
// Did not find last used serial port data in local storage, so do nothing
return;
}

const lastUsedPortInfoStr = JSON.stringify(lastUsedSerialPort.serialPortInfo);
console.log('lastUsedPortInfoStr=', lastUsedPortInfoStr);
// If the JSON representation of the last used port is just "{}",
// it means that the last used port didn't contain any valuable
// information to uniquely identify it, so don't bother trying to
Expand All @@ -234,7 +232,6 @@ export class App {
const approvedPortInfo = approvedPort.getInfo();
const approvedPortInfoStr = JSON.stringify(approvedPort.getInfo());
if (approvedPortInfoStr === lastUsedPortInfoStr) {
console.log('Found a match, opening port. portInfo=', approvedPortInfoStr);
// Found a match, open it
runInAction(async () => {
this.port = approvedPort;
Expand Down Expand Up @@ -289,14 +286,19 @@ export class App {
this.serialPortInfo = this.port.getInfo();
// Save the info for this port, so we can automatically re-open
// it on app re-open in the future
const lastUsedSerialPort: LastUsedSerialPort = this.appStorage.getData('lastUsedSerialPort');
let lastUsedSerialPort: LastUsedSerialPort = this.appStorage.getData('lastUsedSerialPort');
if (lastUsedSerialPort === null) {
lastUsedSerialPort = new LastUsedSerialPort();
}
lastUsedSerialPort.serialPortInfo = this.serialPortInfo;
this.appStorage.saveData('lastUsedSerialPort', lastUsedSerialPort);

});
if (this.settings.portConfiguration.connectToSerialPortAsSoonAsItIsSelected) {
await this.openPort();
this.portState = PortState.OPENED;
runInAction(() => {
this.portState = PortState.OPENED;
});
// Goto the terminal pane
this.setShownMainPane(MainPanes.TERMINAL);
}
Expand Down Expand Up @@ -345,18 +347,17 @@ export class App {
if (printSuccessMsg) {
this.snackbar.sendToSnackbar('Serial port opened.', 'success');
}
this.portState = PortState.OPENED;
// This will automatically close the settings window if the user is currently in it,
// clicks "Open" and the port opens successfully.
if (this.closeSettingsDialogOnPortOpenOrClose) {
this.setSettingsDialogOpen(false);
}

this.keepReading = true;
this.closedPromise = this.readUntilClosed();

// this.appStorage.data.lastUsedSerialPort.portState = PortState.OPENED;
// this.appStorage.saveData();
runInAction(() => {
this.portState = PortState.OPENED;
this.keepReading = true;
this.closedPromise = this.readUntilClosed();
});

const lastUsedSerialPort: LastUsedSerialPort = this.appStorage.getData('lastUsedSerialPort');
lastUsedSerialPort.portState = PortState.OPENED;
Expand Down Expand Up @@ -435,22 +436,12 @@ export class App {
} else {
this.snackbar.sendToSnackbar(`Serial port was removed unexpectedly.\nReturned error from reader.read():\n${error}`, 'error');
}

// this.setPortState(PortState.CLOSED);
// runInAction(() => {
// // Setting this.port to null means the port needs to be
// // reselected in the UI (which makes sense because we just
// // lost it)
// // this.port = null;
// // this.closedPromise = null;
// });
} finally {
// Allow the serial port to be closed later.
this.reader.releaseLock();
}
}

console.log('GOT HERE! Closing port.... keepReading: ', this.keepReading);
await this.port!.close();

// If keepReading is true, this means close() was not called, and it's an unexpected
Expand All @@ -468,8 +459,6 @@ export class App {
// have been removed/disappeared
this.port = null;
}

console.log('readUntilClosed() finished.');
}

setPortState(newPortState: PortState) {
Expand All @@ -496,7 +485,6 @@ export class App {
}

async closePort(goToReopenState = false) {
console.log('closePort() called.')
if (this.lastSelectedPortType === PortType.REAL) {
this.keepReading = false;
// Force reader.read() to resolve immediately and subsequently
Expand Down Expand Up @@ -535,18 +523,6 @@ export class App {
this.portState = PortState.CLOSED;
}

// async setPortState(newPortState: PortState) {
// if (newPortState === PortState.CLOSED) {
// await this.closePort();
// } else if (newPortState === PortState.CLOSED_BUT_WILL_REOPEN) {
// // this.closeButWillReopenPort();
// } else if (newPortState === PortState.OPENED) {
// await this.openPort();
// } else {
// throw Error('Unsupported port state!');
// }
// }

/**
* This is called from either the TX/RX terminal or TX terminal
* (i.e. any terminal pane that is allowed to send data). This function
Expand Down
4 changes: 0 additions & 4 deletions src/AppView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,9 @@ declare global {

window.app = app;

console.log('TEST')

const AppView = observer((props: Props) => {

useEffect(() => {
console.log('useEffect1() called.');
// We need to register the service worker AFTER the app
// has rendered, because it we do it before we won't
// be able to enqueue a snackbar to tell the user there
Expand All @@ -119,7 +116,6 @@ const AppView = observer((props: Props) => {
})

const initFn = async () => {
console.log('Calling init()...');
await app.onAppUiLoaded();
}

Expand Down
51 changes: 40 additions & 11 deletions src/Storage/AppStorage.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
import { expect, test } from 'vitest'
import { expect, test, describe, beforeEach } from 'vitest'

import AppStorage from './AppStorage';

test('get config returns null when nothing stored there', () => {
const appStorage = new AppStorage();
const value = appStorage.getConfig(['prop1', 'prop2']);
expect(value).toEqual(null);
beforeEach(() => {
// Clear local storage, because otherwise jsdom persists storage
// between tests
window.localStorage.clear();
})

test('basic get and set works', () => {
const appStorage = new AppStorage();
appStorage.saveConfig(['prop1', 'prop2'], 'hello');
const value = appStorage.getConfig(['prop1', 'prop2']);
expect(value).toEqual('hello');
})
describe('config tests', () => {
test('get config returns null when nothing stored there', () => {
const appStorage = new AppStorage();
const value = appStorage.getConfig(['prop1', 'prop2']);
expect(value).toEqual(null);
})

test('basic get and set works', () => {
const appStorage = new AppStorage();
appStorage.saveConfig(['prop1', 'prop2'], 'hello');
const value = appStorage.getConfig(['prop1', 'prop2']);
expect(value).toEqual('hello');
})

test('can get parent key and see child', () => {
const appStorage = new AppStorage();
appStorage.saveConfig(['prop1', 'prop2'], 'hello');
const value = appStorage.getConfig(['prop1']);
expect(value).toEqual({ prop2: 'hello' });
})

test('can read back root config', () => {
const appStorage = new AppStorage();
appStorage.saveConfig(['prop1', 'prop2'], 'hello');
const value = appStorage.getConfig([]);
expect(value).toEqual({ prop1: { prop2: 'hello' } });
})

test('can set root config', () => {
const appStorage = new AppStorage();
appStorage.saveConfig([], 'hello');
const value = appStorage.getConfig([]);
expect(value).toEqual('hello');
})
});
18 changes: 17 additions & 1 deletion src/Storage/AppStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ class Config {
configData: any = {};
}

/**
* This class manages the local storage (persistance browser based key/object data store)
* for the application. It is used to store both general data (saveData/getData) and configurations
* (saveConfig/getConfig).
*/
export default class AppStorage {

configs: Config[] = [];
Expand All @@ -14,8 +19,13 @@ export default class AppStorage {
// Read in configurations
const configsStr = window.localStorage.getItem('configs');
if (configsStr === null) {
// No config key found in users store, create one!
const defaultConfig = new Config();
this.configs.push(defaultConfig);
// Save just-created config back to store. Not strictly needed as it
// will be saved as soon as any changes are made, but this feels
// cleaner.
window.localStorage.setItem('configs', JSON.stringify(this.configs));
} else {
this.configs = JSON.parse(configsStr);
}
Expand Down Expand Up @@ -50,7 +60,13 @@ export default class AppStorage {
}
obj = obj[key];
}
obj[keys[keys.length - 1]] = data;
// If no keys were provided, we are writing to the entire
// config object
if (keys.length === 0) {
this.activeConfig.configData = data;
} else {
obj[keys[keys.length - 1]] = data;
}
window.localStorage.setItem('configs', JSON.stringify(this.configs));
}

Expand Down