11-hardware-definition #17

Merged
thinkode merged 13 commits from 11-hardware-definition into develop 2025-01-18 14:53:30 +00:00
9 changed files with 142 additions and 36 deletions
Showing only changes of commit c3c604d871 - Show all commits

View File

@@ -9,17 +9,17 @@
import Show from './components/Show/Show.svelte';
import GeneralConsole from './components/Console/GeneralConsole.svelte';
import RoundIconButton from './components/General/RoundIconButton.svelte';
import { showInformation, needProjectSave, peripherals } from './stores';
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, GetPeripherals } from "../wailsjs/go/main/App";
import { WindowSetTitle } from "../wailsjs/runtime/runtime"
import { get } from "svelte/store"
import ToastNotification from './components/General/ToastNotification.svelte';
// Handle the event when a new peripheral is detected
EventsOn('PERIPHERAL_ARRIVAL', function(peripheralInfo){
console.log("Hardware has been added to the system");
// 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
@@ -31,6 +31,8 @@
peripherals[peripheralInfo.SerialNumber] = peripheralInfo
return {...peripherals}
})
console.log("Hardware has been added to the system");
generateToast('info', 'bxs-hdd', 'Your <b>' + peripheralInfo.Name + '</b> device has been detected')
})
// Handle the event when a peripheral is removed from the system
@@ -49,6 +51,7 @@
storedPeripherals[peripheralInfo.SerialNumber].isDetected = false
return {...storedPeripherals}
})
generateToast('warning', 'bxs-hdd', 'Your <b>' + peripheralInfo.Name + '</b> device has been removed')
})
// Set the window title
@@ -67,8 +70,10 @@
SaveProject().then((filePath) => {
needProjectSave.set(false)
console.log("Project has been saved to " + filePath)
generateToast('info', 'bxs-save', 'The project has been saved')
}).catch((error) => {
console.error(`Unable to save the project: ${error}`)
generateToast('danger', 'bx-error', 'Unable to save the project: ' + error)
})
}
@@ -79,8 +84,9 @@
})
// Request the list of peripherals
// TODO: Handle the error here
GetPeripherals()
GetPeripherals().catch((error) => {
generateToast('danger', 'bx-error', 'Unable to get the list of peripherals: ' + error)
})
// Handle window shortcuts
document.addEventListener('keydown', function(event) {
@@ -116,6 +122,7 @@
{:else if selectedMenu === "console"}
<GeneralConsole />
{/if}
<ToastNotification/>
</main>
<style>

View File

@@ -0,0 +1,94 @@
<script lang=ts>
import { time } from 'svelte-i18n';
import {messages, colors} from '../../stores.js';
let timers = {};
function removeToast(id) {
// Supprime un toast par son ID
$messages = $messages.filter(message => message.id !== id);
clearTimeout(timers[id]);
}
$: {
// Ajoute un timer pour supprimer automatiquement les toasts
for (const message of $messages) {
if (!timers[message.id]) {
timers[message.id] = setTimeout(() => removeToast(message.id), 5000);
}
}
}
</script>
<div class="notificationsPanel">
{#each $messages as message}
<div class="toastMessage" style="background-color: {$colors.second}; color: {$colors.white}" on:mouseup={() => removeToast(message.id)}>
<div class="toastIndicator" style="background-color:{(message.type == 'danger') ? $colors.nok : (message.type == 'warning') ? $colors.orange : $colors.third};"></div>
<p><i class='bx {message.icon}'></i> {@html message.text}</p>
</div>
{/each}
</div>
<style>
p{
margin: 0.5em;
}
.toastIndicator{
width: 10px;
border-top-left-radius: 0.5em;
border-bottom-left-radius: 0.5em;
}
.toastMessage:hover {
opacity: 1;
}
.toastMessage{
word-wrap: break-word;
overflow-wrap: break-word;
white-space: normal;
z-index: 150;
display: flex;
opacity: 0.8;
border-radius: 0.5em;
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1), /* Ombre principale douce */
0px 1px 3px rgba(0, 0, 0, 0.06); /* Ombre plus subtile */
animation: fade-in 0.3s ease-out, fade-out 0.3s ease-in 4.7s;
}
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 0.9;
transform: translateY(0);
}
}
@keyframes fade-out {
from {
opacity: 0.9;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(20px);
}
}
.notificationsPanel{
max-width: 50em;
align-items: flex-end;
position: fixed;
bottom: 1rem;
right: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
z-index: 1000;
}
</style>

View File

@@ -2,7 +2,7 @@
import DeviceCard from "./DeviceCard.svelte";
import Tab from "../General/Tab.svelte";
import { _ } from 'svelte-i18n'
import { needProjectSave, peripherals } from "../../stores";
import { generateToast, needProjectSave, peripherals } from "../../stores";
import { get } from "svelte/store"
import { AddOS2LPeripheral, RemovePeripheral, ConnectFTDI, ActivateFTDI, DeactivateFTDI, DisconnectFTDI, SetDeviceFTDI, AddPeripheral } from "../../../wailsjs/go/main/App";
import RoundedButton from "../General/RoundedButton.svelte";
@@ -62,6 +62,7 @@
$needProjectSave = true
}).catch((error) => {
console.log("Unable to add the peripheral to the project: " + error)
generateToast('danger', 'bx-error', 'Unable to add this device to project')
})
}
@@ -85,6 +86,7 @@
$needProjectSave = true
}).catch((error) => {
console.log("Unable to remove the peripheral from the project: " + error)
generateToast('danger', 'bx-error', 'Unable to remove this device from project')
})
}
@@ -97,8 +99,11 @@
currentPeriph[os2lDevice.SerialNumber] = os2lDevice
return {...currentPeriph}
})
$needProjectSave = true
generateToast('info', 'bx-signal-5', 'Your OS2L peripheral has been created')
}).catch(error => {
console.log("Unable to add the OS2L peripheral: " + error)
generateToast('danger', 'bx-error', 'Unable to create the OS2L peripheral')
})
}
</script>
@@ -114,7 +119,7 @@
if(!peripheral.isSaved)
addPeripheral(peripheral)
}}
title={peripheral.Name} type={peripheral.ProtocolName} location={peripheral.Location ? peripheral.Location : ""} line1={peripheral.SerialNumber ? "S/N: " + peripheral.SerialNumber : ""} addable={!peripheral.isSaved}/>
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> Others</p>

View File

@@ -1,5 +1,5 @@
<script lang=ts>
import { projectsList, showInformation, needProjectSave, peripherals } from '../../stores.js';
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";
@@ -23,6 +23,7 @@
$projectsList = projects
}).catch((error) => {
console.error(`Unable to get the projects list: ${error}`)
generateToast('danger', 'bx-error', 'Unable to get the projects list')
})
}
@@ -51,8 +52,10 @@
return {...storedPeripherals}
})
needProjectSave.set(false)
generateToast('info', 'bx-folder-open', 'The project <b>' + projectInfo.ShowInfo.Name + '</b> was opened')
}).catch((error) => {
console.error(`Unable to open the project: ${error}`)
generateToast('danger', 'bx-error', 'Unable to open the project')
})
}
@@ -61,6 +64,7 @@
CreateProject().then((showInfo) => {
$showInformation = showInfo
$needProjectSave = true
generateToast('info', 'bxs-folder-plus', 'The project was created')
})
}
</script>

View File

@@ -7,6 +7,16 @@ export let needProjectSave = writable(true)
// Show settings
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)
})
}
// Application colors
export const colors = writable({
first: "#1B262C",

View File

@@ -10,25 +10,6 @@ import (
"github.com/mattrtaylor/go-rtmidi"
)
/*
DMXConnect
DMXUSBProtocol.go
Copyright (c) Valentin Boulanger
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// MIDIDriver represents how the protocol is defined
type MIDIDriver struct {
peripherals map[string]Peripheral // The list of peripherals
@@ -109,7 +90,8 @@ func (d *MIDIDriver) Scan(ctx context.Context) error {
}
fmt.Printf("New MIDI device found: %s on %i\n", name, location)
// Add the peripheral to the temporary list
midiPeripherals[portName] = NewMIDIPeripheral(name, location)
sn := strings.ToLower(strings.Replace(name, " ", "_", -1))
midiPeripherals[sn] = NewMIDIPeripheral(name, location, sn)
}
// Compare with the current peripherals to detect arrivals/removals
removedList, addedList := comparePeripherals(d.peripherals, midiPeripherals)

View File

@@ -2,15 +2,17 @@ package hardware
// MIDIPeripheral contains the data of a MIDI peripheral
type MIDIPeripheral struct {
name string // The name of the peripheral
location int // The location of the peripheral
name string // The name of the peripheral
location int // The location of the peripheral
serialNumber string // The S/N of the peripheral
}
// NewMIDIPeripheral creates a new MIDI peripheral
func NewMIDIPeripheral(name string, location int) *MIDIPeripheral {
func NewMIDIPeripheral(name string, location int, serialNumber string) *MIDIPeripheral {
return &MIDIPeripheral{
name: name,
location: location,
name: name,
location: location,
serialNumber: serialNumber,
}
}
@@ -44,5 +46,6 @@ func (p *MIDIPeripheral) GetInfo() PeripheralInfo {
return PeripheralInfo{
Name: p.name,
ProtocolName: "MIDI",
SerialNumber: p.serialNumber,
}
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math/rand"
"strings"
)
// OS2LDriver represents how the protocol is defined
@@ -27,7 +28,7 @@ func (d *OS2LDriver) Initialize() error {
// CreatePeripheral creates a new OS2L peripheral
func (d *OS2LDriver) CreatePeripheral(ctx context.Context) (Peripheral, error) {
// Create a random serial number for this peripheral
randomSerialNumber := fmt.Sprintf("%08x", rand.Intn(1<<32))
randomSerialNumber := strings.ToUpper(fmt.Sprintf("%08x", rand.Intn(1<<32)))
peripheral := NewOS2LPeripheral("OS2L", randomSerialNumber)
d.peripherals[randomSerialNumber] = peripheral
return peripheral, nil

View File

@@ -152,11 +152,11 @@ func (h *HardwareManager) Scan(ctx context.Context) error {
return fmt.Errorf("No peripherals driver registered")
}
for _, driver := range h.drivers {
finder := driver
driverCopy := driver
go func() {
err := driver.Scan(ctx)
err := driverCopy.Scan(ctx)
if err != nil {
fmt.Printf("Unable to scan peripherals with the %s driver: %s\n", finder.GetName(), err)
fmt.Printf("Unable to scan peripherals with the %s driver: %s\n", driverCopy.GetName(), err)
return
}
}()