Handle connecting/disconnecting states
This commit is contained in:
parent
1477d909b0
commit
02b93a3ef0
6 changed files with 176 additions and 41 deletions
|
|
@ -9,6 +9,7 @@ const appState = {
|
||||||
wifiReconnectAttempts: 0,
|
wifiReconnectAttempts: 0,
|
||||||
maxReconnectAttempts: 5,
|
maxReconnectAttempts: 5,
|
||||||
connectedSSID: null,
|
connectedSSID: null,
|
||||||
|
connectionState: 'disconnected',
|
||||||
networks: [],
|
networks: [],
|
||||||
uptime: 0,
|
uptime: 0,
|
||||||
uptimeInterval: null
|
uptimeInterval: null
|
||||||
|
|
@ -104,10 +105,11 @@ async function connectToWifi() {
|
||||||
|
|
||||||
const password = document.getElementById('wifiPassword').value;
|
const password = document.getElementById('wifiPassword').value;
|
||||||
|
|
||||||
if (appState.selectedWifi.security !== 'Open' && !password) {
|
// Password requirement disabled
|
||||||
showToast('warning', 'Attention', 'Mot de passe requis pour ce réseau');
|
// if (appState.selectedWifi.security !== 'Open' && !password) {
|
||||||
return;
|
// showToast('warning', 'Attention', 'Mot de passe requis pour ce réseau');
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
showLoading(true);
|
showLoading(true);
|
||||||
|
|
||||||
|
|
@ -250,12 +252,32 @@ function updateStatusDisplay(status) {
|
||||||
const wifiDot = wifiStatus.querySelector('.status-dot');
|
const wifiDot = wifiStatus.querySelector('.status-dot');
|
||||||
const wifiText = wifiStatus.querySelector('.status-text');
|
const wifiText = wifiStatus.querySelector('.status-text');
|
||||||
|
|
||||||
if (status.connected) {
|
// Use connectionState for more detailed status
|
||||||
|
const state = status.connectionState || (status.connected ? 'connected' : 'disconnected');
|
||||||
|
appState.connectionState = state;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 'connected':
|
||||||
wifiDot.className = 'status-dot active';
|
wifiDot.className = 'status-dot active';
|
||||||
wifiText.textContent = `Connecté: ${status.connectedSSID}`;
|
wifiText.textContent = `Connecté: ${status.connectedSSID}`;
|
||||||
} else {
|
break;
|
||||||
|
case 'connecting':
|
||||||
|
wifiDot.className = 'status-dot connecting';
|
||||||
|
wifiText.textContent = status.connectedSSID ? `Connexion à ${status.connectedSSID}...` : 'Connexion...';
|
||||||
|
break;
|
||||||
|
case 'disconnecting':
|
||||||
|
wifiDot.className = 'status-dot disconnecting';
|
||||||
|
wifiText.textContent = 'Déconnexion...';
|
||||||
|
break;
|
||||||
|
case 'roaming':
|
||||||
|
wifiDot.className = 'status-dot active';
|
||||||
|
wifiText.textContent = `Roaming: ${status.connectedSSID}`;
|
||||||
|
break;
|
||||||
|
case 'disconnected':
|
||||||
|
default:
|
||||||
wifiDot.className = 'status-dot offline';
|
wifiDot.className = 'status-dot offline';
|
||||||
wifiText.textContent = 'Déconnecté';
|
wifiText.textContent = 'Déconnecté';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update hotspot status badge
|
// Update hotspot status badge
|
||||||
|
|
@ -282,11 +304,14 @@ function updateStatusDisplay(status) {
|
||||||
// Update hotspot details if available
|
// Update hotspot details if available
|
||||||
updateHotspotDetails(status.hotspotStatus);
|
updateHotspotDetails(status.hotspotStatus);
|
||||||
|
|
||||||
// Check if connectedSSID changed and refresh WiFi list if needed
|
// Check if connectedSSID or state changed and refresh WiFi list if needed
|
||||||
const connectedSSIDChanged = appState.connectedSSID !== status.connectedSSID;
|
const prevSSID = appState.connectedSSID;
|
||||||
|
const prevState = appState.connectionState;
|
||||||
appState.connectedSSID = status.connectedSSID;
|
appState.connectedSSID = status.connectedSSID;
|
||||||
|
|
||||||
if (connectedSSIDChanged && appState.networks.length > 0) {
|
const connectedChanged = prevSSID !== status.connectedSSID || prevState !== state;
|
||||||
|
|
||||||
|
if (connectedChanged && appState.networks.length > 0) {
|
||||||
displayWifiNetworks(appState.networks);
|
displayWifiNetworks(appState.networks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -314,9 +339,20 @@ function displayWifiNetworks(networks) {
|
||||||
const wifiItem = document.createElement('div');
|
const wifiItem = document.createElement('div');
|
||||||
wifiItem.className = 'wifi-item';
|
wifiItem.className = 'wifi-item';
|
||||||
|
|
||||||
// Mark the currently connected network
|
// Mark the network based on connection state
|
||||||
if (appState.connectedSSID && network.ssid === appState.connectedSSID) {
|
if (appState.connectedSSID && network.ssid === appState.connectedSSID) {
|
||||||
|
switch (appState.connectionState) {
|
||||||
|
case 'connected':
|
||||||
|
case 'roaming':
|
||||||
wifiItem.classList.add('connected');
|
wifiItem.classList.add('connected');
|
||||||
|
break;
|
||||||
|
case 'connecting':
|
||||||
|
wifiItem.classList.add('connecting');
|
||||||
|
break;
|
||||||
|
case 'disconnecting':
|
||||||
|
wifiItem.classList.add('disconnecting');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wifiItem.onclick = () => selectWifi(network, wifiItem);
|
wifiItem.onclick = () => selectWifi(network, wifiItem);
|
||||||
|
|
@ -576,7 +612,11 @@ function handleStateChange(data) {
|
||||||
const wifiDot = wifiStatus.querySelector('.status-dot');
|
const wifiDot = wifiStatus.querySelector('.status-dot');
|
||||||
const wifiText = wifiStatus.querySelector('.status-text');
|
const wifiText = wifiStatus.querySelector('.status-text');
|
||||||
|
|
||||||
if (data.state === 'connected') {
|
// Update state in appState
|
||||||
|
appState.connectionState = data.state;
|
||||||
|
|
||||||
|
switch (data.state) {
|
||||||
|
case 'connected':
|
||||||
wifiDot.className = 'status-dot active';
|
wifiDot.className = 'status-dot active';
|
||||||
wifiText.textContent = `Connecté: ${data.ssid}`;
|
wifiText.textContent = `Connecté: ${data.ssid}`;
|
||||||
appState.connectedSSID = data.ssid;
|
appState.connectedSSID = data.ssid;
|
||||||
|
|
@ -585,7 +625,35 @@ function handleStateChange(data) {
|
||||||
if (appState.networks.length > 0) {
|
if (appState.networks.length > 0) {
|
||||||
displayWifiNetworks(appState.networks);
|
displayWifiNetworks(appState.networks);
|
||||||
}
|
}
|
||||||
} else if (data.state === 'disconnected') {
|
break;
|
||||||
|
|
||||||
|
case 'connecting':
|
||||||
|
wifiDot.className = 'status-dot connecting';
|
||||||
|
wifiText.textContent = data.ssid ? `Connexion à ${data.ssid}...` : 'Connexion...';
|
||||||
|
|
||||||
|
// Refresh network list to show connecting state
|
||||||
|
if (appState.networks.length > 0) {
|
||||||
|
displayWifiNetworks(appState.networks);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'disconnecting':
|
||||||
|
wifiDot.className = 'status-dot disconnecting';
|
||||||
|
wifiText.textContent = 'Déconnexion...';
|
||||||
|
|
||||||
|
// Refresh network list to show disconnecting state
|
||||||
|
if (appState.networks.length > 0) {
|
||||||
|
displayWifiNetworks(appState.networks);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'roaming':
|
||||||
|
wifiDot.className = 'status-dot active';
|
||||||
|
wifiText.textContent = `Roaming: ${data.ssid}`;
|
||||||
|
appState.connectedSSID = data.ssid;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'disconnected':
|
||||||
wifiDot.className = 'status-dot offline';
|
wifiDot.className = 'status-dot offline';
|
||||||
wifiText.textContent = 'Déconnecté';
|
wifiText.textContent = 'Déconnecté';
|
||||||
appState.connectedSSID = null;
|
appState.connectedSSID = null;
|
||||||
|
|
@ -594,9 +662,11 @@ function handleStateChange(data) {
|
||||||
if (appState.networks.length > 0) {
|
if (appState.networks.length > 0) {
|
||||||
displayWifiNetworks(appState.networks);
|
displayWifiNetworks(appState.networks);
|
||||||
}
|
}
|
||||||
} else if (data.state === 'connecting') {
|
break;
|
||||||
wifiDot.className = 'status-dot';
|
|
||||||
wifiText.textContent = `Connexion à ${data.ssid}...`;
|
default:
|
||||||
|
console.warn('Unknown WiFi state:', data.state);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`WiFi state changed: ${data.previous_state} → ${data.state}`, data.ssid);
|
console.log(`WiFi state changed: ${data.previous_state} → ${data.state}`, data.ssid);
|
||||||
|
|
|
||||||
|
|
@ -107,11 +107,26 @@ body {
|
||||||
animation: none;
|
animation: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-dot.connecting {
|
||||||
|
background: var(--warning-color);
|
||||||
|
animation: blink 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-dot.disconnecting {
|
||||||
|
background: var(--warning-color);
|
||||||
|
animation: blink 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% { opacity: 1; }
|
0%, 100% { opacity: 1; }
|
||||||
50% { opacity: 0.5; }
|
50% { opacity: 0.5; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.3; }
|
||||||
|
}
|
||||||
|
|
||||||
/* Stats Grid */
|
/* Stats Grid */
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
@ -428,6 +443,33 @@ body {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wifi-item.connecting {
|
||||||
|
background: #fef3c7;
|
||||||
|
border-left-color: var(--warning-color) !important;
|
||||||
|
animation: pulse-item 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wifi-item.connecting .wifi-ssid {
|
||||||
|
color: var(--warning-color);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wifi-item.disconnecting {
|
||||||
|
background: #fee2e2;
|
||||||
|
border-left-color: #dc2626 !important;
|
||||||
|
animation: pulse-item 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wifi-item.disconnecting .wifi-ssid {
|
||||||
|
color: #dc2626;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse-item {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.7; }
|
||||||
|
}
|
||||||
|
|
||||||
.wifi-item.loading {
|
.wifi-item.loading {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ func New(assets embed.FS) *App {
|
||||||
return &App{
|
return &App{
|
||||||
Status: models.SystemStatus{
|
Status: models.SystemStatus{
|
||||||
Connected: false,
|
Connected: false,
|
||||||
|
ConnectionState: "disconnected",
|
||||||
ConnectedSSID: "",
|
ConnectedSSID: "",
|
||||||
HotspotStatus: nil,
|
HotspotStatus: nil,
|
||||||
ConnectedCount: 0,
|
ConnectedCount: 0,
|
||||||
|
|
@ -136,6 +137,7 @@ func (a *App) periodicStatusUpdate() {
|
||||||
for range ticker.C {
|
for range ticker.C {
|
||||||
a.StatusMutex.Lock()
|
a.StatusMutex.Lock()
|
||||||
a.Status.Connected = wifi.IsConnected()
|
a.Status.Connected = wifi.IsConnected()
|
||||||
|
a.Status.ConnectionState = wifi.GetConnectionState()
|
||||||
a.Status.ConnectedSSID = wifi.GetConnectedSSID()
|
a.Status.ConnectedSSID = wifi.GetConnectedSSID()
|
||||||
a.Status.Uptime = getSystemUptime()
|
a.Status.Uptime = getSystemUptime()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ type HotspotStatus struct {
|
||||||
// SystemStatus represents overall system status
|
// SystemStatus represents overall system status
|
||||||
type SystemStatus struct {
|
type SystemStatus struct {
|
||||||
Connected bool `json:"connected"`
|
Connected bool `json:"connected"`
|
||||||
|
ConnectionState string `json:"connectionState"` // Connection state: connected, disconnected, connecting, disconnecting, roaming
|
||||||
ConnectedSSID string `json:"connectedSSID"`
|
ConnectedSSID string `json:"connectedSSID"`
|
||||||
HotspotStatus *HotspotStatus `json:"hotspotStatus,omitempty"` // Detailed hotspot status
|
HotspotStatus *HotspotStatus `json:"hotspotStatus,omitempty"` // Detailed hotspot status
|
||||||
ConnectedCount int `json:"connectedCount"`
|
ConnectedCount int `json:"connectedCount"`
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,15 @@ func GetConnectedSSID() string {
|
||||||
return props.Name
|
return props.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConnectionState returns the current WiFi connection state
|
||||||
|
func GetConnectionState() string {
|
||||||
|
state, err := station.GetState()
|
||||||
|
if err != nil {
|
||||||
|
return string(iwd.StateDisconnected)
|
||||||
|
}
|
||||||
|
return string(state)
|
||||||
|
}
|
||||||
|
|
||||||
// StartEventMonitoring initializes D-Bus signal monitoring and WebSocket broadcasting
|
// StartEventMonitoring initializes D-Bus signal monitoring and WebSocket broadcasting
|
||||||
func StartEventMonitoring() error {
|
func StartEventMonitoring() error {
|
||||||
// Initialize broadcaster
|
// Initialize broadcaster
|
||||||
|
|
|
||||||
11
openapi.yaml
11
openapi.yaml
|
|
@ -454,6 +454,16 @@ components:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: Whether router is connected to upstream WiFi
|
description: Whether router is connected to upstream WiFi
|
||||||
example: true
|
example: true
|
||||||
|
connectionState:
|
||||||
|
type: string
|
||||||
|
description: Current WiFi connection state
|
||||||
|
enum:
|
||||||
|
- connected
|
||||||
|
- disconnected
|
||||||
|
- connecting
|
||||||
|
- disconnecting
|
||||||
|
- roaming
|
||||||
|
example: "connected"
|
||||||
connectedSSID:
|
connectedSSID:
|
||||||
type: string
|
type: string
|
||||||
description: SSID of connected upstream network (empty if not connected)
|
description: SSID of connected upstream network (empty if not connected)
|
||||||
|
|
@ -485,6 +495,7 @@ components:
|
||||||
$ref: '#/components/schemas/ConnectedDevice'
|
$ref: '#/components/schemas/ConnectedDevice'
|
||||||
required:
|
required:
|
||||||
- connected
|
- connected
|
||||||
|
- connectionState
|
||||||
- connectedSSID
|
- connectedSSID
|
||||||
- connectedCount
|
- connectedCount
|
||||||
- dataUsage
|
- dataUsage
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue