From e61fadd43c97a8adb01d53f07c0c89bcc348288d Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sun, 27 Jul 2025 12:06:05 +0545 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(dashboard):=20add=20dashboard?= =?UTF-8?q?=20UI=20and=20functionality=20with=20Bluetooth=20and=20Network?= =?UTF-8?q?=20tiles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.css | 202 +------------------------------- modules/dashboard/bluetooth.py | 3 +- modules/dashboard/main.py | 10 +- modules/dashboard/network.py | 7 +- styles/dashboard.css | 193 +++++++++++++++++++++++++++++++ styles/player.css | 204 +-------------------------------- 6 files changed, 209 insertions(+), 410 deletions(-) create mode 100644 styles/dashboard.css diff --git a/main.css b/main.css index ea66cbd..c1bf7a0 100644 --- a/main.css +++ b/main.css @@ -11,6 +11,7 @@ @import url("./styles/calendar.css"); @import url("./styles/notification.css"); @import url("./styles/player.css"); +@import url("./styles/dashboard.css"); * { all: unset; @@ -69,204 +70,3 @@ tooltip > * { box-shadow: 0 0 3px alpha(black, 0.7); } -#dashboard-window { - transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); -} -#dashboard { - background-color: black; - border-radius: 25px; - padding: 10px; -} -#inner { - margin: 3px; -} - -.tile { - margin: 2px; - min-height: 60px; - min-width: 140px; - border-radius: 20px; -} -.tile.mini { - min-height: 46px; - min-width: 46px; - border-radius: 100%; -} -.tile.on { - background-color: var(--primary); -} -.tile.off { - background-color: var(--surface-bright); -} -.tile.on .desc-label, -.tile.on .tile-label, -.tile.on .tile-icon { - color: black; - transition: all; -} -.tile.off .desc-label, -.tile.off .tile-label, -.tile.off .tile-icon { - color: var(--foreground); - transition: all; -} - -.tile-icon { - font-size: 16px; - margin: 10px; -} -.tile-icon.mini { - font-size: 20px; - transition: font-size 0.25s cubic-bezier(0.5, 0.25, 0, 1); -} -.tile-icon.maxi { - font-size: 16px; - transition: font-size 0.25s cubic-bezier(0.5, 0.25, 0, 1); -} - -.tile-button { - all: unset; -} - -.tile-menu { - all: unset; - min-width: 400px; - min-height: 300px; - margin: -999px; -} -.tile-menu.expand { - margin: 0px; - transition: margin 0.15s cubic-bezier(0.5, 0.25, 0, 1); -} -.tile-menu.contract { - margin: -200px; - transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); -} - - -#bluetooth-header, -#network-header { - border: 2px solid var(--surface); - padding: 4px; - border-radius: 12px; -} - -#bluetooth-device, -#wifi-ap-slot { - border: 2px solid var(--surface); - border-radius: 12px; - padding: 4px; -} - -#bluetooth-scan, -#bluetooth-back, -#network-refresh, -#network-back { - background-color: var(--surface); - border-radius: 8px; - padding: 4px; -} - -#bluetooth-back-label, -#network-back-label { - font-size: 20px; -} - -#bluetooth-scan:hover, -#bluetooth-back:hover, -#network-refresh:hover, -#network-back:hover { - background-color: var(--surface-bright); -} - -#bluetooth-scan label, -#bluetooth-toggle label, -#wifi-connect-button label { - font-weight: bold; -} - -#bluetooth-text, -#bluetooth-section { - font-weight: bold; -} - -#bluetooth-section { - background-color: var(--surface); - border-radius: 12px; - padding: 8px; -} - -#bluetooth-connection { - font-size: 20px; -} - -#bluetooth-connect, -#wifi-connect-button { - font-weight: bold; - background-color: var(--surface); - border-radius: 8px; - padding: 8px; -} - -#wifi-connect-button.connected { - background-color: var(--green); -} - -#wifi-connect-button.connected label { - color: var(--shadow); -} - -#bluetooth-connect.connected { - background-color: var(--blue); -} - -#bluetooth-connect.connected label { - color: var(--shadow); -} - -#bluetooth-connect:hover { - background-color: var(--surface-bright); -} - -#bluetooth-paired, -#bluetooth-available { - background-color: var(--surface); - border-radius: 20px; - padding: 4px; -} - -#bt-sep { - /*padding: 1px;*/ - border-radius: 16px; - /*background-color: var(--surface);*/ - /*margin: 0 16px;*/ -} - -#bluetooth-scan-label, -#network-refresh-label { - font-size: 20px; - color: var(--primary); -} - -#bluetooth-scan.scanning { - animation: blink 0.5s ease infinite; -} - -#bluetooth-scan-label.scanning { - animation: blink 0.5s ease infinite; -} - -@keyframes blink { - 0% { - background-color: var(--blue); - color: var(--shadow); - } - 50% { - background-color: var(--shadow); - color: var(--blue); - } - 100% { - background-color: var(--blue); - color: var(--shadow); - } -} \ No newline at end of file diff --git a/modules/dashboard/bluetooth.py b/modules/dashboard/bluetooth.py index ba8a10a..d76e81f 100644 --- a/modules/dashboard/bluetooth.py +++ b/modules/dashboard/bluetooth.py @@ -39,10 +39,9 @@ class BluetoothDeviceSlot(CenterBox): children=[ Image(icon_name=device.icon_name + "-symbolic", size=16), Label( - label=device.name, + label=device.name[:8] + "..." if len(device.name) > 8 else device.name, h_expand=True, h_align="start", - ellipsization="end", ), self.connection_label, ], diff --git a/modules/dashboard/main.py b/modules/dashboard/main.py index aa77434..c93e060 100644 --- a/modules/dashboard/main.py +++ b/modules/dashboard/main.py @@ -13,7 +13,7 @@ from utils.wayland import WaylandWindow as Window class Dashboard(Box): def __init__(self, **kwargs): super().__init__( - name="dashboard", + name="dashboard-box", visible=True, orientation="v", spacing=8, @@ -31,10 +31,7 @@ class Dashboard(Box): self.wifi.dashboard_instance = self self.bluetooth.dashboard_instance = self - # Create real notifications component self.dashboard_notifications = DashboardNotifications() - - # Track currently active tile self.active_tile = None self.tiles = Box( @@ -117,9 +114,6 @@ class Dashboard(Box): self.content_stack.set_visible_child(self.default_content) print("Showing default content") - # Don't change tile visual states - keep all tiles unchanged - print("Tile handling complete") - def reset_to_default(self): """Reset dashboard to default state (notifications visible, no active tile)""" print("Resetting dashboard to default state") @@ -140,7 +134,7 @@ class DashboardWindow(Window): self.dashboard = Dashboard() super().__init__( - name="dashboard-window", + name="dashboard", layer="top", anchor="bottom", exclusivity="none", diff --git a/modules/dashboard/network.py b/modules/dashboard/network.py index 46b4c9d..248f719 100644 --- a/modules/dashboard/network.py +++ b/modules/dashboard/network.py @@ -163,7 +163,12 @@ class Network(Tile): if wifi and wifi.active_access_point: connected = True - con_label = wifi.active_access_point.ssid + # Hacky truncation: limit to 8 characters and add ellipsis + ssid = wifi.active_access_point.ssid + if len(ssid) > 8: + con_label = ssid[:8] + "..." + else: + con_label = ssid elif wifi and not wifi.wireless_enabled: con_label = "Off" diff --git a/styles/dashboard.css b/styles/dashboard.css new file mode 100644 index 0000000..745ccd9 --- /dev/null +++ b/styles/dashboard.css @@ -0,0 +1,193 @@ +#dashboard-box { + transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); + background-color: var(--shadow); + border-radius: 25px; + padding: 6px; + margin-bottom: 65px; +} + +#inner { + margin: 3px; +} + +.tile { + margin: 0 6px; + min-height: 60px; + min-width: 140px; + border-radius: 20px; +} +.tile.mini { + min-height: 46px; + min-width: 46px; + border-radius: 100%; +} +.tile.on { + background-color: var(--primary); +} +.tile.off { + background-color: var(--surface-bright); +} +.tile.on .desc-label, +.tile.on .tile-label, +.tile.on .tile-icon { + color: var(--shadow); + transition: all; +} +.tile.off .desc-label, +.tile.off .tile-label, +.tile.off .tile-icon { + color: var(--foreground); + transition: all; +} + +.tile-icon { + font-size: 18px; + margin: 10px; +} +.tile-icon.mini { + font-size: 20px; + transition: font-size 0.25s cubic-bezier(0.5, 0.25, 0, 1); +} +.tile-icon.maxi { + font-size: 16px; + transition: font-size 0.25s cubic-bezier(0.5, 0.25, 0, 1); +} + +.tile-menu { + margin: -999px; +} +.tile-menu.expand { + margin: 0px; + transition: margin 0.15s cubic-bezier(0.5, 0.25, 0, 1); +} +.tile-menu.contract { + margin: -200px; + transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); +} + +#bluetooth-header, +#network-header { + border: 2px solid var(--surface); + padding: 4px; + border-radius: 12px; +} + +#bluetooth-device, +#wifi-ap-slot { + border: 2px solid var(--surface); + border-radius: 12px; + padding: 4px; +} + +#bluetooth-scan, +#bluetooth-back, +#network-refresh, +#network-back { + background-color: var(--surface); + border-radius: 8px; + padding: 4px; +} + +#bluetooth-back-label, +#network-back-label { + font-size: 20px; +} + +#bluetooth-scan:hover, +#bluetooth-back:hover, +#network-refresh:hover, +#network-back:hover { + background-color: var(--surface-bright); +} + +#bluetooth-scan label, +#bluetooth-toggle label, +#wifi-connect-button label { + font-weight: bold; +} + +#bluetooth-text, +#bluetooth-section { + font-weight: bold; +} + +#bluetooth-section { + background-color: var(--surface); + border-radius: 12px; + padding: 8px; +} + +#bluetooth-connection { + font-size: 20px; +} + +#bluetooth-connect, +#wifi-connect-button { + font-weight: bold; + background-color: var(--surface); + border-radius: 8px; + padding: 8px; +} + +#wifi-connect-button.connected { + background-color: var(--green); +} + +#wifi-connect-button.connected label { + color: var(--shadow); +} + +#bluetooth-connect.connected { + background-color: var(--blue); +} + +#bluetooth-connect.connected label { + color: var(--shadow); +} + +#bluetooth-connect:hover { + background-color: var(--surface-bright); +} + +#bluetooth-paired, +#bluetooth-available { + background-color: var(--surface); + border-radius: 20px; + padding: 4px; +} + +#bt-sep { + /*padding: 1px;*/ + border-radius: 16px; + /*background-color: var(--surface);*/ + /*margin: 0 16px;*/ +} + +#bluetooth-scan-label, +#network-refresh-label { + font-size: 20px; + color: var(--primary); +} + +#bluetooth-scan.scanning { + animation: blink 0.5s ease infinite; +} + +#bluetooth-scan-label.scanning { + animation: blink 0.5s ease infinite; +} + +@keyframes blink { + 0% { + background-color: var(--blue); + color: var(--shadow); + } + 50% { + background-color: var(--shadow); + color: var(--blue); + } + 100% { + background-color: var(--blue); + color: var(--shadow); + } +} diff --git a/styles/player.css b/styles/player.css index 285f7ca..3e22dd1 100644 --- a/styles/player.css +++ b/styles/player.css @@ -1,160 +1,7 @@ -.player { - /* background-color: aqua; */ - min-height: 100px; - min-width: 400px; - box-shadow: - inset 0 100px 100px black, - inset 10px 0px 10px rgba(0, 0, 0, 0.5), - inset -10px 0px 10px rgba(0, 0, 0, 0.5); - border-bottom-right-radius: 20px; - border-bottom-left-radius: 20px; - padding: 20px; - background-position: center; - background-size: cover; - margin: 4px; -} - -.player.vertical { - box-shadow: - inset 100px 0px 150px black, - inset 0px 10px 10px rgba(0, 0, 0, 0.5), - inset 0px -10px 10px rgba(0, 0, 0, 0.5); - border-top-right-radius: 20px; - border-bottom-right-radius: 20px; - min-width: 400px; - min-height: 150px; - margin: 10px; -} - -.player-icon { - font-size: 24px; -} -#artist { - color: var(--primary); -} - -#song { - color: whitesmoke; - font-size: 16px; - margin-top: 5px; - font-weight: 900; -} - -#wiggle-bar { - color: var(--primary); -} - -#source { - /* background-color: antiquewhite; */ - margin-top: -10px; -} - -#controls { - margin-bottom: -10px; -} - -#play-next, -#play-previous { - font-size: 24px; -} - -#progress { - /* min-height: 1px; */ - background-color: antiquewhite; -} - -#pause-button { - background-color: var(--surface); - border-radius: 20px; - padding: 8px; -} - -#pause-button.pause-track { - border-radius: 100%; -} - -#pause-label, -#play-label { - color: var(--primary); - font-size: 20px; - padding: 2px; - border-radius: 999px; - min-width: 25px; -} - -#shuffle-button, -#next-button, -#prev-button { - border: none; - padding: 0px; - padding-left: 11px; - padding-right: 11px; -} - -#shuffle-button:hover, -#next-button:hover, -#prev-button:hover { - background-color: var(--surface-bright); -} - -#shuffle { - font-size: 17px; -} - -.player-button { - border-radius: 5px; - /* background-color: var(--secondary); */ - background-color: white; - opacity: 0.5; - min-width: 10px; - min-height: 10px; - padding: 0px; - margin: 0px; - border: none; - margin-left: 5px; -} - -.player-button.active { - opacity: 1; -} - -#player-switch-container.vertical-player { - margin-top: -23px; - padding-bottom: 13px; -} - -#player-switch-container { - margin-top: -18px; - padding-bottom: 13px; -} - -#controls.vertical { - padding-bottom: 10px; - margin-bottom: 0px; -} - -#disable-shuffle { - font-size: 27px; -} - -#progress-slider { - margin-left: -3px; - margin-right: -2px; - margin-top: 8px; - margin-bottom: 8px; - border-radius: 2px; -} - -#progress-other-end { - min-width: 50px; -} - .player-mini { min-height: 60px; - min-width: 220px; + min-width: 200px; padding-right: 20px; - /* box-shadow: inset 0 0 100px rgb(148, 148, 148), - inset 60px 0px 10px rgba(255, 255, 255, 1); */ box-shadow: inset 0 0 100px rgba(148, 148, 148, 0.3), @@ -177,34 +24,9 @@ .album-image { min-width: 65px; - min-height: 60px; background-position: center; background-size: cover; - /* border-top-left-radius: 15px; - border-bottom-left-radius: 15px; */ border-radius: 15px; - /* margin: 2px; */ -} - -.hide-player { - margin: -350px; - transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); - /* animation: hidePlayer 0.5s ease; */ -} - -@keyframes hidePlayer { - 0% { - margin: 0px; - } - 100% { - margin: -999px; - } -} - -.reveal-player { - margin: 0px; - transition: margin 0.25s cubic-bezier(0.5, 0.25, 0, 1); - /* animation: revealPlayer 0.5s ease; */ } #artist { @@ -223,7 +45,7 @@ } #source { - /* background-color: antiquewhite; */ + background-color: antiquewhite; margin-top: -10px; } #source.mini { @@ -233,11 +55,7 @@ #controls { margin-bottom: -10px; } -#play-next, -#play-previous { - text-shadow: none; - font-size: 30px; -} + #play-next.mini, #play-previous.mini { text-shadow: none; @@ -249,13 +67,7 @@ text-shadow: none; } -#progress { - /* min-height: 1px; */ - background-color: antiquewhite; -} - #pause-button { - /* background-color: var(--surface); */ background-color: whitesmoke; border-radius: 16px; padding: 10px; @@ -312,7 +124,7 @@ .player-button { border-radius: 5px; /* background-color: var(--secondary); */ - background-color: white; + /* background-color: white; */ opacity: 0.5; min-width: 10px; min-height: 10px; @@ -324,7 +136,7 @@ .player-button.mini { border-radius: 5px; - background-color: var(--surface); + background-color: var(--shadow); /* background-color: white; */ opacity: 0.5; min-width: 10px; @@ -353,7 +165,7 @@ #player-switch-container.mini { margin-top: 0px; - margin-left: -20px; + margin-left: -18px; padding-right: 10px; } @@ -362,10 +174,6 @@ margin-bottom: 0px; } -.player-icon { - font-size: 20px; -} - .player-icon.mini { font-size: 20px; color: black;