Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Build

on:
push:
branches: main
branches: ["main"]
pull_request:
branches: '*'
branches: ["*"]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
Expand Down
13 changes: 0 additions & 13 deletions .github/workflows/enforce-label.yml

This file was deleted.

18 changes: 8 additions & 10 deletions src/bluetooth-extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
console.log('JupyterLab bluetooth-sidebar plugin is activated!');
const trans = translator.load('jupyterlab');
const { commands } = app;
const openDeviceRegistryDialogLabel = trans.__(
'Add a Device'
);
const openDeviceRegistryDialogLabel = trans.__('Add a Device');
let runningItemsList: Array<IRunningSessions.IRunningItem>;

app.commands.addCommand(CommandIDs.disconnectDevice, {
execute: (args) => {
const selectedDevice= bluetoothManager.deviceList.find((device) => device.native.id === args.deviceID as string);
execute: args => {
const selectedDevice = bluetoothManager.deviceList.find(
device => device.native.id === (args.deviceID as string)
);
if (selectedDevice) {
bluetoothManager.disconnectDevice(selectedDevice);
return selectedDevice;
Expand All @@ -83,7 +83,6 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
label: trans.__('Disconnect Device')
});


app.commands.addCommand(CommandIDs.openDeviceRegistryDialog, {
execute: async () => {
showDialog({
Expand All @@ -107,7 +106,6 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
}
});


managers.add({
name: trans.__('Bluetooth Devices'),
supportsMultipleViews: false,
Expand All @@ -121,8 +119,7 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {
commands
)
);
}
);
});
return runningItemsList;
},
shutdownAll: () => {
Expand Down Expand Up @@ -152,7 +149,8 @@ const BluetoothSidebarPlugin: JupyterFrontEndPlugin<void> = {

export class DropDownRegistry
extends Widget
implements Dialog.IBodyWidget<string> {
implements Dialog.IBodyWidget<string>
{
constructor(registry: BluetoothManager.DeviceRegistry) {
super();
this._selectList = document.createElement('select');
Expand Down
17 changes: 11 additions & 6 deletions src/bluetooth/BluetoothDeviceRunningItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ import { CommandRegistry } from '@lumino/commands';
export const disconnectDevice = 'bluetooth-manager:disconnect-device';

export class BluetoothDeviceRunningItem
implements IRunningSessions.IRunningItem {
constructor(device: BluetoothManager.Device, bluetoothManager: BluetoothManager, commands: CommandRegistry) {
implements IRunningSessions.IRunningItem
{
constructor(
device: BluetoothManager.Device,
bluetoothManager: BluetoothManager,
commands: CommandRegistry
) {
this._device = device;
this.bluetoothManager = bluetoothManager;
if (this._device.native.name) {
Expand All @@ -24,11 +29,11 @@ export class BluetoothDeviceRunningItem
open() {
const commands = this.commands;
const deviceID = this._device.native.id;
const menu = new Menu({ commands: commands })
const menu = new Menu({ commands: commands });
this._device.contextCommands.map((command: string) => {
menu.addItem({ command: command, args: {deviceID}})
})
menu.addClass('jp-bluetooth-device-running-item-menu')
menu.addItem({ command: command, args: { deviceID } });
});
menu.addClass('jp-bluetooth-device-running-item-menu');
const deviceElement = document.querySelector(`.${this.className}`);
if (deviceElement) {
const rect = deviceElement.getBoundingClientRect();
Expand Down
71 changes: 36 additions & 35 deletions src/bluetooth/BluetoothManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { buildCompleteIdentifier } from '../bluetooth-extension';
import { IDisposable } from '@lumino/disposable';
import { Dialog, showDialog } from '@jupyterlab/apputils';


/**
* A class used to update the list of connected device and the related signals used to rerender the connected devices section.
*/
Expand Down Expand Up @@ -101,29 +100,24 @@ export class BluetoothManager implements IBluetoothManager {
const isWebBluetoothSupported: boolean = navigator.bluetooth ? true : false;
if (isWebBluetoothSupported === false) {
showDialog({
title: ('Error'),
body: (
'Web Bluetooth is not supported on your browser. It works on Chrome and Edge (Firefox and Explorer are not supported). \n Please also check that the Web Bluetooth flag is properly set to enabled in the Chrome flags (chrome://flags/).'
),
buttons: [
Dialog.okButton({ label: ('Close') })
]
title: 'Error',
body: 'Web Bluetooth is not supported on your browser. It works on Chrome and Edge (Firefox and Explorer are not supported). \n Please also check that the Web Bluetooth flag is properly set to enabled in the Chrome flags (chrome://flags/).',
buttons: [Dialog.okButton({ label: 'Close' })]
});
}
return isWebBluetoothSupported
return isWebBluetoothSupported;
}

async requestDevice(
registryItem: IDeviceRegistryItem
): Promise<BluetoothDevice | undefined> {
const isWebBluetoothSupported = await this.checkWebBluetoothSupport()
const isWebBluetoothSupported = await this.checkWebBluetoothSupport();
if (isWebBluetoothSupported) {
const native = await navigator.bluetooth.requestDevice(
registryItem.options
);
return native;
}
else {
} else {
return;
}
}
Expand All @@ -146,15 +140,18 @@ export namespace BluetoothManager {
public connected: Signal<this, boolean>;
public disconnected: Signal<this, boolean>;
public isDisposed: boolean;
public contextCommands:Array<string>;
public contextCommands: Array<string>;

constructor(native: BluetoothDevice) {
this.connected = new Signal<this, boolean>(this);
this.disconnected = new Signal<this, boolean>(this);
this.isConnected = false;
this.isDisposed = false;
this.native = native;
this.contextCommands = ['bluetooth-manager:disconnect-device', 'bluetooth-manager:add-lego-movehub-control-panel']
this.contextCommands = [
'bluetooth-manager:disconnect-device',
'bluetooth-manager:add-lego-movehub-control-panel'
];
}

async connectAndGetAllServices(): Promise<
Expand All @@ -164,40 +161,45 @@ export namespace BluetoothManager {
this.isConnected = false;
this.disconnected.emit(true);
});
const server = this.native.gatt
const server = this.native.gatt;
if (server) {
const timeout = 5000;
const connectWithTimeout = new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(
new Error('Connection to GATT server timed out'));
const timeoutId = setTimeout(() => {
reject(new Error('Connection to GATT server timed out'));
server.disconnect();
this.dispose();
}, timeout);

server.connect().then(async () => {
clearTimeout(timeoutId);
resolve();
this.isConnected = true;
this.connected.emit(true);
})
.catch((error) => {
server
.connect()
.then(async () => {
clearTimeout(timeoutId);
resolve();
this.isConnected = true;
this.connected.emit(true);
})
.catch(error => {
server.disconnect();
reject(error);
});
});
await connectWithTimeout
await connectWithTimeout;
if (server.connected === true) {
const services = await server.getPrimaryServices();
if (!services || services.length === 0) {
throw new Error('Server exists but no service found on the device.');
} else { return services; }
}
else {
throw new Error('There is no connection to server. No attempt to get a service.')
throw new Error(
'Server exists but no service found on the device.'
);
} else {
return services;
}
} else {
throw new Error(
'There is no connection to server. No attempt to get a service.'
);
}
}
else {
} else {
throw new Error('Server is not defined.');
}
}
Expand Down Expand Up @@ -256,7 +258,7 @@ export namespace BluetoothManager {
if (service) {
return service.getCharacteristics();
} else {
throw new Error('The requested service is not available.')
throw new Error('The requested service is not available.');
}
}

Expand All @@ -267,7 +269,6 @@ export namespace BluetoothManager {
const service = await this.getService(serviceUUID);
if (service) {
return service.getCharacteristic(characteristicUUID);

} else {
throw new Error('The requested service is not available.');
}
Expand Down
2 changes: 0 additions & 2 deletions src/bluetooth/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ export const LegoBrickIcon = new LabIcon({
name: '@jupyterlab/bluetooh-manager:bluetooth-lego-brick',
svgstr: LegoBrickSvgstr
});
;

export const GreenCircle = new LabIcon({
name: '@jupyterlab/bluetooh-manager:bluetooth-green-circle',
svgstr: GreenCircleSvgstr
Expand Down
52 changes: 30 additions & 22 deletions src/movehub-extension/components/BatteryGauge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ const batteryCustomizationLight = {
lowBatteryColor: 'red',
fontFamily: 'Helvetica',
fontSize: 20,
showPercentage: true // Set to true to show battery percentage
},
showPercentage: true // Set to true to show battery percentage
}
};

const batteryCustomizationDark = {
Expand Down Expand Up @@ -72,11 +72,14 @@ const batteryCustomizationDark = {
lowBatteryColor: 'red',
fontFamily: 'Helvetica',
fontSize: 20,
showPercentage: true // Set to true to show battery percentage
},
showPercentage: true // Set to true to show battery percentage
}
};

export default function BatteryComponent({ device, themeManager }: IMoveHubPanelWithThemeProps) {
export default function BatteryComponent({
device,
themeManager
}: IMoveHubPanelWithThemeProps) {
const [deviceState, setDeviceState] = useState<DeviceInfo>(defaultDeviceInfo);
const theme = themeManager.theme;
console.log('theme:', theme);
Expand Down Expand Up @@ -106,45 +109,50 @@ export default function BatteryComponent({ device, themeManager }: IMoveHubPanel
const isThemeLight = themeManager.isLight(theme);
return (
<UseSignal signal={themeManager.themeChanged}>
{(): JSX.Element => (
{(): JSX.Element =>
deviceState.batteryLevel !== undefined &&
deviceState.connected === true ? (
deviceState.connected === true ? (
<BatteryGauge
value={deviceState.batteryLevel}
width={'50px'}
customization={isThemeLight ? batteryCustomizationLight : batteryCustomizationDark}

customization={
isThemeLight
? batteryCustomizationLight
: batteryCustomizationDark
}
/>
) : (
<div></div>
)
)}
}
</UseSignal>
);
} else {
return (
deviceState.batteryLevel !== undefined &&
deviceState.connected === true ? (
<BatteryGauge
value={deviceState.batteryLevel}
customization={batteryCustomizationLight}

/>) : (<div></div>)
)
return deviceState.batteryLevel !== undefined &&
deviceState.connected === true ? (
<BatteryGauge
value={deviceState.batteryLevel}
customization={batteryCustomizationLight}
/>
) : (
<div></div>
);
}
}

export class BatteryWidget extends ReactWidget {
public device: MoveHub;
public themeManager: IThemeManager
public themeManager: IThemeManager;

constructor(device: MoveHub, themeManager: IThemeManager) {
super();
this.device = device;
this.themeManager = themeManager
this.themeManager = themeManager;
}

render() {
return <BatteryComponent device={this.device} themeManager={this.themeManager} />;
return (
<BatteryComponent device={this.device} themeManager={this.themeManager} />
);
}
}
Loading
Loading