diff options
Diffstat (limited to '.config/ags/greeter')
| -rw-r--r-- | .config/ags/greeter/auth.ts | 109 | ||||
| -rw-r--r-- | .config/ags/greeter/greeter.scss | 64 | ||||
| -rw-r--r-- | .config/ags/greeter/greeter.ts | 37 | ||||
| -rw-r--r-- | .config/ags/greeter/session.ts | 20 | ||||
| -rw-r--r-- | .config/ags/greeter/statusbar.ts | 46 |
5 files changed, 276 insertions, 0 deletions
diff --git a/.config/ags/greeter/auth.ts b/.config/ags/greeter/auth.ts new file mode 100644 index 0000000..23477eb --- /dev/null +++ b/.config/ags/greeter/auth.ts @@ -0,0 +1,109 @@ +import AccountsService from "gi://AccountsService?version=1.0" +import GLib from "gi://GLib?version=2.0" +import icons from "lib/icons" + +const { iconFile, realName, userName } = AccountsService.UserManager + .get_default().list_users()[0] + +const loggingin = Variable(false) + +const CMD = GLib.getenv("ASZTAL_DM_CMD") + || "Hyprland" + +const ENV = GLib.getenv("ASZTAL_DM_ENV") + || "WLR_NO_HARDWARE_CURSORS=1 _JAVA_AWT_WM_NONREPARENTING=1" + +async function login(pw: string) { + loggingin.value = true + const greetd = await Service.import("greetd") + return greetd.login(userName, pw, CMD, ENV.split(/\s+/)) + .catch(res => { + loggingin.value = false + response.label = res?.description || JSON.stringify(res) + password.text = "" + revealer.reveal_child = true + }) +} + +const avatar = Widget.Box({ + class_name: "avatar", + hpack: "center", + css: `background-image: url('${iconFile}')`, +}) + +const password = Widget.Entry({ + placeholder_text: "Password", + hexpand: true, + visibility: false, + on_accept: ({ text }) => { login(text || "") }, +}) + +const response = Widget.Label({ + class_name: "response", + wrap: true, + max_width_chars: 35, + hpack: "center", + hexpand: true, + xalign: .5, +}) + +const revealer = Widget.Revealer({ + transition: "slide_down", + child: response, +}) + +export default Widget.Box({ + class_name: "auth", + attribute: { password }, + vertical: true, + children: [ + Widget.Overlay({ + child: Widget.Box( + { + css: "min-width: 200px; min-height: 200px;", + vertical: true, + }, + Widget.Box({ + class_name: "wallpaper", + css: `background-image: url('${WALLPAPER}')`, + }), + Widget.Box({ + class_name: "wallpaper-contrast", + vexpand: true, + }), + ), + overlay: Widget.Box( + { + vpack: "end", + vertical: true, + }, + avatar, + Widget.Box({ + hpack: "center", + children: [ + Widget.Icon(icons.ui.avatar), + Widget.Label(realName || userName), + ], + }), + Widget.Box( + { + class_name: "password", + }, + Widget.Spinner({ + visible: loggingin.bind(), + active: true, + }), + Widget.Icon({ + visible: loggingin.bind().as(b => !b), + icon: icons.ui.lock, + }), + password, + ), + ), + }), + Widget.Box( + { class_name: "response-box" }, + revealer, + ), + ], +}) diff --git a/.config/ags/greeter/greeter.scss b/.config/ags/greeter/greeter.scss new file mode 100644 index 0000000..e3a5cd8 --- /dev/null +++ b/.config/ags/greeter/greeter.scss @@ -0,0 +1,64 @@ +@import "../style/mixins/floating-widget.scss"; +@import "../style/mixins/widget.scss"; +@import "../style/mixins/spacing.scss"; +@import "../style/mixins/unset.scss"; +@import "../style/mixins/a11y-button.scss"; +@import "../widget/bar/bar.scss"; + +window#greeter { + background-color: lighten($bg, 6%); + color: $fg; + + .bar { + background-color: transparent; + + .date { + @include unset($rec: true); + @include panel-button($flat: true, $reactive: false); + } + } + + .auth { + @include floating_widget; + border-radius: $radius; + min-width: 400px; + padding: 0; + + .wallpaper { + min-height: 220px; + background-size: cover; + border-top-left-radius: $radius; + border-top-right-radius: $radius; + } + + .wallpaper-contrast { + min-height: 100px; + } + + .avatar { + border-radius: 99px; + min-width: 140px; + min-height: 140px; + background-size: cover; + box-shadow: 3px 3px 6px 0 $shadow-color; + margin-bottom: $spacing; + } + + + .password { + entry { + @include button; + padding: $padding*.7 $padding; + margin-left: $spacing*.5; + } + + margin: 0 $padding*4; + margin-top: $spacing; + } + + .response-box { + color: $error-bg; + margin: $spacing 0; + } + } +} diff --git a/.config/ags/greeter/greeter.ts b/.config/ags/greeter/greeter.ts new file mode 100644 index 0000000..eb1493f --- /dev/null +++ b/.config/ags/greeter/greeter.ts @@ -0,0 +1,37 @@ +import "./session" +import "style/style" +import GLib from "gi://GLib?version=2.0" +import RegularWindow from "widget/RegularWindow" +import statusbar from "./statusbar" +import auth from "./auth" + +const win = RegularWindow({ + name: "greeter", + setup: self => { + self.set_default_size(500, 500) + self.show_all() + auth.attribute.password.grab_focus() + }, + child: Widget.Overlay({ + child: Widget.Box({ expand: true }), + overlays: [ + Widget.Box({ + vpack: "start", + hpack: "fill", + hexpand: true, + child: statusbar, + }), + Widget.Box({ + vpack: "center", + hpack: "center", + child: auth, + }), + ], + }), +}) + +App.config({ + icons: "./assets", + windows: [win], + cursorTheme: GLib.getenv("XCURSOR_THEME")!, +}) diff --git a/.config/ags/greeter/session.ts b/.config/ags/greeter/session.ts new file mode 100644 index 0000000..092a5c2 --- /dev/null +++ b/.config/ags/greeter/session.ts @@ -0,0 +1,20 @@ +import GLib from "gi://GLib?version=2.0" +import AccountsService from "gi://AccountsService?version=1.0" + +const { userName } = AccountsService.UserManager.get_default().list_users()[0] + +declare global { + const WALLPAPER: string +} + +Object.assign(globalThis, { + TMP: `${GLib.get_tmp_dir()}/greeter`, + OPTIONS: "/var/cache/greeter/options.json", + WALLPAPER: "/var/cache/greeter/background", + // TMP: "/tmp/ags", + // OPTIONS: Utils.CACHE_DIR + "/options.json", + // WALLPAPER: Utils.HOME + "/.config/background", + USER: userName, +}) + +Utils.ensureDirectory(TMP) diff --git a/.config/ags/greeter/statusbar.ts b/.config/ags/greeter/statusbar.ts new file mode 100644 index 0000000..8076011 --- /dev/null +++ b/.config/ags/greeter/statusbar.ts @@ -0,0 +1,46 @@ +import { clock } from "lib/variables" +import options from "options" +import icons from "lib/icons" +import BatteryBar from "widget/bar/buttons/BatteryBar" +import PanelButton from "widget/bar/PanelButton" + +const { scheme } = options.theme +const { monochrome } = options.bar.powermenu +const { format } = options.bar.date + +const poweroff = PanelButton({ + class_name: "powermenu", + child: Widget.Icon(icons.powermenu.shutdown), + on_clicked: () => Utils.exec("shutdown now"), + setup: self => self.hook(monochrome, () => { + self.toggleClassName("colored", !monochrome.value) + self.toggleClassName("box") + }), +}) + +const date = PanelButton({ + class_name: "date", + child: Widget.Label({ + label: clock.bind().as(c => c.format(`${format}`)!), + }), +}) + +const darkmode = PanelButton({ + class_name: "darkmode", + child: Widget.Icon({ icon: scheme.bind().as(s => icons.color[s]) }), + on_clicked: () => scheme.value = scheme.value === "dark" ? "light" : "dark", +}) + +export default Widget.CenterBox({ + class_name: "bar", + hexpand: true, + center_widget: date, + end_widget: Widget.Box({ + hpack: "end", + children: [ + darkmode, + BatteryBar(), + poweroff, + ], + }), +}) |
