diff --git a/.config/ags/modules/sideright/centermodules/wifinetworks.js b/.config/ags/modules/sideright/centermodules/wifinetworks.js index b39a28c1..71cb1cd5 100644 --- a/.config/ags/modules/sideright/centermodules/wifinetworks.js +++ b/.config/ags/modules/sideright/centermodules/wifinetworks.js @@ -17,6 +17,8 @@ const MATERIAL_SYMBOL_SIGNAL_STRENGTH = { } let connectAttempt = ''; +let networkAuth = null; +let networkAuthSSID = null; const WifiNetwork = (accessPoint) => { const networkStrength = MaterialIcon(MATERIAL_SYMBOL_SIGNAL_STRENGTH[accessPoint.iconName], 'hugerass') @@ -35,15 +37,34 @@ const WifiNetwork = (accessPoint) => { ] }); return Button({ - onClicked: accessPoint.active ? () => { } : () => execAsync(`nmcli device wifi connect ${accessPoint.bssid}`) - // .catch(e => { - // Utils.notify({ - // summary: "Network", - // body: e, - // actions: { "Open network manager": () => execAsync("nm-connection-editor").catch(print) } - // }); - // }) - .catch(print), + onClicked: accessPoint.active ? () => {} : () => { + connectAttempt = accessPoint.ssid; + networkAuthSSID.label = `Connecting to: ${connectAttempt}`; + + // Cek apakah SSID sudah tersimpan + execAsync(['nmcli', '-g', 'NAME', 'connection', 'show']) + .then((savedConnections) => { + const savedSSIDs = savedConnections.split('\n'); + + if (!savedSSIDs.includes(connectAttempt)) { + // Jika SSID belum tersimpan, tampilkan input password + if (networkAuth) { + networkAuth.revealChild = true; + } + } else { + // Jika SSID sudah tersimpan, sembunyikan input password + if (networkAuth) { + networkAuth.revealChild = false; + } + + // Langsung konek tanpa input password + execAsync(['nmcli', 'device', 'wifi', 'connect', connectAttempt]) + .catch(print); + } + }) + .catch(print); + + }, child: Box({ className: 'sidebar-wifinetworks-network spacing-h-10', children: [ @@ -124,28 +145,108 @@ const CurrentNetwork = () => { self.label = Network.wifi.state; }), })] - }) - const networkAuth = Revealer({ + }); + networkAuthSSID = Label({ + className: 'margin-left-5', + hpack: 'start', + hexpand: true, + label: '', + }); + const cancelAuthButton = Button({ + className: 'txt sidebar-centermodules-rightbar-button', + label: 'Cancel', + hpack: 'end', + onClicked: () => { + networkAuth.revealChild = false; + networkAuthSSID.label = ''; + networkName.children[1].label = Network.wifi?.ssid; + } + }); + const authHeader = Box({ + vertical: false, + hpack: 'fill', + spacing: 10, + children: [ + networkAuthSSID, + cancelAuthButton + ] + }); + const forgetButton = Button({ + label: 'Forget Network', + hexpand: true, + className: 'txt sidebar-centermodules-rightbar-button', + onClicked: () => { + execAsync(['nmcli', '-t', '-f', 'ACTIVE,NAME', 'connection', 'show']) + .then(output => { + const activeSSID = output + .split('\n') + .find(line => line.startsWith('yes:')) + ?.split(':')[1]; + + if (activeSSID) { + execAsync(['nmcli', 'connection', 'delete', activeSSID]) + .then(() => notify(`Forgot network: ${activeSSID}`)) + .catch(err => notify(`Failed to forget network: ${err}`)); + } else { + notify('No active network to forget'); + } + }) + .catch(err => notify(`Error: ${err}`)); + } + }); + const settingsButton = Button({ + label: 'Network Properties', + className: 'txt sidebar-centermodules-rightbar-button', + hexpand: true, + onClicked: () => { + Utils.execAsync('nmcli -t -f uuid connection show --active').then(uuid => { + if (uuid.trim()) { + Utils.execAsync(`nm-connection-editor --edit ${uuid.trim()}`); + } + }).catch(error => { + Utils.notify('Failed to get connection UUID'); + }); + } + }); + const networkProp = Box({ + vertical: false, + hpack: 'fill', + homogeneous: true, + spacing: 10, + children: [ + settingsButton, + forgetButton, + ] + }); + networkAuth = Revealer({ transition: 'slide_down', transitionDuration: userOptions.animations.durationLarge, child: Box({ className: 'margin-top-10 spacing-v-5', vertical: true, children: [ - Label({ - className: 'margin-left-5', - hpack: 'start', - label: getString("Authentication"), - }), + authHeader, Entry({ className: 'sidebar-wifinetworks-auth-entry', visibility: false, onAccept: (self) => { authLock = false; - networkAuth.revealChild = false; + // Hapus koneksi SSID sebelum mencoba menyambung ulang + execAsync(['nmcli', 'connection', 'delete', connectAttempt]) + .catch(() => {}); // Abaikan error jika SSID tidak ditemukan + execAsync(['nmcli', 'device', 'wifi', 'connect', connectAttempt, 'password', self.text]) - .catch(print); - } + .then(() => { + connectAttempt = ''; // Reset SSID setelah koneksi berhasil + networkAuth.revealChild = false; // Sembunyikan input jika berhasil + }) + .catch(() => { + // Jika koneksi gagal, tampilkan kembali input password + networkAuth.revealChild = true; + networkAuthSSID.label = `Authentication failed. Retry for: ${connectAttempt}`; + self.text = ''; // Kosongkan input untuk coba lagi + }); + } }) ] }), @@ -192,6 +293,7 @@ const CurrentNetwork = () => { networkAuth, ] }), + networkProp, bottomSeparator, ] }); diff --git a/.config/ags/scss/_sidebars.scss b/.config/ags/scss/_sidebars.scss index d9206f9d..2c79379f 100644 --- a/.config/ags/scss/_sidebars.scss +++ b/.config/ags/scss/_sidebars.scss @@ -1039,3 +1039,17 @@ $waifu_image_overlay_transparency: 0.7; .sidebar-centermodules-scrollgradient-bottom { background: linear-gradient(to top, $layer1 0%, transparentize($layer1, 1) 1.023rem); } + +.sidebar-centermodules-rightbar-button { + @include full-rounding; + @include element_decel; + min-width: 6.818rem; + min-height: 2.25rem; + background-color: $layer2Hover; + color: $onLayer2; +} + +.sidebar-centermodules-rightbar-button:hover, +.sidebar-centermodules-rightbar-button:focus { + background-color: $layer2Active; +} \ No newline at end of file diff --git a/.config/hypr/hyprland/rules.conf b/.config/hypr/hyprland/rules.conf index 3387ec4a..5693b4e3 100644 --- a/.config/hypr/hyprland/rules.conf +++ b/.config/hypr/hyprland/rules.conf @@ -10,6 +10,7 @@ windowrulev2 = noblur, class:.* # Specific floating windows. windowrulev2 = float, class:^(blueberry\.py)$ windowrulev2 = float, class:^(steam)$ +windowrulev2 = float, class:^(nm-connection-editor)$ windowrulev2 = float, class:^(guifetch)$ # FlafyDev/guifetch # Tiling rule for a specific app. @@ -40,6 +41,11 @@ windowrulev2 = move 73% 72%, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$ windowrulev2 = size 25%, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$ windowrulev2 = float, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$ windowrulev2 = pin, title:^([Pp]icture[-\s]?[Ii]n[-\s]?[Pp]icture)(.*)$ +windowrulev2 = size 45%, class:^(pavucontrol)$ +windowrulev2 = center, class:^(pavucontrol)$ +windowrulev2 = size 45%, class:^(nm-connection-editor)$ +windowrulev2 = center, class:^(nm-connection-editor)$ + # --- Tearing --- windowrulev2 = immediate, title:.*\.exe