lets goo
This commit is contained in:
parent
e62a7afa60
commit
6b8b5f62ea
7 changed files with 196 additions and 183 deletions
|
|
@ -1 +1 @@
|
||||||
bun 1.2.8
|
bun latest
|
||||||
|
|
|
||||||
8
components/Svg.tsx
Normal file
8
components/Svg.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
interface SvgProps {
|
||||||
|
color?: string;
|
||||||
|
rotation?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Svg({ color, rotation }: SvgProps) {
|
||||||
|
const svgPath = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" ${rotation && 'transform="rotate(180 12 12)"'} fill="none" stroke="${color || "#cac9c9"}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13.73 4a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/></svg>`;
|
||||||
|
}
|
||||||
107
style.scss
107
style.scss
|
|
@ -1,15 +1,16 @@
|
||||||
$crust: #181926;
|
$primary: #1fb854;
|
||||||
$mantle: #1e2030;
|
$secondary: #1eb88e;
|
||||||
$base: #24273a;
|
$accent: #1fb8ab;
|
||||||
|
$neutral: #19362d;
|
||||||
|
$base100: #1b1717;
|
||||||
|
$base200: #161212;
|
||||||
|
$base300: #110d0d;
|
||||||
|
$basecontent: #cac9c9;
|
||||||
|
|
||||||
$surface0: #363a4f;
|
$info: #00b5ff;
|
||||||
$surface1: #494d64;
|
$success: #00a96e;
|
||||||
$surface2: #5b6078;
|
$warning: #ffbe00;
|
||||||
|
$error: #ff5861;
|
||||||
$rosewater: #f4dbd6;
|
|
||||||
$flamingo: #dd7878;
|
|
||||||
$pink: #ea76cb;
|
|
||||||
$mauve: #8839ef;
|
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
font-family: JetBrainsMono Nerd Font;
|
font-family: JetBrainsMono Nerd Font;
|
||||||
|
|
@ -22,14 +23,16 @@ button {
|
||||||
|
|
||||||
label {
|
label {
|
||||||
transition:
|
transition:
|
||||||
border 0.5s,
|
border 0.35s,
|
||||||
background 0.5s;
|
background 0.35s,
|
||||||
background: $mantle;
|
color 0.35s;
|
||||||
|
background: $base100;
|
||||||
}
|
}
|
||||||
|
|
||||||
label:hover {
|
label:hover {
|
||||||
background: $crust;
|
background: $primary;
|
||||||
border: 3px solid $rosewater;
|
color: $base300;
|
||||||
|
// border: 3px solid $primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,10 +40,10 @@ label {
|
||||||
all: initial;
|
all: initial;
|
||||||
|
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
color: $rosewater;
|
font-size: 14px;
|
||||||
padding: 2px 12px;
|
color: $basecontent;
|
||||||
background: $crust;
|
padding: 0 12px;
|
||||||
border: 3px solid $crust;
|
// background: $base200;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,53 +52,48 @@ popover > contents {
|
||||||
|
|
||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
border: 4px solid $crust;
|
border: 4px solid $base200;
|
||||||
background: rgba($color: $base, $alpha: 0.75);
|
background: rgba($color: $base100, $alpha: 0.98);
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-styles {
|
.no-styles {
|
||||||
all: initial;
|
all: initial;
|
||||||
|
|
||||||
color: $rosewater;
|
color: $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active {
|
.active {
|
||||||
label {
|
label {
|
||||||
background: $crust;
|
background: $secondary;
|
||||||
|
color: $base300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Arch {
|
.Arch {
|
||||||
-gtk-icon-size: 24px;
|
-gtk-icon-size: 22px;
|
||||||
padding: 4px 8px;
|
padding: 0 6px;
|
||||||
border-radius: 8px;
|
|
||||||
border: 3px solid $crust;
|
|
||||||
background: $mantle;
|
|
||||||
transition:
|
|
||||||
border 0.5s,
|
|
||||||
background 0.5s;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $crust;
|
|
||||||
border: 3px solid $rosewater;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.Pywal {
|
.Pywal {
|
||||||
label {
|
label {
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
padding: 6px 16px 6px 10px;
|
padding: 4px 16px 4px 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.SwayNC {
|
.SwayNC {
|
||||||
label {
|
label {
|
||||||
|
font-size: 16px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Tray {
|
.Tray {
|
||||||
margin: 0 4px;
|
margin: 0 4px;
|
||||||
|
|
||||||
|
arrow {
|
||||||
|
all: initial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.Tray > * {
|
.Tray > * {
|
||||||
|
|
@ -107,12 +105,11 @@ popover > contents {
|
||||||
}
|
}
|
||||||
|
|
||||||
.Workspaces {
|
.Workspaces {
|
||||||
background: $mantle;
|
// background: $base300;
|
||||||
border-radius: 8px;
|
// border-radius: 8px;
|
||||||
border: 4px solid $crust;
|
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
margin: 2px;
|
margin: 0 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,14 +129,14 @@ popover > contents {
|
||||||
margin: 4px;
|
margin: 4px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: $crust;
|
background: $base200;
|
||||||
transition:
|
transition:
|
||||||
border 0.5s,
|
border 0.5s,
|
||||||
background 0.5s;
|
background 0.5s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $crust;
|
color: $base300;
|
||||||
background: $rosewater;
|
background: $primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,15 +145,15 @@ popover > contents {
|
||||||
}
|
}
|
||||||
|
|
||||||
.today {
|
.today {
|
||||||
border: 3px solid $rosewater;
|
border: 3px solid $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
.other-month {
|
.other-month {
|
||||||
color: $surface0;
|
color: $accent;
|
||||||
transition: border 0.5s;
|
transition: border 0.5s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border: 3px solid $rosewater;
|
border: 3px solid $secondary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -168,15 +165,19 @@ popover > contents {
|
||||||
|
|
||||||
window.Bar {
|
window.Bar {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
padding: 4px;
|
||||||
|
|
||||||
> centerbox {
|
> centerbox {
|
||||||
background: rgba($color: $base, $alpha: 0.75);
|
border-radius: 8px;
|
||||||
border-bottom: 4px solid $crust;
|
|
||||||
|
background-color: $base300;
|
||||||
|
// background: rgba($color: $base300, $alpha: 0.75);
|
||||||
|
// border-bottom: 4px solid $base200;
|
||||||
|
|
||||||
> box {
|
> box {
|
||||||
margin: 6px;
|
margin: 5px 2px;
|
||||||
& > * {
|
& > * {
|
||||||
margin: 0 4px;
|
margin: 0 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,37 +13,37 @@ import Tray from "./Tray";
|
||||||
import WirePlumber from "./WirePlumber";
|
import WirePlumber from "./WirePlumber";
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<window
|
<window
|
||||||
visible
|
visible
|
||||||
cssClasses={["Bar"]}
|
cssClasses={["Bar"]}
|
||||||
gdkmonitor={gdkmonitor}
|
gdkmonitor={gdkmonitor}
|
||||||
exclusivity={Astal.Exclusivity.EXCLUSIVE}
|
exclusivity={Astal.Exclusivity.EXCLUSIVE}
|
||||||
anchor={TOP | LEFT | RIGHT}
|
anchor={TOP | LEFT | RIGHT}
|
||||||
application={App}
|
application={App}
|
||||||
>
|
>
|
||||||
<centerbox cssName="centerbox">
|
<centerbox cssName="centerbox">
|
||||||
<box halign={Gtk.Align.START}>
|
<box halign={Gtk.Align.START}>
|
||||||
<OS />
|
<OS />
|
||||||
<Workspaces />
|
<Workspaces />
|
||||||
<Tray />
|
<Tray />
|
||||||
<Hyprland.Client />
|
<Hyprland.Client />
|
||||||
</box>
|
</box>
|
||||||
<box halign={Gtk.Align.CENTER}>
|
<box halign={Gtk.Align.CENTER}>
|
||||||
<Mpris />
|
<Mpris />
|
||||||
</box>
|
</box>
|
||||||
<box halign={Gtk.Align.END}>
|
<box halign={Gtk.Align.END}>
|
||||||
<Pywal />
|
<Pywal />
|
||||||
<WirePlumber />
|
<WirePlumber />
|
||||||
<Internet />
|
<Bluetooth />
|
||||||
<Bluetooth />
|
<Internet />
|
||||||
<Memory />
|
<Memory />
|
||||||
<Calendar />
|
<Calendar />
|
||||||
<SwayNC />
|
<SwayNC />
|
||||||
</box>
|
</box>
|
||||||
</centerbox>
|
</centerbox>
|
||||||
</window>
|
</window>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,46 +3,47 @@ import { bind, derive } from "astal";
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
|
|
||||||
const DeviceList = function ({
|
const DeviceList = function ({
|
||||||
devices,
|
devices,
|
||||||
}: {
|
}: {
|
||||||
devices: Binding<AstalBluetooth.Device[]>;
|
devices: Binding<AstalBluetooth.Device[]>;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<box vertical>
|
<box vertical>
|
||||||
{devices.as((devices) => {
|
{devices.as((devices) => {
|
||||||
return devices.map((device) => {
|
return devices.map((device) => {
|
||||||
const name = bind(device, "name");
|
const name = bind(device, "name");
|
||||||
const connected = bind(device, "connected");
|
const connected = bind(device, "connected");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
label={bind(
|
label={bind(
|
||||||
derive(
|
derive(
|
||||||
[name, connected],
|
[name, connected],
|
||||||
(name, connected) => `${connected ? "" : ""} ${name}`,
|
(name, connected) => `${connected ? "" : ""} ${name}`,
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})}
|
})}
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Bluetooth = function () {
|
const Bluetooth = function () {
|
||||||
const bluetooth = AstalBluetooth.get_default();
|
const bluetooth = AstalBluetooth.get_default();
|
||||||
|
|
||||||
const devices = bind(bluetooth, "devices");
|
const devices = bind(bluetooth, "devices");
|
||||||
|
const count = devices.as((devices) => devices.length);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<menubutton>
|
<menubutton>
|
||||||
<label label={""} />
|
<label label={devices.as((devices) => ` ${devices.length}`)} />
|
||||||
<popover>
|
<popover>
|
||||||
<DeviceList devices={devices} />
|
<DeviceList devices={devices} />
|
||||||
</popover>
|
</popover>
|
||||||
</menubutton>
|
</menubutton>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Bluetooth;
|
export default Bluetooth;
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,58 @@
|
||||||
import { bind } from "astal";
|
import { bind } from "astal";
|
||||||
import { Gdk } from "astal/gtk4";
|
import { Gdk, Gtk } from "astal/gtk4";
|
||||||
import Hyprland from "gi://AstalHyprland";
|
import Hyprland from "gi://AstalHyprland";
|
||||||
|
import Rsvg from "gi://Rsvg?version=2.0";
|
||||||
|
|
||||||
const Workspaces = function () {
|
const Workspaces = function () {
|
||||||
const hyprland = Hyprland.get_default();
|
const hyprland = Hyprland.get_default();
|
||||||
|
|
||||||
const workspaces = bind(hyprland, "workspaces").as((workspaces) =>
|
const workspaces = bind(hyprland, "workspaces").as((workspaces) =>
|
||||||
workspaces
|
workspaces
|
||||||
.filter((workspace) => workspace.id > 0)
|
.filter((workspace) => workspace.id > 0)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (a.id > b.id) {
|
if (a.id > b.id) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (a.id < b.id) {
|
} else if (a.id < b.id) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const focusedWorkspace = bind(hyprland, "focused_workspace");
|
const focusedWorkspace = bind(hyprland, "focused_workspace");
|
||||||
const specialWorkspaces = bind(hyprland, "workspaces").as((workspaces) =>
|
const specialWorkspaces = bind(hyprland, "workspaces").as((workspaces) =>
|
||||||
workspaces.filter((workspace) => workspace.id < 0),
|
workspaces.filter((workspace) => workspace.id < 0),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
Gtk.Image.interface_install_property;
|
||||||
<box cssClasses={["Workspaces"]}>
|
|
||||||
{workspaces.as((workspaces) => {
|
const activeTrianglePath =
|
||||||
return workspaces.map((workspace) => (
|
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1fb854" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-icon lucide-triangle"><path d="M13.73 4a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/></svg>';
|
||||||
<button
|
const inactiveTrianglePath =
|
||||||
cursor={Gdk.Cursor.new_from_name("pointer", null)}
|
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" transform="rotate(180 12 12)" fill="none" stroke="#cac9c9" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-icon lucide-triangle"><path d="M13.73 4a2 2 0 0 0-3.46 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/></svg>';
|
||||||
cssClasses={focusedWorkspace.as((focused) => [
|
|
||||||
focused.id === workspace.id ? "active" : "",
|
const activeTrianglePixBuf =
|
||||||
])}
|
Rsvg.Handle.new_from_data(activeTrianglePath).get_pixbuf();
|
||||||
onClicked={() => workspace.focus()}
|
const inactiveTrianglePixBuf =
|
||||||
>
|
Rsvg.Handle.new_from_data(inactiveTrianglePath).get_pixbuf();
|
||||||
{workspace?.name}
|
|
||||||
</button>
|
return (
|
||||||
));
|
<box cssClasses={["Workspaces"]}>
|
||||||
})}
|
{workspaces.as((workspaces) => {
|
||||||
</box>
|
return workspaces.map((workspace) => (
|
||||||
);
|
<button
|
||||||
|
cursor={Gdk.Cursor.new_from_name("pointer", null)}
|
||||||
|
onClicked={() => workspace.focus()}
|
||||||
|
>
|
||||||
|
{focusedWorkspace.as((focused) =>
|
||||||
|
focused.id === workspace.id
|
||||||
|
? Gtk.Image.new_from_pixbuf(activeTrianglePixBuf)
|
||||||
|
: Gtk.Image.new_from_pixbuf(inactiveTrianglePixBuf),
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
));
|
||||||
|
})}
|
||||||
|
</box>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Workspaces;
|
export default Workspaces;
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,30 @@
|
||||||
import { bind } from "astal";
|
import { bind } from "astal";
|
||||||
import { Gdk } from "astal/gtk4";
|
import { Gdk, Gtk } from "astal/gtk4";
|
||||||
import AstalTray from "gi://AstalTray";
|
import AstalTray from "gi://AstalTray";
|
||||||
|
|
||||||
const TrayItemPopover = function ({ item }: { item: AstalTray.TrayItem }) {
|
const TrayItem = function ({ item }: { item: AstalTray.TrayItem }) {
|
||||||
const actionGroup = bind(item, "actionGroup");
|
const popover = Gtk.PopoverMenu.new_from_model(item.menu_model);
|
||||||
|
popover.insert_action_group("dbusmenu", item.action_group);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<popover>
|
<menubutton
|
||||||
<box>{actionGroup.get()}</box>
|
cursor={Gdk.Cursor.new_from_name("pointer", null)}
|
||||||
</popover>
|
icon_name={item.icon_name}
|
||||||
);
|
popover={popover}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Tray = function () {
|
const Tray = function () {
|
||||||
const tray = AstalTray.get_default();
|
const tray = AstalTray.get_default();
|
||||||
|
|
||||||
const trayItems = bind(tray, "items");
|
return (
|
||||||
|
<box cssClasses={["Tray"]}>
|
||||||
return (
|
{bind(tray, "items").as((items) =>
|
||||||
<box cssClasses={["Tray"]}>
|
items.map((item) => TrayItem({ item })),
|
||||||
{trayItems.as((items) =>
|
)}
|
||||||
items.map((item) => {
|
</box>
|
||||||
return (
|
);
|
||||||
<menubutton cursor={Gdk.Cursor.new_from_name("pointer", null)}>
|
|
||||||
<image
|
|
||||||
tooltip_text={bind(item, "tooltip_markup")}
|
|
||||||
file={bind(item, "icon_name").as(
|
|
||||||
(iconName) => iconName || "NONE",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<TrayItemPopover item={item} />
|
|
||||||
</menubutton>
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)}
|
|
||||||
</box>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Tray;
|
export default Tray;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue