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,
|
.ws:hover,
|
||||||
.wifi:hover,
|
|
||||||
.battery:hover {
|
.battery:hover {
|
||||||
background: transparentize($base05, 0.88);
|
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 {
|
.wifi-header {
|
||||||
label {
|
label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import { App, Astal, Gdk, Gtk } from "astal/gtk3"
|
||||||
import Workspaces from "./Workspaces"
|
import Workspaces from "./Workspaces"
|
||||||
import Logo from "./Logo"
|
import Logo from "./Logo"
|
||||||
import Clock from "./Clock"
|
import Clock from "./Clock"
|
||||||
import { WifiWidget } from "./Wifi"
|
|
||||||
import { BatteryWidget } from "./Battery"
|
import { BatteryWidget } from "./Battery"
|
||||||
import QuickSettings from "./QuickSettings"
|
import QuickSettings from "./QuickSettings"
|
||||||
|
|
||||||
|
|
@ -55,17 +54,14 @@ function Corner({ side }: { side: "left" | "right" }) {
|
||||||
|
|
||||||
export default function Bar(gdkmonitor: Gdk.Monitor) {
|
export default function Bar(gdkmonitor: Gdk.Monitor) {
|
||||||
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
|
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
|
||||||
const wifi = WifiWidget(gdkmonitor)
|
|
||||||
const battery = BatteryWidget(gdkmonitor)
|
const battery = BatteryWidget(gdkmonitor)
|
||||||
const quicksettings = QuickSettings(gdkmonitor)
|
const quicksettings = QuickSettings(gdkmonitor)
|
||||||
|
|
||||||
const right: Array<JSX.Element> = []
|
const right: Array<JSX.Element> = []
|
||||||
if (wifi.button) right.push(wifi.button)
|
|
||||||
if (battery.button) right.push(battery.button)
|
if (battery.button) right.push(battery.button)
|
||||||
right.push(quicksettings.button)
|
right.push(quicksettings.button)
|
||||||
|
|
||||||
const popups: Array<JSX.Element> = []
|
const popups: Array<JSX.Element> = []
|
||||||
if (wifi.popup) popups.push(wifi.popup)
|
|
||||||
if (battery.popup) popups.push(battery.popup)
|
if (battery.popup) popups.push(battery.popup)
|
||||||
popups.push(quicksettings.popup)
|
popups.push(quicksettings.popup)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import AstalWp from "gi://AstalWp"
|
import AstalWp from "gi://AstalWp"
|
||||||
import { execAsync, Variable, bind } from "astal"
|
import { execAsync, Variable, bind } from "astal"
|
||||||
import Dropdown from "./Dropdown"
|
import Dropdown from "./Dropdown"
|
||||||
|
import { wifiIcon, WifiSection } from "./Wifi"
|
||||||
|
|
||||||
const speaker = AstalWp.get_default().audio.default_speaker!
|
const speaker = AstalWp.get_default().audio.default_speaker!
|
||||||
const mic = AstalWp.get_default().audio.default_microphone
|
const mic = AstalWp.get_default().audio.default_microphone
|
||||||
|
|
@ -49,6 +50,7 @@ export default function QuickSettings(gdkmonitor: Gdk.Monitor) {
|
||||||
<box spacing={6}>
|
<box spacing={6}>
|
||||||
<icon icon={speakerIcon()} />
|
<icon icon={speakerIcon()} />
|
||||||
{micIcon && <icon icon={micIcon()} />}
|
{micIcon && <icon icon={micIcon()} />}
|
||||||
|
{wifiIcon && <icon icon={wifiIcon} />}
|
||||||
</box>
|
</box>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
@ -95,6 +97,7 @@ export default function QuickSettings(gdkmonitor: Gdk.Monitor) {
|
||||||
/>
|
/>
|
||||||
</box>
|
</box>
|
||||||
)}
|
)}
|
||||||
|
<WifiSection open={open} />
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import Gtk from "gi://Gtk?version=3.0"
|
import Gtk from "gi://Gtk?version=3.0"
|
||||||
import AstalNetwork from "gi://AstalNetwork"
|
import AstalNetwork from "gi://AstalNetwork"
|
||||||
import { type Binding, Variable, bind } from "astal"
|
import { type Binding, type Variable, Variable, bind } from "astal"
|
||||||
import Dropdown from "./Dropdown"
|
|
||||||
|
|
||||||
const CONNECTING = [40, 50, 60, 70, 80, 90]
|
const CONNECTING = [40, 50, 60, 70, 80, 90]
|
||||||
|
|
||||||
|
const wifi = AstalNetwork.get_default().wifi
|
||||||
|
|
||||||
function strongest(aps: AstalNetwork.AccessPoint[]) {
|
function strongest(aps: AstalNetwork.AccessPoint[]) {
|
||||||
const bySsid = new Map<string, AstalNetwork.AccessPoint>()
|
const bySsid = new Map<string, AstalNetwork.AccessPoint>()
|
||||||
for (const ap of aps) {
|
for (const ap of aps) {
|
||||||
|
|
@ -15,6 +16,10 @@ function strongest(aps: AstalNetwork.AccessPoint[]) {
|
||||||
return [...bySsid.values()].sort((a, b) => b.strength - a.strength)
|
return [...bySsid.values()].sort((a, b) => b.strength - a.strength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const wifiIcon: Binding<string> | null = wifi
|
||||||
|
? bind(wifi, "icon-name")
|
||||||
|
: null
|
||||||
|
|
||||||
function WifiRow(
|
function WifiRow(
|
||||||
ap: AstalNetwork.AccessPoint,
|
ap: AstalNetwork.AccessPoint,
|
||||||
activeSsid: Binding<string>,
|
activeSsid: Binding<string>,
|
||||||
|
|
@ -43,12 +48,10 @@ function WifiRow(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
export function WifiSection({ open }: { open: Variable<boolean> }) {
|
||||||
const wifi = AstalNetwork.get_default().wifi
|
if (!wifi) return <box />
|
||||||
|
|
||||||
if (!wifi) return { button: null, popup: null }
|
const expanded = Variable(false)
|
||||||
|
|
||||||
const open = Variable(false)
|
|
||||||
const pendingAP = Variable<AstalNetwork.AccessPoint | null>(null)
|
const pendingAP = Variable<AstalNetwork.AccessPoint | null>(null)
|
||||||
const failed = Variable("")
|
const failed = Variable("")
|
||||||
|
|
||||||
|
|
@ -97,19 +100,34 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
const button = (
|
open.subscribe((v) => {
|
||||||
<button
|
if (v) {
|
||||||
className="wifi"
|
wifi.scan()
|
||||||
onClicked={() => open.set(!open.get())}
|
} else {
|
||||||
>
|
expanded.set(false)
|
||||||
<icon icon={bind(wifi, "icon-name")} />
|
pendingAP.set(null)
|
||||||
</button>
|
failed.set("")
|
||||||
)
|
passwordEntry.text = ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const popup = (
|
return (
|
||||||
<Dropdown gdkmonitor={gdkmonitor} target={button} open={open} width={260}>
|
<box className="wifi-section" vertical>
|
||||||
<box className="wifi-header">
|
<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()}>
|
<button className="wifi-rescan" onClicked={() => wifi.scan()}>
|
||||||
<icon icon="view-refresh-symbolic" />
|
<icon icon="view-refresh-symbolic" />
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -121,6 +139,12 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</box>
|
</box>
|
||||||
|
<revealer
|
||||||
|
transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
|
||||||
|
transitionDuration={180}
|
||||||
|
revealChild={bind(expanded)}
|
||||||
|
>
|
||||||
|
<box vertical>
|
||||||
<label
|
<label
|
||||||
className="wifi-status"
|
className="wifi-status"
|
||||||
label={status()}
|
label={status()}
|
||||||
|
|
@ -141,22 +165,14 @@ export function WifiWidget(gdkmonitor: Gdk.Monitor) {
|
||||||
>
|
>
|
||||||
<box vertical>
|
<box vertical>
|
||||||
{bind(wifi, "access-points").as((aps) =>
|
{bind(wifi, "access-points").as((aps) =>
|
||||||
strongest(aps).map((ap) => WifiRow(ap, activeSsid, connect))
|
strongest(aps).map((ap) =>
|
||||||
|
WifiRow(ap, activeSsid, connect)
|
||||||
|
),
|
||||||
)}
|
)}
|
||||||
</box>
|
</box>
|
||||||
</scrollable>
|
</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