(WIP) Code orginazation/refactoring and beging nework refactoring...
This commit is contained in:
58
modules/menus/audio/InputDevices.js
Normal file
58
modules/menus/audio/InputDevices.js
Normal 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 };
|
||||||
58
modules/menus/audio/PlaybackDevices.js
Normal file
58
modules/menus/audio/PlaybackDevices.js
Normal 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 };
|
||||||
66
modules/menus/audio/SelectedInput.js
Normal file
66
modules/menus/audio/SelectedInput.js
Normal 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 };
|
||||||
67
modules/menus/audio/SelectedPlayback.js
Normal file
67
modules/menus/audio/SelectedPlayback.js
Normal 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 };
|
||||||
@@ -1,294 +1,11 @@
|
|||||||
const audio = await Service.import("audio");
|
const audio = await Service.import("audio");
|
||||||
import DropdownMenu from "../DropdownMenu.js";
|
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 () => {
|
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({
|
return DropdownMenu({
|
||||||
name: "audiomenu",
|
name: "audiomenu",
|
||||||
transition: "crossfade",
|
transition: "crossfade",
|
||||||
|
|||||||
27
modules/menus/audio/utils.js
Normal file
27
modules/menus/audio/utils.js
Normal 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 };
|
||||||
67
modules/menus/network/Ethernet.js
Normal file
67
modules/menus/network/Ethernet.js
Normal 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 };
|
||||||
39
modules/menus/network/Wifi/APStaging.js
Normal file
39
modules/menus/network/Wifi/APStaging.js
Normal 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 };
|
||||||
61
modules/menus/network/Wifi/WirelessAPs.js
Normal file
61
modules/menus/network/Wifi/WirelessAPs.js
Normal 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 };
|
||||||
45
modules/menus/network/Wifi/index.js
Normal file
45
modules/menus/network/Wifi/index.js
Normal 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 };
|
||||||
483
modules/menus/network/index.bkup.js
Normal file
483
modules/menus/network/index.bkup.js
Normal 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 = "";
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
const network = await Service.import("network");
|
const network = await Service.import("network");
|
||||||
import DropdownMenu from "../DropdownMenu.js";
|
import DropdownMenu from "../DropdownMenu.js";
|
||||||
|
import { Ethernet } from "./Ethernet.js";
|
||||||
|
import { Wifi } from "./Wifi/index.js";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const pendingAuth = Variable("");
|
|
||||||
|
|
||||||
return DropdownMenu({
|
return DropdownMenu({
|
||||||
name: "networkmenu",
|
name: "networkmenu",
|
||||||
transition: "crossfade",
|
transition: "crossfade",
|
||||||
@@ -13,487 +13,7 @@ export default () => {
|
|||||||
vertical: true,
|
vertical: true,
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
class_name: "menu-items-container network",
|
class_name: "menu-items-container network",
|
||||||
children: [
|
children: [Ethernet(), Wifi()],
|
||||||
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 = "";
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -196,6 +196,9 @@ export default () => {
|
|||||||
|
|
||||||
return (self.children = sortedNotifications.map((notif) => {
|
return (self.children = sortedNotifications.map((notif) => {
|
||||||
return Widget.Box({
|
return Widget.Box({
|
||||||
|
class_name: "notification-card-content-container",
|
||||||
|
children: [
|
||||||
|
Widget.Box({
|
||||||
class_name: "notification-card menu",
|
class_name: "notification-card menu",
|
||||||
vpack: "center",
|
vpack: "center",
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
@@ -212,7 +215,8 @@ export default () => {
|
|||||||
hexpand: true,
|
hexpand: true,
|
||||||
children: [
|
children: [
|
||||||
Widget.Box({
|
Widget.Box({
|
||||||
class_name: "notification-card-header menu",
|
class_name:
|
||||||
|
"notification-card-header menu",
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
vpack: "start",
|
vpack: "start",
|
||||||
children: [
|
children: [
|
||||||
@@ -231,7 +235,8 @@ export default () => {
|
|||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
Widget.Box({
|
Widget.Box({
|
||||||
class_name: "notification-card-header menu",
|
class_name:
|
||||||
|
"notification-card-header menu",
|
||||||
hexpand: true,
|
hexpand: true,
|
||||||
hpack: "end",
|
hpack: "end",
|
||||||
children: [NotificationIcon(notif)],
|
children: [NotificationIcon(notif)],
|
||||||
@@ -262,6 +267,8 @@ export default () => {
|
|||||||
...actionsContainer(notif),
|
...actionsContainer(notif),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
Widget.Button({
|
Widget.Button({
|
||||||
class_name: "close-notification-button menu",
|
class_name: "close-notification-button menu",
|
||||||
on_primary_click: () => {
|
on_primary_click: () => {
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ tooltip label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-section-container {
|
.menu-section-container {
|
||||||
|
margin: 1.35em 0em;
|
||||||
|
|
||||||
.menu-label {
|
.menu-label {
|
||||||
color: $text;
|
color: $text;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
@@ -118,16 +120,18 @@ tooltip label {
|
|||||||
min-height: 2em;
|
min-height: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
margin: 1.35em 0em;
|
&:first-child {
|
||||||
|
|
||||||
&.volume {
|
|
||||||
margin-bottom: 0em;
|
margin-bottom: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.input {
|
&:last-child {
|
||||||
margin-top: 0em;
|
margin-top: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
margin-top: 1.35em;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-items-section {
|
.menu-items-section {
|
||||||
background: $base;
|
background: $base;
|
||||||
border-radius: 0.4em;
|
border-radius: 0.4em;
|
||||||
@@ -135,13 +139,6 @@ tooltip label {
|
|||||||
border-top-right-radius: 0em;
|
border-top-right-radius: 0em;
|
||||||
padding: 0.9em;
|
padding: 0.9em;
|
||||||
margin: 0em 1.35em;
|
margin: 0em 1.35em;
|
||||||
|
|
||||||
&.selected {
|
|
||||||
margin-bottom: 0em;
|
|
||||||
}
|
|
||||||
&.input {
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +229,10 @@ tooltip label {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $overlay0;
|
color: $overlay0;
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $maroon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item-box {
|
.menu-item-box {
|
||||||
|
|||||||
@@ -1,91 +1,38 @@
|
|||||||
@import "../colors";
|
@import "../colors";
|
||||||
|
|
||||||
.menu-dropdown-label.network {
|
.menu-items-container.network {
|
||||||
|
.menu-items-section {
|
||||||
|
padding-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.menu-label {
|
||||||
color: $mauve;
|
color: $mauve;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-element-item-ethernet.multi {
|
.network-ethernet-icon {
|
||||||
margin-bottom: 0.5rem;
|
font-size: 1.3em;
|
||||||
}
|
|
||||||
|
|
||||||
.menu-button-name.status.network {
|
|
||||||
margin-left: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-label.network {
|
|
||||||
color: $mauve;
|
color: $mauve;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-element-items-container * {
|
.connection-container {
|
||||||
font-size: 0.95em;
|
margin-left: 1em;
|
||||||
}
|
}
|
||||||
|
.connection-status {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
.menu-section-container.wifi {
|
||||||
|
.menu-items-section {
|
||||||
|
min-height: 5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-element-item {
|
||||||
|
|
||||||
.network-element-item {
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
margin-bottom: 0.4em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $mauve;
|
color: $mauve;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.menu-button-icon.network {
|
|
||||||
color: $overlay2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-password-input {
|
|
||||||
border-radius: 0.4rem;
|
|
||||||
background: $crust;
|
|
||||||
padding: 0.4rem;
|
|
||||||
margin-left: 2.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: 0.85em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.refresh.network {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $mauve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-password-input-close {
|
|
||||||
margin-left: 0.75rem;
|
|
||||||
margin-bottom: 0.6rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $sky;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.45em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.network.disconnect {
|
|
||||||
margin-bottom: 1.4rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $mauve;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.network.forget {
|
|
||||||
margin-bottom: 1.4rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $mauve;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 1.35em;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,15 @@
|
|||||||
margin: 0em;
|
margin: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-card-content-container {
|
||||||
|
&:first-child {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.menu-label-container.notifications {
|
.menu-label-container.notifications {
|
||||||
margin: 0em;
|
margin: 0em;
|
||||||
padding: 0em;
|
padding: 0em;
|
||||||
|
|||||||
111
style.css
111
style.css
@@ -523,12 +523,15 @@ tooltip label {
|
|||||||
margin: 0em 1.35em;
|
margin: 0em 1.35em;
|
||||||
min-height: 2em;
|
min-height: 2em;
|
||||||
}
|
}
|
||||||
.menu-section-container.volume {
|
.menu-section-container:first-child {
|
||||||
margin-bottom: 0em;
|
margin-bottom: 0em;
|
||||||
}
|
}
|
||||||
.menu-section-container.input {
|
.menu-section-container:last-child {
|
||||||
margin-top: 0em;
|
margin-top: 0em;
|
||||||
}
|
}
|
||||||
|
.menu-section-container:nth-child(2) {
|
||||||
|
margin-top: 1.35em;
|
||||||
|
}
|
||||||
.menu-section-container .menu-items-section {
|
.menu-section-container .menu-items-section {
|
||||||
background: #1e1e2e;
|
background: #1e1e2e;
|
||||||
border-radius: 0.4em;
|
border-radius: 0.4em;
|
||||||
@@ -537,12 +540,6 @@ tooltip label {
|
|||||||
padding: 0.9em;
|
padding: 0.9em;
|
||||||
margin: 0em 1.35em;
|
margin: 0em 1.35em;
|
||||||
}
|
}
|
||||||
.menu-section-container .menu-items-section.selected {
|
|
||||||
margin-bottom: 0em;
|
|
||||||
}
|
|
||||||
.menu-section-container .menu-items-section.input {
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-active {
|
.menu-active {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
@@ -628,6 +625,9 @@ tooltip label {
|
|||||||
color: #6c7086;
|
color: #6c7086;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
.menu-button-icon.active {
|
||||||
|
color: #eba0ac;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-item-box {
|
.menu-item-box {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
@@ -826,86 +826,32 @@ window#powermenu .powermenu.box {
|
|||||||
color: #eba0ac;
|
color: #eba0ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-dropdown-label.network {
|
.menu-items-container.network .menu-items-section {
|
||||||
|
padding-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
.menu-items-container.network .menu-label {
|
||||||
color: #cba6f7;
|
color: #cba6f7;
|
||||||
}
|
}
|
||||||
|
.menu-items-container.network .network-ethernet-icon {
|
||||||
.network-element-item-ethernet.multi {
|
font-size: 1.3em;
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-button-name.status.network {
|
|
||||||
margin-left: 2.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-label.network {
|
|
||||||
color: #cba6f7;
|
color: #cba6f7;
|
||||||
}
|
}
|
||||||
|
.menu-items-container.network .connection-container {
|
||||||
.network-element-items-container * {
|
margin-left: 1em;
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
}
|
||||||
|
.menu-items-container.network .connection-status {
|
||||||
.network-element-item:not(:last-child) {
|
font-size: 0.9em;
|
||||||
margin-bottom: 0.4em;
|
|
||||||
}
|
}
|
||||||
.network-element-item:hover {
|
.menu-items-container.network .menu-section-container.wifi .menu-items-section {
|
||||||
|
min-height: 5em;
|
||||||
|
}
|
||||||
|
.menu-items-container.network .network-element-item:not(:last-child) {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.menu-items-container.network .network-element-item:hover {
|
||||||
color: #cba6f7;
|
color: #cba6f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-button-icon.network {
|
|
||||||
color: #9399b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-password-input {
|
|
||||||
border-radius: 0.4rem;
|
|
||||||
background: #11111b;
|
|
||||||
padding: 0.4rem;
|
|
||||||
margin-left: 2.5rem;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: 0.85em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.refresh.network {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
.menu-icon-button.refresh.network:hover {
|
|
||||||
color: #cba6f7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.network-password-input-close {
|
|
||||||
margin-left: 0.75rem;
|
|
||||||
margin-bottom: 0.6rem;
|
|
||||||
}
|
|
||||||
.network-password-input-close:hover {
|
|
||||||
color: #89dceb;
|
|
||||||
}
|
|
||||||
.network-password-input-close label {
|
|
||||||
font-size: 1.45em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.network.disconnect {
|
|
||||||
margin-bottom: 1.4rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
.menu-icon-button.network.disconnect:hover {
|
|
||||||
color: #cba6f7;
|
|
||||||
}
|
|
||||||
.menu-icon-button.network.disconnect label {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon-button.network.forget {
|
|
||||||
margin-bottom: 1.4rem;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
.menu-icon-button.network.forget:hover {
|
|
||||||
color: #cba6f7;
|
|
||||||
}
|
|
||||||
.menu-icon-button.network.forget label {
|
|
||||||
font-size: 1.35em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-dropdown-label.bluetooth {
|
.menu-dropdown-label.bluetooth {
|
||||||
color: #89dceb;
|
color: #89dceb;
|
||||||
}
|
}
|
||||||
@@ -1093,6 +1039,13 @@ image {
|
|||||||
margin: 0em;
|
margin: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification-card-content-container:first-child {
|
||||||
|
margin-top: 0.5em;
|
||||||
|
}
|
||||||
|
.notification-card-content-container:not(:last-child) {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-label-container.notifications {
|
.menu-label-container.notifications {
|
||||||
margin: 0em;
|
margin: 0em;
|
||||||
padding: 0em;
|
padding: 0em;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user