Skip to content

Commit 924b40d

Browse files
committed
feat: add timezone fetching and battery percentage to statusbar
1 parent 6a8643c commit 924b40d

File tree

1 file changed

+119
-16
lines changed

1 file changed

+119
-16
lines changed

src/components/common/navigation/StatusBar.jsx

+119-16
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,41 @@ import { useState, useEffect } from "react";
22
import { BatteryIcon, BluetoothIcon, WifiMaxIcon, WifiHighIcon, WifiLowIcon, WifiOffIcon } from "../../common/icons";
33
import { useSettings } from "../../../contexts/SettingsContext";
44
import { useWiFiNetworks } from "../../../hooks/useWiFiNetworks";
5+
import { useBluetooth } from "../../../hooks/useNocturned";
6+
import { useConnector } from "../../../contexts/ConnectorContext";
57

68
export default function StatusBar() {
79
const [currentTime, setCurrentTime] = useState("");
810
const [isFourDigits, setIsFourDigits] = useState(false);
911
const [isBluetoothConnected, setIsBluetoothConnected] = useState(true);
1012
const [batteryPercentage, setBatteryPercentage] = useState(80);
13+
const [timezone, setTimezone] = useState(null);
1114
const { settings } = useSettings();
1215
const { currentNetwork, availableNetworks } = useWiFiNetworks();
16+
const { lastConnectedDevice, connectedDevices } = useBluetooth();
17+
const { isConnectorAvailable } = useConnector();
18+
19+
useEffect(() => {
20+
const fetchTimezone = async () => {
21+
try {
22+
const response = await fetch("https://api.usenocturne.com/v1/timezone");
23+
if (!response.ok) {
24+
console.error("Failed to fetch timezone from API");
25+
return;
26+
}
27+
28+
const data = await response.json();
29+
if (data.timezone) {
30+
setTimezone(data.timezone);
31+
console.log("Timezone set to:", data.timezone);
32+
}
33+
} catch (error) {
34+
console.error("Error fetching timezone:", error);
35+
}
36+
};
37+
38+
fetchTimezone();
39+
}, []);
1340

1441
const getWiFiIcon = () => {
1542
if (!currentNetwork) return null;
@@ -29,10 +56,55 @@ export default function StatusBar() {
2956
}
3057
};
3158

59+
const fetchBatteryInfo = async (deviceAddress) => {
60+
if (!deviceAddress) return;
61+
62+
try {
63+
const response = await fetch(`http://localhost:5000/bluetooth/info/${deviceAddress}`);
64+
if (!response.ok) {
65+
console.error("Failed to fetch battery info");
66+
return;
67+
}
68+
69+
const deviceInfo = await response.json();
70+
71+
if (deviceInfo.connected && deviceInfo.batteryPercentage !== undefined) {
72+
setBatteryPercentage(deviceInfo.batteryPercentage);
73+
setIsBluetoothConnected(true);
74+
} else if (!deviceInfo.connected) {
75+
setIsBluetoothConnected(false);
76+
}
77+
} catch (error) {
78+
console.error("Error fetching battery info:", error);
79+
}
80+
};
81+
3282
useEffect(() => {
3383
const updateTime = () => {
3484
const now = new Date();
35-
85+
86+
if (timezone) {
87+
try {
88+
const options = { timeZone: timezone, hour: 'numeric', minute: 'numeric', hour12: !settings.use24HourTime };
89+
const formatter = new Intl.DateTimeFormat('en-US', options);
90+
const timeString = formatter.format(now);
91+
92+
let parts = timeString.split(':');
93+
let hours = parts[0];
94+
let minutes = parts[1];
95+
96+
if (!settings.use24HourTime) {
97+
minutes = minutes.split(' ')[0];
98+
}
99+
100+
setCurrentTime(`${hours}:${minutes}`);
101+
setIsFourDigits(hours.length >= 2);
102+
return;
103+
} catch (error) {
104+
console.error("Error formatting time with timezone:", error);
105+
}
106+
}
107+
36108
let hours;
37109
if (settings.use24HourTime) {
38110
hours = now.getHours().toString().padStart(2, "0");
@@ -60,9 +132,34 @@ export default function StatusBar() {
60132
clearInterval(interval);
61133
window.removeEventListener("timeFormatChanged", handleTimeFormatChange);
62134
};
63-
}, [settings.use24HourTime]);
135+
}, [settings.use24HourTime, timezone]);
64136

65-
if (!isBluetoothConnected) return null;
137+
useEffect(() => {
138+
let deviceAddress = null;
139+
140+
if (lastConnectedDevice && lastConnectedDevice.address) {
141+
deviceAddress = lastConnectedDevice.address;
142+
} else if (connectedDevices && connectedDevices.length > 0) {
143+
deviceAddress = connectedDevices[0].address;
144+
}
145+
146+
if (deviceAddress) {
147+
fetchBatteryInfo(deviceAddress);
148+
149+
const interval = setInterval(() => {
150+
fetchBatteryInfo(deviceAddress);
151+
}, 2 * 60 * 1000);
152+
153+
return () => clearInterval(interval);
154+
} else {
155+
setIsBluetoothConnected(false);
156+
}
157+
}, [lastConnectedDevice, connectedDevices]);
158+
159+
const shouldRenderStatusBar = isBluetoothConnected || (isConnectorAvailable && currentNetwork);
160+
if (!shouldRenderStatusBar) return null;
161+
162+
const showBluetoothInfo = isBluetoothConnected && (!isConnectorAvailable || !currentNetwork);
66163

67164
return (
68165
<div
@@ -76,9 +173,25 @@ export default function StatusBar() {
76173
{currentTime}
77174
</div>
78175
<div className="flex gap-2.5 h-10" style={{ marginTop: "-10px" }}>
79-
{currentNetwork ? getWiFiIcon() : (
80-
<BluetoothIcon
81-
className="w-8 h-10 text-white"
176+
{currentNetwork && isConnectorAvailable ? (
177+
getWiFiIcon()
178+
) : (
179+
showBluetoothInfo && (
180+
<BluetoothIcon
181+
className="w-8 h-10 text-white"
182+
style={{
183+
margin: 0,
184+
padding: 0,
185+
display: "block",
186+
transform: "translateY(-10px)",
187+
}}
188+
/>
189+
)
190+
)}
191+
{showBluetoothInfo && (
192+
<BatteryIcon
193+
className="w-10 h-10"
194+
percentage={batteryPercentage}
82195
style={{
83196
margin: 0,
84197
padding: 0,
@@ -87,16 +200,6 @@ export default function StatusBar() {
87200
}}
88201
/>
89202
)}
90-
{!currentNetwork && <BatteryIcon
91-
className="w-10 h-10"
92-
percentage={batteryPercentage}
93-
style={{
94-
margin: 0,
95-
padding: 0,
96-
display: "block",
97-
transform: "translateY(-10px)",
98-
}}
99-
/>}
100203
</div>
101204
</div>
102205
);

0 commit comments

Comments
 (0)