Added AGS
This commit is contained in:
+10
@@ -0,0 +1,10 @@
|
||||
import app from "ags/gtk3/app"
|
||||
import style from "./style.css"
|
||||
import Media from "./widget/Media"
|
||||
|
||||
app.start({
|
||||
css: style,
|
||||
main() {
|
||||
app.get_monitors().map(Media)
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
const mpris = await Service.import('mpris');
|
||||
|
||||
const Media = () => Widget.Box({
|
||||
class_name: 'media-container',
|
||||
spacing: 10,
|
||||
children: [
|
||||
Widget.Button({
|
||||
class_name: 'media-btn',
|
||||
on_clicked: () => mpris.players[0]?.previous(),
|
||||
child: Widget.Label('⏮'),
|
||||
}),
|
||||
Widget.Button({
|
||||
class_name: 'media-btn',
|
||||
on_clicked: () => mpris.players[0]?.playPause(),
|
||||
child: Widget.Label().hook(mpris, label => {
|
||||
const player = mpris.players[0];
|
||||
label.label = player?.play_back_status === 'Playing' ? '⏸' : '▶';
|
||||
}),
|
||||
}),
|
||||
Widget.Button({
|
||||
class_name: 'media-btn',
|
||||
on_clicked: () => mpris.players[0]?.next(),
|
||||
child: Widget.Label('⏭'),
|
||||
}),
|
||||
Widget.Label({
|
||||
class_name: 'media-text',
|
||||
}).hook(mpris, label => {
|
||||
const player = mpris.players[0];
|
||||
label.label = player ? `${player.track_title} - ${player.track_artists.join(', ')}` : 'No Media Playing';
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
App.config({
|
||||
style: './style.css',
|
||||
windows: [
|
||||
Widget.Window({
|
||||
name: 'media_widget',
|
||||
anchor: ['bottom', 'left'],
|
||||
margins: [0, 0, 20, 20],
|
||||
layer: 'bottom',
|
||||
child: Media(),
|
||||
})
|
||||
]
|
||||
});
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
declare const SRC: string
|
||||
|
||||
declare module "inline:*" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.scss" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.blp" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
|
||||
declare module "*.css" {
|
||||
const content: string
|
||||
export default content
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"ags": "*",
|
||||
"gnim": "*"
|
||||
},
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"tabWidth": 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
* {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.MediaWindow {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.media-container {
|
||||
background-color: rgba(30, 30, 46, 0.85);
|
||||
border-radius: 8px;
|
||||
border: 2px solid rgba(137, 180, 250, 0.5);
|
||||
padding: 8px 15px;
|
||||
font-family: "JetBrainsMono Nerd Font", sans-serif;
|
||||
}
|
||||
|
||||
.media-btn {
|
||||
color: #cba6f7;
|
||||
font-size: 16px;
|
||||
padding: 0 5px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.media-btn:hover {
|
||||
color: #89b4fa;
|
||||
}
|
||||
|
||||
.media-text {
|
||||
color: #cdd6f4;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"module": "ES2022",
|
||||
"target": "ES2020",
|
||||
"lib": ["ES2023"],
|
||||
"moduleResolution": "Bundler",
|
||||
// "checkJs": true,
|
||||
// "allowJs": true,
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "ags/gtk3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import app from "ags/gtk3/app"
|
||||
import { Astal, Gtk, Gdk } from "ags/gtk3"
|
||||
import { execAsync } from "ags/process"
|
||||
import { createPoll } from "ags/time"
|
||||
|
||||
export default function Media(gdkmonitor: Gdk.Monitor) {
|
||||
const { TOP, LEFT } = Astal.WindowAnchor
|
||||
|
||||
// Poll playerctl for metadata and status
|
||||
const mediaInfo = createPoll("No Media Playing", 1000, 'sh -c "playerctl metadata -f \'{{title}} - {{artist}}\' 2>/dev/null || echo \'No Media Playing\'"')
|
||||
const statusIcon = createPoll("▶", 1000, 'sh -c "s=\\$(playerctl status 2>/dev/null); if [ \\"\\$s\\" = \\"Playing\\" ]; then echo \\"⏸\\"; else echo \\"▶\\"; fi"')
|
||||
|
||||
return (
|
||||
<window
|
||||
class="MediaWindow"
|
||||
gdkmonitor={gdkmonitor}
|
||||
exclusivity={Astal.Exclusivity.NORMAL}
|
||||
layer={Astal.Layer.BOTTOM}
|
||||
anchor={TOP | LEFT}
|
||||
margin={20}
|
||||
application={app}
|
||||
>
|
||||
<box class="media-container" spacing={10}>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl previous").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label="⏮" />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl play-pause").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label={statusIcon} />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl next").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label="⏭" />
|
||||
</button>
|
||||
<label class="media-text" label={mediaInfo} />
|
||||
</box>
|
||||
</window>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user