<commit_before>import { Action, Selector, State, StateContext } from '@ngxs/store';
import { of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { AbstractDevice, DeviceParams } from './abstract-device';
import {
  BLEConnectionLost,
  ConnectDevice,
  DeviceConnectionLost,
  DevicesDiscovered,
  DisconnectDevice,
  EditDeviceParams,
  SaveDeviceParams,
  StartDiscoverDevices,
  StopDiscoverDevices,
  UpdateDevice,
  UpdateDeviceInfo
} from './devices.action';
import { DevicesService } from './devices.service';

export interface DevicesStateModel {
  isScanning: boolean;
  availableDevices: AbstractDevice[];
  knownDevices: AbstractDevice[];
  connectedDevice?: AbstractDevice;
  editedDevice?: AbstractDevice;
  editedDeviceForm?: {
    model: DeviceParams;
    dirty: boolean;
    status: string;
    errors: any;
  };
}

@State<DevicesStateModel>({
  name: 'devices',
  defaults: {
    isScanning: false,
    availableDevices: [],
    knownDevices: []
  }
})
export class DevicesState {
  constructor(private devicesService: DevicesService) {}

  @Selector()
  static availableDevices(state: DevicesStateModel): AbstractDevice[] {
    return state.availableDevices.filter(
      availableDevice =>
        state.connectedDevice === undefined || state.connectedDevice.sensorUUID !== availableDevice.sensorUUID
    );
  }

  @Selector()
  static knownDevices(state: DevicesStateModel): AbstractDevice[] {
    return state.knownDevices.filter(knownDevice => {
      return (
        state.availableDevices.every(availableDevice => availableDevice.sensorUUID !== knownDevice.sensorUUID) &&
        (state.connectedDevice === undefined || state.connectedDevice.sensorUUID !== knownDevice.sensorUUID)
      );
    });
  }

  @Selector()
  static connectedDevice(state: DevicesStateModel): AbstractDevice | undefined {
    return state.connectedDevice;
  }

  @Selector()
  static isScanning(state: DevicesStateModel): boolean {
    return state.isScanning;
  }

  @Selector()
  static editedDevice(state: DevicesStateModel): AbstractDevice | undefined {
    return state.editedDevice;
  }

  @Action(StartDiscoverDevices, { cancelUncompleted: true })
  startDiscoverDevices({ patchState }: StateContext<DevicesStateModel>) {
    return this.devicesService.startDiscoverDevices().pipe(
      tap(() =>
        patchState({
          isScanning: true
        })
      )
    );
  }

  @Action(StopDiscoverDevices)
  stopDiscoverDevices({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      isScanning: false,
      availableDevices: []
    });
  }

  @Action(BLEConnectionLost)
  bleConnectionLost({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      isScanning: false,
      availableDevices: []
    });
  }

  @Action(DevicesDiscovered)
  devicesDiscovered({ getState, patchState }: StateContext<DevicesStateModel>, { devices }: DevicesDiscovered) {
    const { knownDevices } = getState();
    patchState({
      availableDevices: [
        ...devices.map(device => ({
          ...(knownDevices.find(knownDevice => knownDevice.sensorUUID === device.sensorUUID) || device),
          batteryLevel: device.batteryLevel
        }))
      ]
    });
  }

  @Action(ConnectDevice, { cancelUncompleted: true })
  connectDevice({ getState, patchState }: StateContext<DevicesStateModel>, { device }: ConnectDevice) {
    const { knownDevices, connectedDevice } = getState();
    if (connectedDevice) {
      this.devicesService.disconnectDevice(connectedDevice).pipe(
        tap(() => {
          patchState({
            connectedDevice: undefined
          });
        })
      );
    }
    return this.devicesService.connectDevice(device).pipe(
      tap(() => {
        if (knownDevices.find(knownDevice => knownDevice.sensorUUID === device.sensorUUID)) {
          patchState({
            connectedDevice: device
          });
        } else {
          patchState({
            connectedDevice: device,
            knownDevices: [...knownDevices, device]
          });
        }
      })
    );
  }

  @Action(DeviceConnectionLost)
  deviceConnectionLost({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      connectedDevice: undefined
    });
  }

  @Action(DisconnectDevice)
  disconnectDevice({ getState, patchState }: StateContext<DevicesStateModel>) {
    const { connectedDevice } = getState();
    if (connectedDevice) {
      return this.devicesService.disconnectDevice(connectedDevice).pipe(
        tap(() => {
          patchState({
            connectedDevice: undefined
          });
        })
      );
    } else {
      return of();<commit_msg>Disconnect previous sensor at connection<commit_after>import { Action, Selector, State, StateContext } from '@ngxs/store';
import { of } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { AbstractDevice, DeviceParams } from './abstract-device';
import {
  BLEConnectionLost,
  ConnectDevice,
  DeviceConnectionLost,
  DevicesDiscovered,
  DisconnectDevice,
  EditDeviceParams,
  SaveDeviceParams,
  StartDiscoverDevices,
  StopDiscoverDevices,
  UpdateDevice,
  UpdateDeviceInfo
} from './devices.action';
import { DevicesService } from './devices.service';

export interface DevicesStateModel {
  isScanning: boolean;
  availableDevices: AbstractDevice[];
  knownDevices: AbstractDevice[];
  connectedDevice?: AbstractDevice;
  editedDevice?: AbstractDevice;
  editedDeviceForm?: {
    model: DeviceParams;
    dirty: boolean;
    status: string;
    errors: any;
  };
}

@State<DevicesStateModel>({
  name: 'devices',
  defaults: {
    isScanning: false,
    availableDevices: [],
    knownDevices: []
  }
})
export class DevicesState {
  constructor(private devicesService: DevicesService) {}

  @Selector()
  static availableDevices(state: DevicesStateModel): AbstractDevice[] {
    return state.availableDevices.filter(
      availableDevice =>
        state.connectedDevice === undefined || state.connectedDevice.sensorUUID !== availableDevice.sensorUUID
    );
  }

  @Selector()
  static knownDevices(state: DevicesStateModel): AbstractDevice[] {
    return state.knownDevices.filter(knownDevice => {
      return (
        state.availableDevices.every(availableDevice => availableDevice.sensorUUID !== knownDevice.sensorUUID) &&
        (state.connectedDevice === undefined || state.connectedDevice.sensorUUID !== knownDevice.sensorUUID)
      );
    });
  }

  @Selector()
  static connectedDevice(state: DevicesStateModel): AbstractDevice | undefined {
    return state.connectedDevice;
  }

  @Selector()
  static isScanning(state: DevicesStateModel): boolean {
    return state.isScanning;
  }

  @Selector()
  static editedDevice(state: DevicesStateModel): AbstractDevice | undefined {
    return state.editedDevice;
  }

  @Action(StartDiscoverDevices, { cancelUncompleted: true })
  startDiscoverDevices({ patchState }: StateContext<DevicesStateModel>) {
    return this.devicesService.startDiscoverDevices().pipe(
      tap(() =>
        patchState({
          isScanning: true
        })
      )
    );
  }

  @Action(StopDiscoverDevices)
  stopDiscoverDevices({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      isScanning: false,
      availableDevices: []
    });
  }

  @Action(BLEConnectionLost)
  bleConnectionLost({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      isScanning: false,
      availableDevices: []
    });
  }

  @Action(DevicesDiscovered)
  devicesDiscovered({ getState, patchState }: StateContext<DevicesStateModel>, { devices }: DevicesDiscovered) {
    const { knownDevices } = getState();
    patchState({
      availableDevices: [
        ...devices.map(device => ({
          ...(knownDevices.find(knownDevice => knownDevice.sensorUUID === device.sensorUUID) || device),
          batteryLevel: device.batteryLevel
        }))
      ]
    });
  }

  @Action(ConnectDevice, { cancelUncompleted: true })
  connectDevice({ getState, patchState, dispatch }: StateContext<DevicesStateModel>, { device }: ConnectDevice) {
    return dispatch(new DisconnectDevice()).pipe(() => {
      return this.devicesService.connectDevice(device).pipe(
        tap(() => {
          const { knownDevices } = getState();
          if (knownDevices.find(knownDevice => knownDevice.sensorUUID === device.sensorUUID)) {
            patchState({
              connectedDevice: device
            });
          } else {
            patchState({
              connectedDevice: device,
              knownDevices: [...knownDevices, device]
            });
          }
        })
      );
    });
  }

  @Action(DeviceConnectionLost)
  deviceConnectionLost({ patchState }: StateContext<DevicesStateModel>) {
    patchState({
      connectedDevice: undefined
    });
  }

  @Action(DisconnectDevice)
  disconnectDevice({ getState, patchState }: StateContext<DevicesStateModel>) {
    const { connectedDevice } = getState();
    if (connectedDevice) {
      return this.devicesService.disconnectDevice(connectedDevice).pipe(
        tap(() => {
          patchState({
            connectedDevice: undefined
          });
        })
      );
    } else {
      return of(null);
{'fraction_non_alphanumeric': 0.1181462140992167, 'fraction_numerical': 0.0, 'mean_word_length': 3.3098921706516644, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2479230', 'n_tokens_mistral': 2559, 'n_tokens_neox': 2518, 'n_words': 469}