Notifications
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
␍<g id="SVGRepo_bgCarrier" stroke-width="0"/>
|
||||
␍<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
␍<g id="SVGRepo_iconCarrier"> <path d="M12.0009 5C13.4331 5 14.8066 5.50571 15.8193 6.40589C16.832 7.30606 17.4009 8.52696 17.4009 9.8C17.4009 11.7691 17.846 13.2436 18.4232 14.3279C19.1606 15.7133 19.5293 16.406 19.5088 16.5642C19.4849 16.7489 19.4544 16.7997 19.3026 16.9075C19.1725 17 18.5254 17 17.2311 17H6.77066C5.47638 17 4.82925 17 4.69916 16.9075C4.54741 16.7997 4.51692 16.7489 4.493 16.5642C4.47249 16.406 4.8412 15.7133 5.57863 14.3279C6.1558 13.2436 6.60089 11.7691 6.60089 9.8C6.60089 8.52696 7.16982 7.30606 8.18251 6.40589C9.19521 5.50571 10.5687 5 12.0009 5ZM12.0009 5V3M9.35489 20C10.0611 20.6233 10.9888 21.0016 12.0049 21.0016C13.0209 21.0016 13.9486 20.6233 14.6549 20" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="--darkreader-inline-stroke: var(--darkreader-text-ffffff, #e8e6e3);" data-darkreader-inline-stroke=""/> </g>
|
||||
␍</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
+34
@@ -10,6 +10,9 @@ window {
|
||||
> centerbox {
|
||||
background: $background-1;
|
||||
}
|
||||
icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
@@ -303,3 +306,34 @@ button {
|
||||
border: 2px solid $highlight-3;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@keyframes notifIn {
|
||||
0% {
|
||||
margin-right: -352px;
|
||||
}
|
||||
}
|
||||
@keyframes glowIn {
|
||||
from {
|
||||
background: white;
|
||||
box-shadow: 0 0 10px 4px white;
|
||||
}
|
||||
}
|
||||
|
||||
.notifBox {
|
||||
animation: notifIn cubic-bezier(0.34, 1.4, 0.64, 1) 0.4s, glowIn ease-in 0.3s;
|
||||
transition: margin cubic-bezier(0.34, 1.4, 0.64, 1) 0.4s;
|
||||
background: $background-3;
|
||||
border-radius: 10px;
|
||||
padding: 8px;
|
||||
box-shadow: 0 0 10px 4px black;
|
||||
min-width: 300px;
|
||||
margin: 12px 12px 40px 40px;
|
||||
}
|
||||
|
||||
.notifIcon {
|
||||
min-width: 64px;
|
||||
min-height: 64px;
|
||||
margin: 8px;
|
||||
background-size: contain;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import brightness from "./brightness"
|
||||
import client from "./client"
|
||||
import player from "./player"
|
||||
import bluetooth from "./bluetooth"
|
||||
import notifs from "./notif"
|
||||
|
||||
const time = Variable("").poll(1000, "date +'%a %b %d · %H:%M'")
|
||||
|
||||
@@ -40,6 +41,7 @@ export default function Bar(monitor: Hyprland.Monitor) {
|
||||
label={time()}
|
||||
/>
|
||||
</box></button>
|
||||
{notifs()}
|
||||
</box>
|
||||
</centerbox>
|
||||
</window>
|
||||
|
||||
@@ -21,7 +21,7 @@ function bluetoothItem(device: Bluetooth.Device) {
|
||||
valign: Gtk.Align.CENTER,
|
||||
})}>
|
||||
<box>
|
||||
<icon icon={device.icon} css="font-size: 32px;" />
|
||||
<icon icon={device.icon ?? "bluetooth"} css="font-size: 32px;" />
|
||||
<label valign={Gtk.Align.CENTER}>{device.alias ?? device.name}</label>
|
||||
</box>
|
||||
</overlay>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
import { bind } from "astal"
|
||||
import { Astal, Gtk, Widget } from "astal/gtk3"
|
||||
import Notif from "gi://AstalNotifd"
|
||||
import Pango from "gi://Pango?version=1.0"
|
||||
const notifs = Notif.get_default()
|
||||
|
||||
const { TOP, RIGHT } = Astal.WindowAnchor
|
||||
const notifPlaceholder = "/home/protoshark/.config/ags/assets/notif.svg"
|
||||
let notifWindow: Widget.Window
|
||||
|
||||
function NewNotif(notif: Notif.Notification) {
|
||||
return <box
|
||||
className="notifBox"
|
||||
halign={Gtk.Align.END}
|
||||
valign={Gtk.Align.START} >
|
||||
<box
|
||||
spacing={8}>
|
||||
<box
|
||||
halign={Gtk.Align.CENTER}
|
||||
valign={Gtk.Align.CENTER}
|
||||
className="notifIcon"
|
||||
css={`background-image: url("${notif.image ?? notifPlaceholder}")`}
|
||||
/>
|
||||
<box vertical={true} valign={Gtk.Align.CENTER} spacing={6}>
|
||||
<label
|
||||
halign={Gtk.Align.START}
|
||||
css="font-size: 16px;"
|
||||
wrap={true}
|
||||
maxWidthChars={20}
|
||||
wrapMode={Pango.WrapMode.WORD_CHAR}>
|
||||
{notif.summary.substring(0, 80)}
|
||||
</label>
|
||||
<label
|
||||
halign={Gtk.Align.START}
|
||||
css="font-size: 14px;"
|
||||
wrap={true}
|
||||
maxWidthChars={22}
|
||||
wrapMode={Pango.WrapMode.WORD_CHAR}>
|
||||
{notif.body.substring(0, 88)}
|
||||
</label>
|
||||
</box>
|
||||
</box></box>
|
||||
}
|
||||
|
||||
function notify(notif: Notif.Notification) {
|
||||
let thisNotif = NewNotif(notif)
|
||||
if (notifWindow) {
|
||||
let os = notifWindow.get_child().overlays
|
||||
let top = 12
|
||||
for (let i = os.length-1; i > 0; i--) {
|
||||
top += thisNotif.get_preferred_height()[0] - 40
|
||||
if (os[i].get_preferred_width()[0] >= 352) {
|
||||
os[i].css = `margin-top: ${top}px;`
|
||||
}
|
||||
}
|
||||
notifWindow.get_child().add_overlay(thisNotif)
|
||||
notifWindow.get_child().get_child().heightRequest = os[1].get_preferred_height()[0] + thisNotif.get_preferred_height()[0]
|
||||
} else {
|
||||
notifWindow = <window
|
||||
anchor={ TOP | RIGHT }
|
||||
marginTop={36}
|
||||
css="background: transparent;"
|
||||
namespace="notification">
|
||||
<overlay overlay={thisNotif}>
|
||||
<box
|
||||
halign={Gtk.Align.END}
|
||||
valign={Gtk.Align.START}
|
||||
widthRequest={thisNotif.get_preferred_width()[0]}
|
||||
heightRequest={1200}
|
||||
/>
|
||||
</overlay>
|
||||
</window>
|
||||
}
|
||||
setTimeout(() => {
|
||||
let os = notifWindow.get_child().overlays
|
||||
thisNotif.css = `margin-right: -352px; margin-top: ${thisNotif.get_preferred_height()[0]-thisNotif.get_child().get_preferred_height()[0]-52}px; transition: cubic-bezier(0.64, 0, 0.78, 0) 0.3s;`
|
||||
setTimeout(() => {
|
||||
let os = notifWindow.get_child().overlays
|
||||
notifWindow.get_child().remove(thisNotif)
|
||||
if (os.length < 3) {
|
||||
notifWindow.destroy()
|
||||
notifWindow = null
|
||||
}
|
||||
}, 400)
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
function notifCount() {
|
||||
return <label css="padding-top: 2px;">
|
||||
{bind(notifs, "notifications").as(ns => ns.length)}
|
||||
</label>
|
||||
}
|
||||
|
||||
export default function notifWidget() {
|
||||
return <button
|
||||
onClicked={() => {}}
|
||||
setup={(self) => self.hook(notifs, "notified", (_, id) => {
|
||||
notify(notifs.get_notification(id))
|
||||
})}>
|
||||
<box>
|
||||
<icon icon="notif" css="color: white;" />
|
||||
{notifCount()}
|
||||
</box>
|
||||
</button>
|
||||
}
|
||||
Reference in New Issue
Block a user