(WIP) Code orginazation/refactoring and beging nework refactoring...

This commit is contained in:
Jas Singh
2024-06-29 03:36:57 -07:00
parent 78496ae98a
commit 5ddf5c240d
18 changed files with 1109 additions and 984 deletions

View File

@@ -0,0 +1,58 @@
const audio = await Service.import("audio");
const renderInputDevices = (inputDevices) => {
if (!inputDevices.length) {
return [
Widget.Box({
class_name: `menu-unfound-button input`,
child: Widget.Box({
children: [
Widget.Label({
class_name: "menu-button-name input",
label: "No input devices found...",
}),
],
}),
}),
];
}
return inputDevices.map((device) => {
return Widget.Button({
on_primary_click: () => (audio.microphone = device),
class_name: `menu-button audio input ${device}`,
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
children: [
Widget.Label({
class_name: audio.microphone
.bind("description")
.as((v) =>
device.description === v
? "menu-button-icon active input"
: "menu-button-icon input",
),
label: "",
}),
Widget.Label({
truncate: "end",
wrap: true,
class_name: audio.microphone
.bind("description")
.as((v) =>
device.description === v
? "menu-button-name active input"
: "menu-button-name input",
),
label: device.description,
}),
],
}),
],
}),
});
});
};
export { renderInputDevices };

View File

@@ -0,0 +1,58 @@
const audio = await Service.import("audio");
const renderPlaybacks = (playbackDevices) => {
return playbackDevices.map((device) => {
if (device.description === "Dummy Output") {
return Widget.Box({
class_name: "menu-unfound-button playback",
child: Widget.Box({
children: [
Widget.Label({
class_name: "menu-button-name playback",
label: "No playback devices found...",
}),
],
}),
});
}
return Widget.Button({
class_name: `menu-button audio playback ${device}`,
on_primary_click: () => (audio.speaker = device),
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
children: [
Widget.Label({
truncate: "end",
wrap: true,
class_name: audio.speaker
.bind("description")
.as((v) =>
device.description === v
? "menu-button-icon active playback"
: "menu-button-icon playback",
),
label: "",
}),
Widget.Label({
class_name: audio.speaker
.bind("description")
.as((v) =>
device.description === v
? "menu-button-name active playback"
: "menu-button-name playback",
),
truncate: "end",
wrap: true,
label: device.description,
}),
],
}),
],
}),
});
});
};
export { renderPlaybacks };

View File

@@ -0,0 +1,66 @@
const audio = await Service.import("audio");
import { getIcon } from './utils.js';
const renderActiveInput = () => {
return [
Widget.Box({
class_name: "menu-slider-container input",
children: [
Widget.Button({
vexpand: false,
vpack: "end",
setup: (self) => {
self.hook(audio, () => {
const mic = audio.microphone;
const className = `menu-active-button input ${mic.is_muted ? "muted" : ""}`;
return (self.class_name = className);
});
},
on_primary_click: () =>
(audio.microphone.is_muted = !audio.microphone.is_muted),
child: Widget.Icon({
class_name: "menu-active-icon input",
setup: (self) => {
self.hook(audio, () => {
self.icon = getIcon(
audio.microphone.volume,
audio.microphone.is_muted,
)["mic"];
});
},
}),
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
class_name: "menu-active input",
hpack: "start",
truncate: "end",
wrap: true,
label: audio.bind("microphone").as((v) => v.description || ""),
}),
Widget.Slider({
value: audio.microphone.bind("volume").as((v) => v),
class_name: "menu-active-slider menu-slider inputs",
draw_value: false,
hexpand: true,
min: 0,
max: 1,
onChange: ({ value }) => (audio.microphone.volume = value),
}),
],
}),
Widget.Label({
class_name: "menu-active-percentage input",
vpack: "end",
label: audio.microphone
.bind("volume")
.as((v) => `${Math.floor(v * 100)}%`),
}),
],
}),
];
};
export { renderActiveInput };

View File

@@ -0,0 +1,67 @@
const audio = await Service.import("audio");
import { getIcon } from "./utils.js";
const renderActivePlayback = () => {
return [
Widget.Box({
class_name: "menu-slider-container playback",
children: [
Widget.Button({
vexpand: false,
vpack: "end",
setup: (self) => {
self.hook(audio, () => {
const spkr = audio.speaker;
const className = `menu-active-button playback ${spkr.is_muted ? "muted" : ""}`;
return (self.class_name = className);
});
},
on_primary_click: () =>
(audio.speaker.is_muted = !audio.speaker.is_muted),
child: Widget.Icon({
class_name: "menu-active-icon playback",
setup: (self) => {
self.hook(audio, () => {
self.icon = getIcon(
audio.speaker.volume,
audio.speaker.is_muted,
)["spkr"];
});
},
}),
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
class_name: "menu-active playback",
hpack: "start",
truncate: "end",
expand: true,
wrap: true,
label: audio.bind("speaker").as((v) => v.description || ""),
}),
Widget.Slider({
value: audio["speaker"].bind("volume"),
class_name: "menu-active-slider menu-slider playback",
draw_value: false,
hexpand: true,
min: 0,
max: 1,
onChange: ({ value }) => (audio.speaker.volume = value),
}),
],
}),
Widget.Label({
vpack: "end",
class_name: "menu-active-percentage playback",
label: audio.speaker
.bind("volume")
.as((v) => `${Math.floor(v * 100)}%`),
}),
],
}),
];
};
export { renderActivePlayback };

View File

@@ -1,294 +1,11 @@
const audio = await Service.import("audio");
import DropdownMenu from "../DropdownMenu.js";
import { renderInputDevices } from "./InputDevices.js";
import { renderPlaybacks } from "./PlaybackDevices.js";
import { renderActiveInput } from "./SelectedInput.js";
import { renderActivePlayback } from "./SelectedPlayback.js";
export default () => {
const renderPlaybacks = (playbackDevices) => {
return playbackDevices.map((device) => {
if (device.description === "Dummy Output") {
return Widget.Box({
class_name: "menu-unfound-button playback",
child: Widget.Box({
children: [
Widget.Label({
class_name: "menu-button-name playback",
label: "No playback devices found...",
}),
],
}),
});
}
return Widget.Button({
class_name: `menu-button audio playback ${device}`,
on_primary_click: () => (audio.speaker = device),
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
children: [
Widget.Label({
truncate: "end",
wrap: true,
class_name: audio.speaker
.bind("description")
.as((v) =>
device.description === v
? "menu-button-icon active playback"
: "menu-button-icon playback",
),
label: "",
}),
Widget.Label({
class_name: audio.speaker
.bind("description")
.as((v) =>
device.description === v
? "menu-button-name active playback"
: "menu-button-name playback",
),
truncate: "end",
wrap: true,
label: device.description,
}),
],
}),
Widget.Box({
hpack: "end",
expand: true,
children: [
Widget.Label({
class_name: "menu-button-isactive audio playback",
label: audio.speaker
.bind("description")
.as((v) => (device.description === v ? " " : "")),
}),
],
}),
],
}),
});
});
};
const getIcon = (audioVol, isMuted) => {
const speakerIcons = {
101: "audio-volume-overamplified-symbolic",
66: "audio-volume-high-symbolic",
34: "audio-volume-medium-symbolic",
1: "audio-volume-low-symbolic",
0: "audio-volume-muted-symbolic",
};
const inputIcons = {
66: "microphone-sensitivity-high-symbolic",
34: "microphone-sensitivity-medium-symbolic",
1: "microphone-sensitivity-low-symbolic",
0: "microphone-disabled-symbolic",
};
const icon = isMuted
? 0
: [101, 66, 34, 1, 0].find((threshold) => threshold <= audioVol * 100);
return {
spkr: speakerIcons[icon],
mic: inputIcons[icon],
};
};
const renderInputDevices = (inputDevices) => {
if (!inputDevices.length) {
return [
Widget.Box({
class_name: `menu-unfound-button input`,
child: Widget.Box({
children: [
Widget.Label({
class_name: "menu-button-name input",
label: "No input devices found...",
}),
],
}),
}),
];
}
return inputDevices.map((device) => {
return Widget.Button({
on_primary_click: () => (audio.microphone = device),
class_name: `menu-button audio input ${device}`,
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
children: [
Widget.Label({
class_name: audio.microphone
.bind("description")
.as((v) =>
device.description === v
? "menu-button-icon active input"
: "menu-button-icon input",
),
label: "",
}),
Widget.Label({
truncate: "end",
wrap: true,
class_name: audio.microphone
.bind("description")
.as((v) =>
device.description === v
? "menu-button-name active input"
: "menu-button-name input",
),
label: device.description,
}),
],
}),
Widget.Box({
hpack: "end",
expand: true,
children: [
Widget.Label({
class_name: "menu-button-isactive audio input",
truncate: "end",
wrap: true,
label: audio.microphone
.bind("description")
.as((v) => (device.description === v ? " " : "")),
}),
],
}),
],
}),
});
});
};
const renderActivePlayback = () => {
return [
Widget.Box({
class_name: "menu-slider-container playback",
children: [
Widget.Button({
vexpand: false,
vpack: "end",
setup: (self) => {
self.hook(audio, () => {
const spkr = audio.speaker;
const className = `menu-active-button playback ${spkr.is_muted ? "muted" : ""}`;
return (self.class_name = className);
});
},
on_primary_click: () =>
(audio.speaker.is_muted = !audio.speaker.is_muted),
child: Widget.Icon({
class_name: "menu-active-icon playback",
setup: (self) => {
self.hook(audio, () => {
self.icon = getIcon(
audio.speaker.volume,
audio.speaker.is_muted,
)["spkr"];
});
},
}),
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
class_name: "menu-active playback",
hpack: "start",
truncate: "end",
expand: true,
wrap: true,
label: audio.bind("speaker").as((v) => v.description || ""),
}),
Widget.Slider({
value: audio["speaker"].bind("volume"),
class_name: "menu-active-slider menu-slider playback",
draw_value: false,
hexpand: true,
min: 0,
max: 1,
onChange: ({ value }) => (audio.speaker.volume = value),
}),
],
}),
Widget.Label({
vpack: "end",
class_name: "menu-active-percentage playback",
label: audio.speaker
.bind("volume")
.as((v) => `${Math.floor(v * 100)}%`),
}),
],
}),
];
};
const renderActiveInput = () => {
return [
Widget.Box({
class_name: "menu-slider-container input",
children: [
Widget.Button({
vexpand: false,
vpack: "end",
setup: (self) => {
self.hook(audio, () => {
const mic = audio.microphone;
const className = `menu-active-button input ${mic.is_muted ? "muted" : ""}`;
return (self.class_name = className);
});
},
on_primary_click: () =>
(audio.microphone.is_muted = !audio.microphone.is_muted),
child: Widget.Icon({
class_name: "menu-active-icon input",
setup: (self) => {
self.hook(audio, () => {
self.icon = getIcon(
audio.microphone.volume,
audio.microphone.is_muted,
)["mic"];
});
},
}),
}),
Widget.Box({
vertical: true,
children: [
Widget.Label({
class_name: "menu-active input",
hpack: "start",
truncate: "end",
wrap: true,
label: audio.bind("microphone").as((v) => v.description || ""),
}),
Widget.Slider({
value: audio.microphone.bind("volume").as((v) => v),
class_name: "menu-active-slider menu-slider inputs",
draw_value: false,
hexpand: true,
min: 0,
max: 1,
onChange: ({ value }) => (audio.microphone.volume = value),
}),
],
}),
Widget.Label({
class_name: "menu-active-percentage input",
vpack: "end",
label: audio.microphone
.bind("volume")
.as((v) => `${Math.floor(v * 100)}%`),
}),
],
}),
];
};
return DropdownMenu({
name: "audiomenu",
transition: "crossfade",

View File

@@ -0,0 +1,27 @@
const getIcon = (audioVol, isMuted) => {
const speakerIcons = {
101: "audio-volume-overamplified-symbolic",
66: "audio-volume-high-symbolic",
34: "audio-volume-medium-symbolic",
1: "audio-volume-low-symbolic",
0: "audio-volume-muted-symbolic",
};
const inputIcons = {
66: "microphone-sensitivity-high-symbolic",
34: "microphone-sensitivity-medium-symbolic",
1: "microphone-sensitivity-low-symbolic",
0: "microphone-disabled-symbolic",
};
const icon = isMuted
? 0
: [101, 66, 34, 1, 0].find((threshold) => threshold <= audioVol * 100);
return {
spkr: speakerIcons[icon],
mic: inputIcons[icon],
};
};
export { getIcon };

View File

@@ -0,0 +1,67 @@
const network = await Service.import("network");
const Ethernet = () => {
return Widget.Box({
class_name: "menu-section-container ethernet",
vertical: true,
children: [
Widget.Box({
class_name: "menu-label-container",
hpack: "fill",
child: Widget.Label({
class_name: "menu-label",
hexpand: true,
hpack: "center",
label: "Ethernet",
}),
}),
Widget.Box({
class_name: "menu-items-section",
vertical: true,
children: [
Widget.Box({
class_name: "menu-content",
vertical: true,
child: network.bind("wired").as((wired) => {
return Widget.Box({
class_name: "network-element-item",
child: Widget.Box({
hpack: "start",
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
tooltip_text: wired.internet,
icon: `${wired["icon_name"]}`,
}),
Widget.Box({
class_name: "connection-container",
vertical: true,
children: [
Widget.Label({
class_name: "active-connection",
hpack: "start",
truncate: "end",
wrap: true,
label: `Ethernet Connection ${typeof wired.speed === "number" ? `(${wired.speed / 1000} Gbps)` : ""}`,
}),
Widget.Label({
hpack: "start",
class_name: "connection-status dim",
label:
wired.internet.charAt(0).toUpperCase() +
wired.internet.slice(1),
}),
],
}),
],
}),
});
}),
}),
],
}),
],
});
};
export { Ethernet };

View File

@@ -0,0 +1,39 @@
const renderWapStaging = (self, stagedDevice) => {
self.hook(stagedDevice, ({ value }) => {
return (self.child = Widget.Button({
class_name: "network-element-item",
child: Widget.Box({
hpack: "start",
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
icon: `${stagedDevice["iconName"]}`,
}),
Widget.Box({
class_name: "connection-container",
vertical: true,
children: [
Widget.Label({
class_name: "active-connection",
hpack: "start",
truncate: "end",
wrap: true,
label: stagedDevice.ssid,
}),
Widget.Revealer({
revealChild: stagedDevice.active,
child: Widget.Label({
hpack: "start",
class_name: "connection-status dim",
label: "Connected",
}),
}),
],
}),
],
}),
}));
});
};
export { renderWapStaging };

View File

@@ -0,0 +1,61 @@
const renderWAPs = (self, network) => {
self.hook(network, () => {
const WAPs = network.wifi.access_points;
console.log("WAPs");
console.log(JSON.stringify(WAPs, null, 2));
const filteredWAPs = WAPs.filter((ap) => ap.ssid !== "Unknown").sort(
(a, b) => {
return b.strength - a.strength;
},
);
if (filteredWAPs.length <= 0) {
return (self.child = Widget.Label({
class_name: "waps-not-found dim",
expand: true,
hpack: "center",
vpack: "center",
label: "No Wi-Fi Networks Found",
}));
}
return (self.children = filteredWAPs.map((ap) => {
return Widget.Button({
class_name: "network-element-item",
child: Widget.Box({
hpack: "start",
children: [
Widget.Icon({
class_name: "network-ethernet-icon",
icon: `${ap["iconName"]}`,
}),
Widget.Box({
class_name: "connection-container",
vertical: true,
children: [
Widget.Label({
class_name: "active-connection",
hpack: "start",
truncate: "end",
wrap: true,
label: ap.ssid,
}),
Widget.Revealer({
revealChild: ap.active,
child: Widget.Label({
hpack: "start",
class_name: "connection-status dim",
label: "Connected",
}),
}),
],
}),
],
}),
});
}));
});
};
export { renderWAPs };

View File

@@ -0,0 +1,45 @@
const network = await Service.import("network");
import { renderWAPs } from "./WirelessAPs.js";
import { renderWapStaging } from "./APStaging.js";
const Staging = Variable("none");
const Wifi = () => {
return Widget.Box({
class_name: "menu-section-container wifi",
vertical: true,
children: [
Widget.Box({
class_name: "menu-label-container",
hpack: "fill",
child: Widget.Label({
class_name: "menu-label",
hexpand: true,
hpack: "center",
label: "Wi-Fi",
}),
}),
Widget.Box({
class_name: "menu-items-section",
vertical: true,
children: [
Widget.Box({
class_name: "wap-staging",
setup: (self) => {
renderWapStaging(self, Staging);
},
}),
Widget.Box({
class_name: "available-waps",
vertical: true,
setup: (self) => {
renderWAPs(self, network);
},
}),
],
}),
],
});
};
export { Wifi };

View File

@@ -0,0 +1,483 @@
const network = await Service.import("network");
import DropdownMenu from "../DropdownMenu.js";
export default () => {
const pendingAuth = Variable("");
return DropdownMenu({
name: "networkmenu",
transition: "crossfade",
child: Widget.Box({
class_name: "menu-items",
child: Widget.Box({
vertical: true,
hexpand: true,
class_name: "menu-items-container network",
children: [
Widget.Box({
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Connected Network",
}),
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
children: Utils.merge(
[
network.bind("wired"),
network.bind("wifi"),
network.bind("primary"),
pendingAuth.bind("value"),
],
(wired, wifi, primary) => {
let sortedNetworks = [];
if (wifi.access_points.length > 0) {
sortedNetworks = wifi.access_points
.filter((ap) => ap.ssid !== "Unknown")
.sort((a, b) => {
return b.strength - a.strength;
});
}
const localIfConnected = () => {
if (primary === "wired") {
return [
Widget.Box({
class_name: `network-element-item-ethernet ${sortedNetworks.length > 0 ? "multi" : ""}`,
child: Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name: "network-element-items-container",
children: [
Widget.Button({
class_name: "menu-button-icon network",
child: Widget.Icon({
tooltip_text: wired.internet,
icon: `${wired["icon_name"]}`,
}),
}),
Widget.Label({
class_name: "menu-button-name network",
truncate: "end",
wrap: true,
label: `Ethernet (${wired.speed / 1000} Gbps)`,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
wired.internet.charAt(0).toUpperCase() +
wired.internet.slice(1),
}),
],
}),
],
}),
}),
];
}
return [];
};
const wifiIfConnected = () => {
const getIdBySsid = (ssid, nmcliOutput) => {
const lines = nmcliOutput.trim().split("\n");
for (const line of lines) {
const columns = line.trim().split(/\s{2,}/);
if (columns[0].includes(ssid)) {
return columns[1];
}
}
return null;
};
if (wifi.ssid !== "") {
return [
Widget.Box({
class_name: `network-element-item-ethernet`,
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name: "menu-button-icon network",
child: Widget.Icon({
tooltip_text: wifi.state,
icon: `${wifi["icon_name"]}`,
}),
}),
Widget.Label({
class_name: "menu-button-name network",
truncate: "end",
wrap: true,
label: wifi.ssid,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
wifi.internet.charAt(0).toUpperCase() +
wifi.internet.slice(1),
}),
],
}),
],
}),
Widget.Box({
hexpand: true,
hpack: "end",
children: [
Widget.Button({
class_name:
"menu-icon-button network disconnect",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection down ${connectionId} "${wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while disconnecting from wifi "${wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label(""),
}),
Widget.Box({
hexpand: true,
child: Widget.Button({
class_name: "menu-icon-button network forget",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection delete ${connectionId} "${wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while forgetting "${wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label("󰆴"),
}),
}),
],
}),
],
}),
];
}
return [];
};
return [...localIfConnected(), ...wifiIfConnected()];
},
),
}),
Widget.Box({
children: [
Widget.Box({
hpack: "start",
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Available Networks",
}),
}),
Widget.Box({
hexpand: true,
hpack: "end",
child: Widget.Button({
class_name: "menu-icon-button refresh network",
on_primary_click: () => {
network.wifi.scan();
},
child: Widget.Icon("view-refresh-symbolic"),
}),
}),
],
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
children: [
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(pendingAuth, () => {
const accPoint = network.wifi.access_points.find(
(ap) => ap.bssid === pendingAuth.value,
);
if (
pendingAuth.value !== "" &&
accPoint !== undefined &&
network.wifi.ssid !== pendingAuth.value
) {
return (self.child = Widget.Box({
vertical: true,
children: [
Widget.Button({
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) => (v === accPoint.bssid ? true : false)),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Box({
child: Widget.Entry({
hpack: "start",
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
Utils.execAsync(
`nmcli dev wifi connect ${accPoint.bssid} password ${selfInp.text}`,
)
.catch((err) => {
pendingAuth.value = "";
console.error(
`Failed to connect to wifi: ${accPoint.ssid}... ${err}`,
);
})
.then(() => (pendingAuth.value = ""));
selfInp.text = "";
},
}),
}),
Widget.Box({
class_name:
"network-password-input-close-container",
hexpand: true,
child: Widget.Button({
class_name: "network-password-input-close",
on_primary_click: () =>
(pendingAuth.value = ""),
child: Widget.Label("󰅜 "),
}),
}),
],
}),
}),
],
}));
} else {
self.children = [];
}
});
},
}),
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(network, () => {
let sortedNetworks = [];
self.hook(pendingAuth, () => {
if (network.wifi.access_points.length > 0) {
sortedNetworks = network.wifi.access_points
.filter((ap) => {
return (
ap.ssid !== "Unknown" &&
ap.bssid !== pendingAuth.value &&
!ap.active &&
network.wifi.ssid !== ap.ssid
);
})
.sort((a, b) => {
return b.strength - a.strength;
});
}
if (sortedNetworks.length <= 0) {
return (self.children = [
Widget.Label({
class_name: "not-found-label dim",
expand: true,
hpack: "center",
vpack: "center",
label: "No Wifi Networks Found",
}),
]);
}
return (self.children = sortedNetworks.map((accPoint) => {
return Widget.Box({
vertical: true,
children: [
Widget.Button({
on_primary_click: () => {
Utils.execAsync(
`nmcli device wifi connect ${accPoint.bssid}`,
).catch((err) => {
if (
err
.toLowerCase()
.includes(
"secrets were required, but not provided",
)
) {
pendingAuth.value = accPoint.bssid;
}
});
},
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) =>
v === accPoint.bssid ? true : false,
),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Entry({
hexpand: true,
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
selfInp.text = "";
},
}),
],
}),
}),
],
});
}));
});
});
},
}),
],
}),
],
}),
}),
});
};

View File

@@ -1,9 +1,9 @@
const network = await Service.import("network");
import DropdownMenu from "../DropdownMenu.js";
import { Ethernet } from "./Ethernet.js";
import { Wifi } from "./Wifi/index.js";
export default () => {
const pendingAuth = Variable("");
return DropdownMenu({
name: "networkmenu",
transition: "crossfade",
@@ -13,487 +13,7 @@ export default () => {
vertical: true,
hexpand: true,
class_name: "menu-items-container network",
children: [
Widget.Box({
class_name: "menu-dropdown-label-container",
hpack: "start",
children: [
Widget.Label({
class_name: "menu-dropdown-label network",
label: "Networks",
}),
],
}),
Widget.Box({
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Connected Network",
}),
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
setup: (self) => {
self.hook(network, () => {
self.hook(pendingAuth, () => {
let sortedNetworks = [];
if (network.wifi.access_points.length > 0) {
sortedNetworks = network.wifi.access_points
.filter((ap) => ap.ssid !== "Unknown")
.sort((a, b) => {
return b.strength - a.strength;
});
}
const localIfConnected = () => {
if (network.primary === "wired") {
return [
Widget.Box({
class_name: `network-element-item-ethernet ${sortedNetworks.length > 0 ? "multi" : ""}`,
child: Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name: "menu-button-icon network",
child: Widget.Icon({
tooltip_text: network.wired.internet,
icon: `${network.wired["icon_name"]}`,
}),
}),
Widget.Label({
class_name: "menu-button-name network",
truncate: "end",
wrap: true,
label: `Ethernet (${network.wired.speed / 1000} Gbps)`,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
network.wired.internet
.charAt(0)
.toUpperCase() +
network.wired.internet.slice(1),
}),
],
}),
],
}),
}),
];
}
return [];
};
const wifiIfConnected = () => {
const getIdBySsid = (ssid, nmcliOutput) => {
const lines = nmcliOutput.trim().split("\n");
for (const line of lines) {
const columns = line.trim().split(/\s{2,}/);
if (columns[0].includes(ssid)) {
return columns[1];
}
}
return null;
};
if (network.wifi.ssid !== "") {
return [
Widget.Box({
class_name: `network-element-item-ethernet`,
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text: network.wifi.state,
icon: `${network.wifi["icon_name"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: network.wifi.ssid,
}),
],
}),
],
}),
Widget.Box({
class_name:
"menu-button-name-container status dim",
children: [
Widget.Label({
class_name:
"menu-button-name status network dim",
label:
network.wifi.internet
.charAt(0)
.toUpperCase() +
network.wifi.internet.slice(1),
}),
],
}),
],
}),
Widget.Box({
hexpand: true,
hpack: "end",
children: [
Widget.Button({
class_name:
"menu-icon-button network disconnect",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
network.wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection down ${connectionId} "${network.wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while disconnecting from wifi "${network.wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label(""),
}),
Widget.Box({
hexpand: true,
child: Widget.Button({
class_name:
"menu-icon-button network forget",
on_primary_click: () => {
Utils.execAsync(
"nmcli connection show --active",
).then((res) => {
const connectionId = getIdBySsid(
network.wifi.ssid,
res,
);
Utils.execAsync(
`nmcli connection delete ${connectionId} "${network.wifi.ssid}"`,
).catch((err) =>
console.error(
`Error while forgetting "${network.wifi.ssid}": ${err}`,
),
);
});
},
child: Widget.Label("󰆴"),
}),
}),
],
}),
],
}),
];
}
return [];
};
return (self.children = [
...localIfConnected(),
...wifiIfConnected(),
]);
});
});
},
}),
Widget.Box({
children: [
Widget.Box({
hpack: "start",
class_name: "menu-label-container network",
child: Widget.Label({
class_name: "menu-label network",
hpack: "start",
label: "Available Networks",
}),
}),
Widget.Box({
hexpand: true,
hpack: "end",
child: Widget.Button({
class_name: "menu-icon-button refresh network",
on_primary_click: () => {
network.wifi.scan();
},
child: Widget.Icon("view-refresh-symbolic"),
}),
}),
],
}),
Widget.Box({
class_name: "menu-item-box network",
vertical: true,
children: [
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(pendingAuth, () => {
const accPoint = network.wifi.access_points.find(
(ap) => ap.bssid === pendingAuth.value,
);
if (
pendingAuth.value !== "" &&
accPoint !== undefined &&
network.wifi.ssid !== pendingAuth.value
) {
return (self.child = Widget.Box({
vertical: true,
children: [
Widget.Button({
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) => (v === accPoint.bssid ? true : false)),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Box({
child: Widget.Entry({
hpack: "start",
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
Utils.execAsync(
`nmcli dev wifi connect ${accPoint.bssid} password ${selfInp.text}`,
)
.catch((err) => {
pendingAuth.value = "";
console.error(
`Failed to connect to wifi: ${accPoint.ssid}... ${err}`,
);
})
.then(() => (pendingAuth.value = ""));
selfInp.text = "";
},
}),
}),
Widget.Box({
class_name:
"network-password-input-close-container",
hexpand: true,
child: Widget.Button({
class_name: "network-password-input-close",
on_primary_click: () =>
(pendingAuth.value = ""),
child: Widget.Label("󰅜 "),
}),
}),
],
}),
}),
],
}));
} else {
self.children = [];
}
});
},
}),
Widget.Box({
vertical: true,
setup: (self) => {
self.hook(network, () => {
let sortedNetworks = [];
self.hook(pendingAuth, () => {
if (network.wifi.access_points.length > 0) {
sortedNetworks = network.wifi.access_points
.filter((ap) => {
return (
ap.ssid !== "Unknown" &&
ap.bssid !== pendingAuth.value &&
!ap.active &&
network.wifi.ssid !== ap.ssid
);
})
.sort((a, b) => {
return b.strength - a.strength;
});
}
if (sortedNetworks.length <= 0) {
return self.children = [
Widget.Label({
class_name: "not-found-label dim",
expand: true,
hpack: "center",
vpack: "center",
label: "No Wifi Networks Found"
})
]
}
return (self.children = sortedNetworks.map((accPoint) => {
return Widget.Box({
vertical: true,
children: [
Widget.Button({
on_primary_click: () => {
Utils.execAsync(
`nmcli device wifi connect ${accPoint.bssid}`,
).catch((err) => {
if (
err
.toLowerCase()
.includes(
"secrets were required, but not provided",
)
) {
pendingAuth.value = accPoint.bssid;
}
});
},
class_name: "network-element-item",
child: Widget.Box({
children: [
Widget.Box({
hpack: "start",
vertical: true,
children: [
Widget.Box({
class_name:
"network-element-items-container",
children: [
Widget.Button({
class_name:
"menu-button-icon network",
child: Widget.Icon({
tooltip_text:
accPoint.ssid ===
network.wifi.ssid
? network.wifi.state
: null,
icon: `${accPoint["iconName"]}`,
}),
}),
Widget.Label({
class_name:
"menu-button-name network",
truncate: "end",
wrap: true,
label: accPoint.ssid,
}),
],
}),
],
}),
],
}),
}),
Widget.Revealer({
transition: "slide_down",
reveal_child: pendingAuth
.bind("value")
.as((v) =>
v === accPoint.bssid ? true : false,
),
class_name: "network-password-input-container",
child: Widget.Box({
hexpand: true,
children: [
Widget.Entry({
hexpand: true,
class_name: "network-password-input",
placeholder_text: "enter password",
visibility: false,
onAccept: (selfInp) => {
selfInp.text = "";
},
}),
],
}),
}),
],
});
}));
});
});
},
}),
],
}),
],
children: [Ethernet(), Wifi()],
}),
}),
});

View File

@@ -196,70 +196,77 @@ export default () => {
return (self.children = sortedNotifications.map((notif) => {
return Widget.Box({
class_name: "notification-card menu",
vpack: "center",
hexpand: true,
class_name: "notification-card-content-container",
children: [
...imageContainer(notif),
Widget.Box({
class_name: "notification-card menu",
vpack: "center",
vertical: true,
hexpand: true,
class_name: `notification-card-content ${notif.image === undefined ? "noimg" : " menu"}`,
children: [
...imageContainer(notif),
Widget.Box({
vertical: false,
vpack: "center",
vertical: true,
hexpand: true,
class_name: `notification-card-content ${notif.image === undefined ? "noimg" : " menu"}`,
children: [
Widget.Box({
class_name: "notification-card-header menu",
vertical: false,
hexpand: true,
vpack: "start",
children: [
Widget.Label({
Widget.Box({
class_name:
"notification-card-header-label menu",
hpack: "start",
"notification-card-header menu",
hexpand: true,
vexpand: true,
max_width_chars:
notif.image === undefined ? 27 : 20,
truncate: "end",
wrap: true,
label: notif["summary"],
vpack: "start",
children: [
Widget.Label({
class_name:
"notification-card-header-label menu",
hpack: "start",
hexpand: true,
vexpand: true,
max_width_chars:
notif.image === undefined ? 27 : 20,
truncate: "end",
wrap: true,
label: notif["summary"],
}),
],
}),
Widget.Box({
class_name:
"notification-card-header menu",
hexpand: true,
hpack: "end",
children: [NotificationIcon(notif)],
}),
],
}),
Widget.Box({
class_name: "notification-card-header menu",
vpack: "start",
hexpand: true,
hpack: "end",
children: [NotificationIcon(notif)],
class_name: "notification-card-body menu",
children: [
Widget.Label({
hexpand: true,
use_markup: true,
xalign: 0,
justification: "left",
truncate: "end",
lines: 2,
max_width_chars:
notif.image === undefined ? 35 : 28,
wrap: true,
class_name:
"notification-card-body-label menu",
label: notif["body"],
}),
],
}),
...actionsContainer(notif),
],
}),
Widget.Box({
vpack: "start",
hexpand: true,
class_name: "notification-card-body menu",
children: [
Widget.Label({
hexpand: true,
use_markup: true,
xalign: 0,
justification: "left",
truncate: "end",
lines: 2,
max_width_chars:
notif.image === undefined ? 35 : 28,
wrap: true,
class_name:
"notification-card-body-label menu",
label: notif["body"],
}),
],
}),
...actionsContainer(notif),
],
}),
Widget.Button({