24-project-life (#28)

Fix peripherals states and implements plug and reload feature.
Graphics improvements.
Stability improvements.

Reviewed-on: #28
This commit was merged in pull request #28.
This commit is contained in:
2025-11-11 19:14:44 +00:00
parent 9e8cbed73f
commit 6dd555265c
17 changed files with 876 additions and 350 deletions

View File

@@ -7,66 +7,50 @@
import Settings from './components/Settings/Settings.svelte';
import Devices from './components/Devices/Devices.svelte';
import Show from './components/Show/Show.svelte';
import DropdownList from "./components/General/DropdownList.svelte";
import RoundDropdownList from "./components/General/RoundDropdownList.svelte";
import GeneralConsole from './components/Console/GeneralConsole.svelte';
import RoundIconButton from './components/General/RoundIconButton.svelte';
import { generateToast, showInformation, needProjectSave, peripherals } from './stores';
import { SaveProject } from '../wailsjs/go/main/App.js';
import { construct_svelte_component } from 'svelte/internal';
import { EventsOn } from '../wailsjs/runtime'
import { CreateProject } from "../wailsjs/go/main/App";
import { generateToast, showInformation, needProjectSave, projectsList } from './stores.js';
import { GetProjects, CreateProject, OpenProjectFromDisk, SaveProject } from '../wailsjs/go/main/App.js';
import { WindowSetTitle } from "../wailsjs/runtime/runtime"
import { get } from "svelte/store"
import ToastNotification from './components/General/ToastNotification.svelte';
import { onMount, onDestroy } from 'svelte'
import { destroyRuntimeEvents, initRuntimeEvents } from './runtime-events.js'
// Handle the event when a new peripheral is detected
EventsOn('PERIPHERAL_ARRIVAL', function(peripheralInfo){
// When a new peripheral is detected, add it to the map and:
// - Pass the isDetected key to true
// - Set the isSaved key to the last value
let peripheralsList = get(peripherals)
let lastSavedProperty = peripheralsList[peripheralInfo.SerialNumber]?.isSaved
peripheralInfo.isDetected = true
peripheralInfo.isSaved = (lastSavedProperty === true) ? true : false
peripherals.update((peripherals) => {
peripherals[peripheralInfo.SerialNumber] = peripheralInfo
return {...peripherals}
})
console.log("Hardware has been added to the system");
generateToast('info', 'bxs-hdd', $_("peripheralArrivalToast") + ' <b>' + peripheralInfo.Name + '</b>')
})
// Handle the event when a peripheral is removed from the system
EventsOn('PERIPHERAL_REMOVAL', function(peripheralInfo){
console.log("Hardware has been removed from the system");
// When a peripheral is disconnected, pass its isDetected key to false
// If the isSaved key is set to false, we can completely remove the peripheral from the list
let peripheralsList = get(peripherals)
let lastSavedProperty = peripheralsList[peripheralInfo.SerialNumber]?.isSaved
let needToDelete = (lastSavedProperty !== true) ? true : false
peripherals.update((storedPeripherals) => {
if (needToDelete){
delete storedPeripherals[peripheralInfo.SerialNumber];
return { ...storedPeripherals };
}
storedPeripherals[peripheralInfo.SerialNumber].isDetected = false
return {...storedPeripherals}
function initializeNewProject(){
// Instanciate a new project
CreateProject().then(() => {
// Project created, we set the needSave flag to true (not already saved)
needProjectSave.set(true)
}).catch((error) => {
console.error(`Unable to create the project: ${error}`)
generateToast('danger', 'bx-error', $_("projectCreateErrorToast"))
})
generateToast('warning', 'bxs-hdd', $_("peripheralRemovalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
// Initialize runtime events at startup
onMount(() => {
initRuntimeEvents()
// Handle window shortcuts
document.addEventListener('keydown', function(event) {
// Check the CTRL+S keys
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
// Avoid the natural behaviour
event.preventDefault();
// Save the current project
saveProject()
}
});
// Initialize a new project
initializeNewProject()
})
// Handle the event when a peripheral status is updated
EventsOn('PERIPHERAL_STATUS', function(peripheral, status){
console.log("Hardware status has been updated to " + status);
// When a peripheral status is updated, update it in the store
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheral.SerialNumber]: {
...storedPeripherals[peripheral.SerialNumber],
isSaved: true,
Status: status,
},
}})
// Destroy runtime events at shutdown
onDestroy(() => {
destroyRuntimeEvents()
})
// Set the window title
@@ -92,23 +76,41 @@
})
}
// Handle window shortcuts
document.addEventListener('keydown', function(event) {
// Check the CTRL+S keys
if ((event.ctrlKey || event.metaKey) && event.key === 's') {
// Avoid the natural behaviour
event.preventDefault();
// Save the current project
saveProject()
}
});
// Open the selected project
function openSelectedProject(event){
let selectedOption = event.detail.key
// Open the selected project
OpenProjectFromDisk(selectedOption).then(() => {
// Project opened, we set the needSave flag to false (already saved)
needProjectSave.set(false)
}).catch((error) => {
console.error(`Unable to open the project: ${error}`)
generateToast('danger', 'bx-error', $_("projectOpenErrorToast"))
})
}
// Refresh the projects list
let choices = new Map()
function loadProjectsList(){
GetProjects().then((projects) => {
choices = new Map(projects.map(item => [item.Save, item.Name]));
$projectsList = projects
}).catch((error) => {
console.error(`Unable to get the projects list: ${error}`)
generateToast('danger', 'bx-error', $_("projectsLoadErrorToast"))
})
}
</script>
<header>
<!-- Project buttons -->
<RoundIconButton on:mouseup={initializeNewProject} icon='bxs-plus-square' width="2.5em" tooltip={$_("newProjectTooltip")}/>
<RoundDropdownList on:click={loadProjectsList} on:selected={openSelectedProject} choices={choices} icon='bxs-folder-open' width="2.5em" tooltip={$_("openProjectTooltip")}/>
<NavigationBar on:navigationChanged="{onNavigationChanged}"/>
{#if $needProjectSave}
<RoundIconButton on:mouseup={saveProject} icon="bx-save" width="2.5em" tooltip={$_("saveButtonTooltip")}></RoundIconButton>
<RoundIconButton on:mouseup={saveProject} icon="bx-save" width="2.5em" tooltip={$_("saveButtonTooltip")}/>
{/if}
<Clock/>
</header>

View File

@@ -0,0 +1,152 @@
<!-- Create a round icon button -->
<script>
import { createEventDispatcher, onDestroy } from 'svelte';
import {colors} from '../../stores.js';
import Tooltip from './Tooltip.svelte';
import { _ } from 'svelte-i18n'
export let icon = "bxs-heart" // The icon wanted
export let width = "10em" // The button width
export let active = false // If the button is active or not
export let tooltip = "Default tooltip" // The description shown in the tooltip
export let operationalStatus = undefined// The optional button status
export let okStatusLabel = "" // The label shown when the button is OK
export let nokStatusLabel = "" // The label shown when the button is NOK
export let choices = new Map()
export let style = '';
let tooltipMessage = tooltip
// Default values for background and foreground
$: background = $colors.first
$: foreground = $colors.first
// Change the background when the selected prop changed
$: {
if (active === true) {
background = $colors.third
foreground = $colors.fourth
} else {
background = $colors.fourth
foreground = $colors.second
}
}
// Show the operational status if specified
// undefined => no status displayed
// operationalStatus = true => OK color displayed
// operationalStatus = false => NOK color displayed
$: statusColor = $colors.nok
$: {
if (operationalStatus === true){
statusColor = $colors.ok
tooltipMessage = tooltip + " " + okStatusLabel
} else {
statusColor = $colors.nok
tooltipMessage = tooltip + " " + nokStatusLabel
}
}
// Emit a click event when the button is clicked
const dispatch = createEventDispatcher();
function handleclick(key){
// Deactivate the list visibility
hideList()
dispatch('selected', key)
}
// Show the option list
let listShowing = false
function toggleList(){
if (!listShowing) {
dispatch('click')
}
listShowing = !listShowing
}
function hideList(){
listShowing = false
}
let tooltipPosition = {top: 0, left: 0}
// Show a tooltip on mouse hover
let tooltipShowing = false
let buttonRef
function toggleTooltip(active){
const rect = buttonRef.getBoundingClientRect();
tooltipPosition = {
top: rect.bottom + 5, // Ajouter une marge en bas
left: rect.left, // Centrer horizontalement
};
tooltipShowing = active
}
</script>
<div class="container">
<button bind:this={buttonRef}
style="width:{width}; height:{width}; border-radius:{width}; background-color:{background}; color:{foreground};"
on:mouseenter={() => { toggleTooltip(true) }}
on:mouseleave={() => { toggleTooltip(false) }}
on:click={toggleList}>
<i class='bx {icon}' style="font-size:100%;"></i>
</button>
<!-- Showing the badge status if the button has an operational status -->
{#if (operationalStatus !== undefined)}
<div class="badge"
style="width: calc({width} / 3); height: calc({width} / 3); border-radius: calc({width}); background-color:{statusColor}; display:block;">
</div>
{/if}
<Tooltip message={tooltipMessage} show={tooltipShowing} position={tooltipPosition}></Tooltip>
<div class="list" style="color: {$colors.white}; display: {listShowing ? "block" : "none"}; border: 2px solid {$colors.second}; background-color: {$colors.first};"
on:mouseleave={hideList}>
{#each Array.from(choices) as [key, value]}
<div class="item" on:click={() => handleclick({key})}>{value}</div>
{/each}
</div>
</div>
<style>
.item{
border-radius: 0.3em;
padding: 0.3em;
}
.item:hover {
background-color: var(--second-color);
color: var(--white-color);
}
.container {
position: relative;
display: inline-block;
}
.list {
z-index: 200;
padding: 0.2em;
margin-top: 0.2em;
position: absolute;
width: auto;
cursor: pointer;
border-radius: 0.5em;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 30em;
max-height: 40vh;
overflow-y: scroll;
scrollbar-width: none;
}
button{
display: inline-block;
margin: 0;
border:none;
cursor: pointer;
}
button:hover{
box-shadow: 1px 1px 3px 0px rgba(0, 0, 0, 0.25) inset;
}
</style>

View File

@@ -15,13 +15,14 @@
export let signalizable = false;
export let signalized = false;
export let selected = false;
export let status = "disconnected";
export let status = "PERIPHERAL_DISCONNECTED";
// Emit a delete event when the device is being removed
const dispatch = createEventDispatcher();
function remove(event){
dispatch('delete')
}
function add(event){
dispatch('add')
}
@@ -37,11 +38,11 @@
</script>
<div class="card" on:dblclick={dblclick}>
<div class="{selected ? "selected" : "unselected"} {status == "connecting" ? "waiting" : ""}" on:mousedown={click} style="color: {(status == "disconnected") ? $colors.first : $colors.white};">
<div class="{selected ? "selected" : "unselected"} {status == "PERIPHERAL_CONNECTING" ? "waiting" : ""}" on:mousedown={click} style="color: {(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white};">
<div style="z-index: 1;">
<p>{#if status == "disconnected" }<i class='bx bx-no-signal' style="font-size:100%; color: var(--nok-color);"></i> {/if}{title}</p>
<p>{#if status == "PERIPHERAL_DISCONNECTED" }<i class='bx bx-no-signal' style="font-size:100%; color: var(--nok-color);"></i> {/if}{title}</p>
<h6 class="subtitle">{type} {location != '' ? "- " : ""}<i>{location}</i></h6>
{#if status == "disconnected"}
{#if status == "PERIPHERAL_DISCONNECTED"}
<h6><b>Disconnected</b></h6>
{:else}
<h6>{line1}</h6>
@@ -50,9 +51,9 @@
</div>
<div class="actions">
<InfoButton on:click={add} color="{(status == "disconnected") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { addable ? 'flex' : 'none' }" icon='bxs-message-square-add' interactive message={$_("projectHardwareAddTooltip")}/>
<InfoButton on:click={remove} color="{(status == "disconnected") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { removable ? 'flex' : 'none' }" icon='bx-trash' interactive message={$_("projectHardwareDeleteTooltip")}/>
<InfoButton style="margin: 0.2em; display: { (status == "activated" || status == "deactivated") ? 'flex' : 'none' }" background={ (status == "activated") ? $colors.ok : (status == "deactivated") ? $colors.nok : null} icon='bx-pulse' hide={!signalizable}/>
<InfoButton on:click={add} color="{(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { addable ? 'flex' : 'none' }" icon='bxs-message-square-add' interactive message={$_("projectHardwareAddTooltip")}/>
<InfoButton on:click={remove} color="{(status == "PERIPHERAL_DISCONNECTED") ? $colors.first : $colors.white}" style="margin: 0.2em; display: { removable ? 'flex' : 'none' }" icon='bx-trash' interactive message={$_("projectHardwareDeleteTooltip")}/>
<InfoButton style="margin: 0.2em; display: { (status == "PERIPHERAL_ACTIVATED" || status == "PERIPHERAL_DEACTIVATED") ? 'flex' : 'none' }" background={ (status == "PERIPHERAL_ACTIVATED") ? $colors.ok : (status == "PERIPHERAL_DEACTIVATED") ? $colors.nok : null} icon='bx-pulse' hide={!signalizable}/>
</div>
</div>
</div>

View File

@@ -11,20 +11,8 @@
// Add the peripheral to the project
function addPeripheral(peripheral){
// Add the peripheral to the project (backend)
AddPeripheral(peripheral).then((serialNumber) => {
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[serialNumber]: {
...storedPeripherals[serialNumber],
Name: peripheral.Name,
ProtocolName: peripheral.ProtocolName,
SerialNumber: serialNumber,
isSaved: true,
},
}})
$needProjectSave = true
}).catch((error) => {
AddPeripheral(peripheral)
.catch((error) => {
console.log("Unable to add the peripheral to the project: " + error)
generateToast('danger', 'bx-error', $_("addPeripheralErrorToast"))
})
@@ -33,27 +21,8 @@
// Remove the peripheral from the project
function removePeripheral(peripheral) {
// Delete the peripheral from the project (backend)
RemovePeripheral(peripheral.ProtocolName, peripheral.SerialNumber).then(() => {
// If the peripheral is not detected, we can delete it form the store
// If not, we only pass the isSaved key to false
let peripheralsList = get(peripherals)
let lastDetectedProperty = peripheralsList[peripheral.SerialNumber]?.isDetected
let needToDelete = (lastDetectedProperty !== true) ? true : false
peripherals.update((storedPeripherals) => {
if (needToDelete){
delete storedPeripherals[peripheral.SerialNumber];
return { ...storedPeripherals };
}
storedPeripherals[peripheral.SerialNumber].isSaved = false
return { ...storedPeripherals };
})
$needProjectSave = true
// If the peripheral is currently selected, unselect it
if (selectedPeripheralSN == peripheral.SerialNumber) {
selectedPeripheralSN = null
selectedPeripheralSettings = {}
}
}).catch((error) => {
RemovePeripheral(peripheral)
.catch((error) => {
console.log("Unable to remove the peripheral from the project: " + error)
generateToast('danger', 'bx-error', $_("removePeripheralErrorToast"))
})
@@ -76,7 +45,7 @@
}
}
// Unselect the peripheral if it is disconnect
// Unselect the peripheral if it is disconnected
$: {
Object.entries($peripherals).filter(([serialNumber, peripheral]) => {
if (!peripheral.isDetected && peripheral.isSaved && selectedPeripheralSN == serialNumber) {
@@ -120,7 +89,7 @@
if(!peripheral.isSaved)
addPeripheral(peripheral)
}}
status="connected" title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={"S/N: " + peripheral.SerialNumber} addable={!peripheral.isSaved}/>
status="PERIPHERAL_CONNECTED" title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={"S/N: " + peripheral.SerialNumber} addable={!peripheral.isSaved}/>
{/if}
{/each}
<p style="color: var(--first-color);"><i class='bx bxs-network-chart' ></i> {$_("projectHardwareOthersLabel")}</p>
@@ -134,7 +103,7 @@
{#if savedPeripheralNumber > 0}
{#each Object.entries($peripherals) as [serialNumber, peripheral]}
{#if peripheral.isSaved}
<DeviceCard status="{peripheral.Status}" on:delete={() => removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)} on:click={() => selectPeripheral(peripheral)}
<DeviceCard status="{peripheral.status}" on:delete={() => removePeripheral(peripheral)} on:dblclick={() => removePeripheral(peripheral)} on:click={() => selectPeripheral(peripheral)}
title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} selected={serialNumber == selectedPeripheralSN} removable signalizable/>
{/if}
{/each}

View File

@@ -1,109 +1,16 @@
<script lang=ts>
import { generateToast, projectsList, showInformation, needProjectSave, peripherals } from '../../stores.js';
import RoundedButton from "../General/RoundedButton.svelte";
import ProjectPropertiesContent from "./ProjectPropertiesContent.svelte";
import DropdownList from "../General/DropdownList.svelte";
import InputsOutputsContent from "./InputsOutputsContent.svelte";
import Tab from "../General/Tab.svelte";
import { CreateProject, GetProjects, OpenProjectFromDisk } from "../../../wailsjs/go/main/App";
import { _ } from 'svelte-i18n'
import {colors} from '../../stores.js';
import { get } from "svelte/store"
import { EventsOn } from '../../../wailsjs/runtime'
const tabs = [
{ title: $_("projectPropertiesTab"), icon: 'bxs-info-circle', tooltip: $_("projectPropertiesTooltip"), component: ProjectPropertiesContent },
{ title: $_("projectInputOutputTab"), icon: 'bxs-plug', tooltip: $_("projectInputOutputTooltip"), component: InputsOutputsContent },
];
// Refresh the projects list
let choices = new Map()
function loadProjectsList(){
GetProjects().then((projects) => {
choices = new Map(projects.map(item => [item.Save, item.Name]));
$projectsList = projects
}).catch((error) => {
console.error(`Unable to get the projects list: ${error}`)
generateToast('danger', 'bx-error', $_("projectsLoadErrorToast"))
})
}
// Unsave peripherals from the store and remove the disconnected peripherals
function unsavePeripherals(){
peripherals.update((storedPeripherals) => {
// Set all the isSaved keys to false and delete the disconnected peripherals
for (let peripheralID in storedPeripherals) {
storedPeripherals[peripheralID].isSaved = false
if (!storedPeripherals[peripheralID].isDetected) {
delete storedPeripherals[peripheralID]
}
}
return {...storedPeripherals}
})
}
// Load the saved peripherals into the store
function loadPeripherals(peripheralsInfo){
peripherals.update((storedPeripherals) => {
// Add the saved peripherals of the project
// If already exists pass the isSaved key to true, if not create the peripheral and set it to disconnected
for (let peripheralID in peripheralsInfo){
// Add the peripheral to the list of peripherals, with the last isDetected key and the isSaved key to true
let lastDetectedKey = storedPeripherals[peripheralID]?.isDetected
storedPeripherals[peripheralID] = peripheralsInfo[peripheralID]
storedPeripherals[peripheralID].isDetected = (lastDetectedKey === true) ? true : false
storedPeripherals[peripheralID].isSaved = true
}
return {...storedPeripherals}
})
}
// Handle the event when a new project need to be loaded
EventsOn('LOAD_PROJECT', function(projectInfo){
// Store project information
showInformation.set(projectInfo.ShowInfo)
// Remove the saved peripherals of the current project
unsavePeripherals()
// Load new project peripherals
loadPeripherals(projectInfo.PeripheralsInfo)
console.log("Project has been opened");
generateToast('info', 'bx-folder-open', $_("projectOpenedToast") + ' <b>' + projectInfo.ShowInfo.Name + '</b>')
})
// Open the selected project
function openSelectedProject(event){
let selectedOption = event.detail.key
// Open the selected project
OpenProjectFromDisk(selectedOption).then(() => {
// Project opened, we set the needSave flag to false (already saved)
needProjectSave.set(false)
}).catch((error) => {
console.error(`Unable to open the project: ${error}`)
generateToast('danger', 'bx-error', $_("projectOpenErrorToast"))
})
}
function initializeNewProject(){
// Instanciate a new project
CreateProject().then(() => {
// Project created, we set the needSave flag to true (not already saved)
needProjectSave.set(true)
}).catch((error) => {
console.error(`Unable to create the project: ${error}`)
generateToast('danger', 'bx-error', $_("projectCreateErrorToast"))
})
}
// Instantiate a new project
initializeNewProject()
</script>
<!-- Project buttons -->
<RoundedButton on:click={initializeNewProject} text={$_("newProjectString")} icon='bxs-plus-square' tooltip={$_("newProjectTooltip")}/>
<DropdownList icon='bxs-folder-open' text={$_("openProjectString")} choices={choices} tooltip={$_("openProjectTooltip")} on:click={loadProjectsList} on:selected={openSelectedProject}/>
<!-- Project tabcontrol -->
<Tab { tabs } maxHeight='73vh'/>

View File

@@ -1,8 +1,9 @@
import App from './App.svelte';
import { WindowSetTitle } from "../wailsjs/runtime/runtime"
import { _ } from 'svelte-i18n'
import {showInformation, needProjectSave} from './stores.js';
import {messages, showInformation, needProjectSave} from './stores.js';
// Load dictionaries
import { addMessages, init } from 'svelte-i18n';

View File

@@ -0,0 +1,169 @@
import { EventsOn, EventsOff } from "../wailsjs/runtime/runtime.js"
import { peripherals, generateToast, needProjectSave, showInformation } from './stores'
import { get } from "svelte/store"
import { _ } from 'svelte-i18n'
// New peripheral has been added to the system
function peripheralArrival (peripheralInfo){
// If not exists, add it to the map
// isDetected key to true
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isDetected: true,
},
}})
console.log("Hardware has been added to the system");
generateToast('info', 'bxs-hdd', get(_)("peripheralArrivalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
// Peripheral is removed from the system
function peripheralRemoval (peripheralInfo){
// If not exists, add it to the map
// isDetected key to false
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isDetected: false,
status: "PERIPHERAL_DISCONNECTED",
},
}})
console.log("Hardware has been removed from the system");
generateToast('warning', 'bxs-hdd', get(_)("peripheralRemovalToast") + ' <b>' + peripheralInfo.Name + '</b>')
}
// Update peripheral status
function peripheralUpdateStatus(peripheralInfo, status){
// If not exists, add it to the map
// change status key
peripherals.update((storedPeripherals) => {
console.log(status)
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
status: status,
},
}})
console.log("Hardware status has been updated to " + status);
}
// Load the peripheral in the project
function loadPeripheral (peripheralInfo) {
// If not exists, add it to the map
// isSaved key to true
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isSaved: true,
},
}})
console.log("Hardware has been added to the project");
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
}
function loadProject (showInfo){
// Store project information
showInformation.set(showInfo)
console.log("Project has been opened");
generateToast('info', 'bx-folder-open', get(_)("projectOpenedToast") + ' <b>' + showInfo.Name + '</b>')
}
// Unload the hardware from the project
function unloadPeripheral (peripheralInfo) {
// If not exists, add it to the map
// isSaved key to false
peripherals.update((storedPeripherals) => {
return {
...storedPeripherals,
[peripheralInfo.SerialNumber]: {
...storedPeripherals[peripheralInfo.SerialNumber],
Name: peripheralInfo.Name,
ProtocolName: peripheralInfo.ProtocolName,
SerialNumber: peripheralInfo.SerialNumber,
Settings: peripheralInfo.Settings,
isSaved: false,
},
}})
console.log("Hardware has been removed from the project");
//TODO: Lors d'un chargement/déchargement natif au démarrage, il ne doit pas y avoir de nécessité de sauvegarder
needProjectSave.set(true)
}
let initialized = false
export function initRuntimeEvents(){
if (initialized) return
initialized = true
// Handle the event when a new peripheral is detected
EventsOn('PERIPHERAL_ARRIVAL', peripheralArrival)
// Handle the event when a peripheral is removed from the system
EventsOn('PERIPHERAL_REMOVAL', peripheralRemoval)
// Handle the event when a peripheral status is updated
EventsOn('PERIPHERAL_STATUS', peripheralUpdateStatus)
// Handle the event when a new project need to be loaded
EventsOn('LOAD_PROJECT', loadProject)
// Handle a peripheral loaded in the project
EventsOn('LOAD_PERIPHERAL', loadPeripheral)
// Handle a peripheral unloaded from the project
EventsOn('UNLOAD_PERIPHERAL', unloadPeripheral)
}
export function destroyRuntimeEvents(){
if (!initialized) return
initialized = false
// Handle the event when a new peripheral is detected
EventsOff('PERIPHERAL_ARRIVAL')
// Handle the event when a peripheral is removed from the system
EventsOff('PERIPHERAL_REMOVAL')
// Handle the event when a peripheral status is updated
EventsOff('PERIPHERAL_STATUS')
// Handle the event when a new project need to be loaded
EventsOff('LOAD_PROJECT')
// Handle a peripheral loaded in the project
EventsOff('LOAD_PERIPHERAL')
// Handle a peripheral unloaded from the project
EventsOff('UNLOAD_PERIPHERAL')
}

View File

@@ -10,13 +10,12 @@ export let showInformation = writable({})
// Toasts notifications
export let messages = writable([])
export function generateToast(type, icon, text){
messages.update((value) => {
value.push( { id: Date.now(), type: type, icon: icon, text: text } )
return value.slice(-5)
})
messages.update((value) => {
value.push( { id: Date.now(), type: type, icon: icon, text: text } )
return value.slice(-5)
})
}
// Application colors
export const colors = writable({
first: "#1B262C",
@@ -35,4 +34,15 @@ export const secondSize = writable("14px")
export const thirdSize = writable("20px")
// List of current hardware
export let peripherals = writable({})
export let peripherals = writable({})
// Peripheral structure :
// Name string `yaml:"name"` // Name of the peripheral
// SerialNumber string `yaml:"sn"` // S/N of the peripheral
// ProtocolName string `yaml:"protocol"` // Protocol name of the peripheral
// Settings map[string]interface{} `yaml:"settings"` // Peripheral settings
// isSaved // if the peripheral is saved in the project
// isDetected // if the peripheral is detected by the system
// status // the status of connection