diff --git a/modules/bar/network/index.js b/modules/bar/network/index.js index b91e21a..9404182 100644 --- a/modules/bar/network/index.js +++ b/modules/bar/network/index.js @@ -11,7 +11,7 @@ const Network = () => { Widget.Label({ label: network.wifi .bind("ssid") - .as((ssid) => (ssid ? ` ${ssid}` : " --").substring(0, 7)), + .as((ssid) => (ssid ? ` ${ssid}` : " --").substring(0, 7)), }), ]; diff --git a/modules/menus/network/wifi/WirelessAPs.js b/modules/menus/network/wifi/WirelessAPs.js index 5135bb7..04794ef 100644 --- a/modules/menus/network/wifi/WirelessAPs.js +++ b/modules/menus/network/wifi/WirelessAPs.js @@ -30,8 +30,24 @@ const renderWAPs = (self, network, staging, connecting) => { [network.bind("wifi"), staging.bind("value"), connecting.bind("value")], () => { // Sometimes the network service will yield a "this._device is undefined" when - // trying to access the "access_points" property. So we must check if it exists. - const WAPs = Object.hasOwnProperty.call(network.wifi, "access_points") ? network.wifi.access_points : []; + // trying to access the "access_points" property. So we must validate that + // it's not 'undefined' + let WAPs = network.wifi["access_points"] !== undefined + ? network.wifi["access-points"] + : []; + + const dedupeWAPs = () => { + const dedupMap = {}; + WAPs.forEach((item) => { + if (!Object.hasOwnProperty.call(dedupMap, item.ssid)) { + dedupMap[item.ssid] = item; + } + }) + + return Object.keys(dedupMap).map(itm => dedupMap[itm]); + } + + WAPs = dedupeWAPs(); const isInStaging = (wap) => { if (Object.keys(staging.value).length === 0) { @@ -49,7 +65,9 @@ const renderWAPs = (self, network, staging, connecting) => { }; const filteredWAPs = WAPs.filter( - (ap) => ap.ssid !== "Unknown" && !isInStaging(ap), + (ap) => { + return ap.ssid !== "Unknown" && !isInStaging(ap) + }, ).sort((a, b) => { if (network.wifi.ssid === a.ssid) { return -1; @@ -136,7 +154,7 @@ const renderWAPs = (self, network, staging, connecting) => { class_name: "connection-status dim", label: WifiStatusMap[ - network.wifi.state.toLowerCase() + network.wifi.state.toLowerCase() ], }), }), diff --git a/modules/menus/network/wifi/index.js b/modules/menus/network/wifi/index.js index e4608ca..1554c2f 100644 --- a/modules/menus/network/wifi/index.js +++ b/modules/menus/network/wifi/index.js @@ -5,6 +5,15 @@ import { renderWapStaging } from "./APStaging.js"; const Staging = Variable({}); const Connecting = Variable(""); +const searchInProgress = Variable(false); + +const startRotation = () => { + searchInProgress.value = true; + setTimeout(() => { + searchInProgress.value = false; + }, 5 * 1000); +}; + const Wifi = () => { return Widget.Box({ class_name: "menu-section-container wifi", @@ -13,12 +22,29 @@ const Wifi = () => { Widget.Box({ class_name: "menu-label-container", hpack: "fill", - child: Widget.Label({ - class_name: "menu-label", - hexpand: true, - hpack: "start", - label: "Wi-Fi", - }), + children: [ + Widget.Label({ + class_name: "menu-label", + hexpand: true, + hpack: "start", + label: "Wi-Fi", + }), + Widget.Button({ + vpack: "center", + hpack: "end", + class_name: "menu-icon-button search network", + on_primary_click: () => { + startRotation(); + network.wifi.scan(); + }, + child: Widget.Icon({ + class_name: searchInProgress + .bind("value") + .as((v) => (v ? "spinning" : "")), + icon: "view-refresh-symbolic", + }), + }), + ], }), Widget.Box({ class_name: "menu-items-section", diff --git a/scss/menus/bluetooth.scss b/scss/menus/bluetooth.scss index 0c0146b..e166dff 100644 --- a/scss/menus/bluetooth.scss +++ b/scss/menus/bluetooth.scss @@ -25,16 +25,6 @@ button { margin-right: 0.5em; &.search { - @keyframes spin { - to { -gtk-icon-transform: rotate(1turn); } - } - - image.spinning { - animation-name: spin; - animation-duration: 1s; - animation-timing-function: linear; - animation-iteration-count: infinite; - } image { color: $text; } diff --git a/scss/menus/menu.scss b/scss/menus/menu.scss index fe54983..23a616d 100644 --- a/scss/menus/menu.scss +++ b/scss/menus/menu.scss @@ -94,13 +94,13 @@ tooltip label { background: $crust; border: .13em solid $surface0; border-radius: .7rem; - min-width: 400px; + min-width: 275px; color: $text; } .menu-items-container { border-radius: 0.4em; - min-width: 400px; + min-width: 275px; } .menu-section-container { @@ -252,3 +252,14 @@ tooltip label { min-height: 0em; margin-top: 2.8em; } + +@keyframes spin { +to { -gtk-icon-transform: rotate(1turn); } +} + +image.spinning { + animation-name: spin; + animation-duration: 1s; + animation-timing-function: linear; + animation-iteration-count: infinite; +} diff --git a/scss/menus/network.scss b/scss/menus/network.scss index 4508d41..f00b67e 100644 --- a/scss/menus/network.scss +++ b/scss/menus/network.scss @@ -9,6 +9,14 @@ color: $mauve; } + .menu-icon-button.network { + margin: 1em; + + &:hover { + color: $mauve; + } + } + .network-icon { font-size: 1.3em; min-width: 1em;