Move wifi into QuickSettings popup with collapsible network list
This commit is contained in:
parent
b14533ef2b
commit
1c8a84ef21
|
|
@ -92,7 +92,6 @@ $module-bg: transparentize($base02, 0.4);
|
|||
}
|
||||
|
||||
.ws:hover,
|
||||
.wifi:hover,
|
||||
.battery:hover {
|
||||
background: transparentize($base05, 0.88);
|
||||
}
|
||||
|
|
@ -166,6 +165,26 @@ $module-bg: transparentize($base02, 0.4);
|
|||
}
|
||||
}
|
||||
|
||||
.wifi-section {
|
||||
margin-top: 10px;
|
||||
border-top: 1px solid $base02;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.wifi-toggle {
|
||||
padding: 4px 6px;
|
||||
border-radius: 6px;
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: transparentize($base05, 0.88);
|
||||
}
|
||||
}
|
||||
|
||||
.wifi-header {
|
||||
label {
|
||||
font-weight: bold;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { App, Astal, Gdk, Gtk } from "astal/gtk3"
|
|||
import Workspaces from "./Workspaces"
|
||||
import Logo from "./Logo"
|
||||
import Clock from "./Clock"
|
||||
import { WifiWidget } from "./Wifi"
|
||||
import { BatteryWidget } from "./Battery"
|
||||
import QuickSettings from "./QuickSettings"
|
||||
|
||||
|
|
@ -55,17 +54,14 @@ function Corner({ side }: { side: "left" | "right" }) {
|
|||
|
||||
export default function Bar(gdkmonitor: Gdk.Monitor) {
|
||||
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
|
||||
const wifi = WifiWidget(gdkmonitor)
|
||||
const battery = BatteryWidget(gdkmonitor)
|
||||
const quicksettings = QuickSettings(gdkmonitor)
|
||||
|
||||
const right: Array<JSX.Element> = []
|
||||
if (wifi.button) right.push(wifi.button)
|
||||
if (battery.button) right.push(battery.button)
|
||||
right.push(quicksettings.button)
|
||||
|
||||
const popups: Array<JSX.Element> = []
|
||||
if (wifi.popup) popups.push(wifi.popup)
|
||||
if (battery.popup) popups.push(battery.popup)
|
||||
popups.push(quicksettings.popup)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import AstalWp from "gi://AstalWp"
|
||||
import { execAsync, Variable, bind } from "astal"
|
||||
import Dropdown from "./Dropdown"
|
||||
import { wifiIcon, WifiSection } from "./Wifi"
|
||||
|
||||
const speaker = AstalWp.get_default().audio.default_speaker!
|
||||
const mic = AstalWp.get_default().audio.default_microphone
|
||||
|
|
@ -49,6 +50,7 @@ export default function QuickSettings(gdkmonitor: Gdk.Monitor) {
|
|||
<box spacing={6}>
|
||||
<icon icon={speakerIcon()} />
|
||||
{micIcon && <icon icon={micIcon()} />}
|
||||
{wifiIcon && <icon icon={wifiIcon} />}
|
||||
</box>
|
||||
</button>
|
||||
)
|
||||
|
|
@ -95,6 +97,7 @@ export default function QuickSettings(gdkmonitor: Gdk.Monitor) {
|
|||
/>
|
||||
</box>
|
||||
)}
|
||||
<WifiSection open={open} />
|
||||
</Dropdown>
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import Gtk from "gi://Gtk?version=3.0"
|
||||
import AstalNetwork from "gi://AstalNetwork"
|
||||
import { type Binding, Variable, bind } from "astal"
|
||||
import Dropdown from "./Dropdown"
|
||||
import { type Binding, type Variable, Variable, bind } from "astal"
|
||||
|
||||
const CONNECTING = [40, 50, 60, 70, 80, 90]
|
||||
|
||||
const wifi = AstalNetwork.get_default().wifi
|
||||
|
||||
function strongest(aps: AstalNetwork.AccessPoint[]) {
|
||||
const bySsid = new Map<string, AstalNetwork.AccessPoint>()
|
||||
for (const ap of aps) {
|
||||
|
|
@ -15,6 +16,10 @@ function strongest(aps: AstalNetwork.AccessPoint[]) {
|
|||
return [...bySsid.values()].sort((a, b) => b.strength - a.strength)
|
||||
}
|
||||
|
||||
export const wifiIcon: Binding<string> | null = wifi
|
||||
? bind(wifi, "icon-name")
|
||||
: null
|
||||
|
||||
function WifiRow(
|
||||
ap: AstalNetwork.AccessPoint,
|
||||
activeSsid: Binding<string>,
|
||||
|
|
@ -43,12 +48,10 @@ function WifiRow(
|
|||
)
|
||||
}
|
||||
|
||||
export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
||||
const wifi = AstalNetwork.get_default().wifi
|
||||
export function WifiSection({ open }: { open: Variable<boolean> }) {
|
||||
if (!wifi) return <box />
|
||||
|
||||
if (!wifi) return { button: null, popup: null }
|
||||
|
||||
const open = Variable(false)
|
||||
const expanded = Variable(false)
|
||||
const pendingAP = Variable<AstalNetwork.AccessPoint | null>(null)
|
||||
const failed = Variable("")
|
||||
|
||||
|
|
@ -97,19 +100,34 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
|||
/>
|
||||
)
|
||||
|
||||
const button = (
|
||||
<button
|
||||
className="wifi"
|
||||
onClicked={() => open.set(!open.get())}
|
||||
>
|
||||
<icon icon={bind(wifi, "icon-name")} />
|
||||
</button>
|
||||
)
|
||||
open.subscribe((v) => {
|
||||
if (v) {
|
||||
wifi.scan()
|
||||
} else {
|
||||
expanded.set(false)
|
||||
pendingAP.set(null)
|
||||
failed.set("")
|
||||
passwordEntry.text = ""
|
||||
}
|
||||
})
|
||||
|
||||
const popup = (
|
||||
<Dropdown gdkmonitor={gdkmonitor} target={button} open={open} width={260}>
|
||||
return (
|
||||
<box className="wifi-section" vertical>
|
||||
<box className="wifi-header">
|
||||
<label label="Wi-Fi" hexpand halign={Gtk.Align.START} />
|
||||
<button
|
||||
className="wifi-toggle"
|
||||
onClicked={() => expanded.set(!expanded.get())}
|
||||
>
|
||||
<box spacing={6}>
|
||||
<icon icon={bind(wifi, "icon-name")} />
|
||||
<label label="Wi-Fi" />
|
||||
<icon
|
||||
icon={expanded().as((v) =>
|
||||
v ? "pan-down-symbolic" : "pan-end-symbolic",
|
||||
)}
|
||||
/>
|
||||
</box>
|
||||
</button>
|
||||
<button className="wifi-rescan" onClicked={() => wifi.scan()}>
|
||||
<icon icon="view-refresh-symbolic" />
|
||||
</button>
|
||||
|
|
@ -121,6 +139,12 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
|||
}}
|
||||
/>
|
||||
</box>
|
||||
<revealer
|
||||
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
|
||||
transitionDuration={180}
|
||||
revealChild={bind(expanded)}
|
||||
>
|
||||
<box vertical>
|
||||
<label
|
||||
className="wifi-status"
|
||||
label={status()}
|
||||
|
|
@ -141,22 +165,14 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
|||
>
|
||||
<box vertical>
|
||||
{bind(wifi, "access-points").as((aps) =>
|
||||
strongest(aps).map((ap) => WifiRow(ap, activeSsid, connect))
|
||||
strongest(aps).map((ap) =>
|
||||
WifiRow(ap, activeSsid, connect)
|
||||
),
|
||||
)}
|
||||
</box>
|
||||
</scrollable>
|
||||
</Dropdown>
|
||||
</box>
|
||||
</revealer>
|
||||
</box>
|
||||
)
|
||||
|
||||
open.subscribe((v) => {
|
||||
if (v) {
|
||||
wifi.scan()
|
||||
} else {
|
||||
pendingAP.set(null)
|
||||
failed.set("")
|
||||
passwordEntry.text = ""
|
||||
}
|
||||
})
|
||||
|
||||
return { button, popup }
|
||||
}
|
||||
Loading…
Reference in New Issue