This commit is contained in:
2024-07-08 22:46:35 +02:00
parent 02f44c49d2
commit 27254d817a
56249 changed files with 808097 additions and 1 deletions

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Krypion17
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,20 @@
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
import { ProgressBarManager as ProgressBarManager, ProgressBar as ProgressBar } from "./progressBar.js";
import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
export default class mediaProgress extends Extension {
constructor(metadata) {
super(metadata);
}
enable() {
this.media_section = Main.panel.statusArea.dateMenu._messageList._mediaSection;
this.progressBarManager = new ProgressBarManager(this.media_section);
}
disable() {
this.progressBarManager?.destroy();
this.progressBarManager = null;
this.media_section = null;
}
}

View File

@ -0,0 +1,11 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "Progress Bar for the GNOME Media Notification",
"name": "Media Progress",
"shell-version": [
"46"
],
"url": "https://github.com/Krypion17/media-progress",
"uuid": "media-progress@krypion17",
"version": 13
}

View File

@ -0,0 +1,278 @@
import Gio from "gi://Gio";
import GLib from "gi://GLib";
import GObject from "gi://GObject";
import St from 'gi://St';
import {Slider} from 'resource:///org/gnome/shell/ui/slider.js';
import { loadInterfaceXML } from 'resource:///org/gnome/shell/misc/fileUtils.js';
let timeout;
export class ProgressBarManager extends Slider {
_init(mediaSection) {
super._init(0);
const DBusIface = loadInterfaceXML('org.freedesktop.DBus');
const DBusProxy = Gio.DBusProxy.makeProxyWrapper(DBusIface);
this._dbusProxy = new DBusProxy(Gio.DBus.session,
'org.freedesktop.DBus',
'/org/freedesktop/DBus',
this._onProxyReady.bind(this));
this._mediaSection = mediaSection;
this.signals = [];
this.bars = {};
}
_addProgress(name, owners, newOwner, oldOwner) {
for (let i of this._mediaSection._messages) {
if (i._player._busName === name) {
if (owners && !newOwner && oldOwner)
return;
try {
if (i.get_child().get_last_child().get_child_at_index(1) instanceof ProgressBar)
return;
} catch {
return;
}
let length;
const MprisPlayerIface = loadInterfaceXML('org.mpris.MediaPlayer2.Player');
const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
let playerProxy = new MprisPlayerProxy(Gio.DBus.session, name, '/org/mpris/MediaPlayer2');
try {
length = playerProxy.get_connection().call_sync(
name,
"/org/mpris/MediaPlayer2",
"org.freedesktop.DBus.Properties",
"Get",
new GLib.Variant("(ss)", ["org.mpris.MediaPlayer2.Player", "Metadata"]),
null,
Gio.DBusCallFlags.NONE,
50,
null
).recursiveUnpack()[0]['mpris:length'] / 60000000;
if (!length)
return;
} catch (e) {
return;
}
let timestamp1 = new St.Label({
style_class: "progressbar-timestamp"
});
timestamp1.set_text("0:00");
let timestamp2 = new St.Label({
style_class: "progressbar-timestamp"
});
let progressBar = new ProgressBar(0, this, name, [timestamp1, timestamp2]);
let box = new St.BoxLayout();
playerProxy = null;
timestamp2.set_text(`${Math.floor(length)}:${Math.floor((length - Math.floor(length))*60).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}`);
box.add_child(timestamp1);
box.add_child(progressBar);
box.add_child(timestamp2);
i.get_child().add_child(box);
this.bars[name] = progressBar;
this.signals.push(i._player.connect('closed', (() => {
if (timeout)
clearInterval(timeout);
if (!this.bars[name])
return;
this.bars[name].destroy();
delete this.bars[name];
})));
}
}
}
async _onProxyReady() {
const [names] = await this._dbusProxy.ListNamesAsync().catch();
names.forEach(name => {
if (!name.startsWith('org.mpris.MediaPlayer2.'))
return;
this._addProgress(name, false);
});
this.signals.push(this._dbusProxy.connectSignal("NameOwnerChanged", (pproxy, sender, [name, oldOwner, newOwner]) => {
if (!name.startsWith('org.mpris.MediaPlayer2.'))
return;
this.signals.push(this._mediaSection._players.get(name).connect('changed', () => {
this._addProgress(name, true, newOwner, oldOwner);
}));
this.timeout = setTimeout(() => {
this._addProgress(name, true, newOwner, oldOwner);
}, 500);
}));
}
destroy() {
clearTimeout(this.timeout);
for (let i in this.bars) {
if (!this.bars[i])
continue;
this.bars[i].destroy();
delete this.bars[i];
}
this.signals.map((i) => {
this.disconnect(i);
});
for (let i of this._mediaSection._messages) {
try {
if (i.get_child().get_last_child().get_child_at_index(1) instanceof ProgressBar)
i.get_child().get_last_child().get_child_at_index(1).destroy();
} catch {}
}
super.destroy();
}
}
export class ProgressBar extends Slider {
_init(value, manager, busName, timestamps) {
super._init(value);
this._busName = busName;
this.manager = manager;
this.timestamps = timestamps;
this._updateSettings();
this.updateSignal = St.Settings.get().connect('notify', () => this._updateSettings());
this.track_hover = true;
this.signals = [];
const MprisPlayerIface = loadInterfaceXML('org.mpris.MediaPlayer2.Player');
const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
this._playerProxy = MprisPlayerProxy(Gio.DBus.session, this._busName, '/org/mpris/MediaPlayer2', this._onPlayerProxyReady.bind(this));
const position = this.getProperty("Position");
this.value = position / this._length;
timeout = setInterval(() => {
if (this._dragging || this.getProperty("PlaybackStatus") !== "Playing")
return;
if (!this) {
clearInterval(timeout);
return;
}
let position = this.getProperty("Position");
this.value = position / this._length;
position = position / 60000000;
this.timestamps[0].set_text(`${Math.floor(position)}:${Math.floor((position - Math.floor(position))*60).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}`);
}, 1000);
this.signals.push(this.connect("drag-end", () => {
if (this._dragging)
return;
this.setPosition(this.value * this._length);
}));
}
_updateInfo() {
this._trackId = this.getProperty("Metadata")['mpris:trackid'];
if (!this._trackId)
this.reactive = false;
if (this._trackId !== 0 && this.getProperty("CanSeek"))
this.reactive = true;
if (!this._length)
this._length = this.getProperty("Metadata")['mpris:length'];
if (!this._length) {
this.visible = false;
this.timestamps[0].visible = false;
this.timestamps[1].visible = false;
}
else {
this.visible = true;
this.timestamps[0].visible = true;
this.timestamps[1].visible = true;
}
this.timestamps[1].set_text(`${Math.floor(this._length / 60000000)}:${Math.floor((this._length / 60000000 - Math.floor(this._length / 60000000))*60).toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}`);
}
getProperty(prop) {
try {
return this._playerProxy.get_connection().call_sync(
this._busName,
"/org/mpris/MediaPlayer2",
"org.freedesktop.DBus.Properties",
"Get",
new GLib.Variant("(ss)", ["org.mpris.MediaPlayer2.Player", prop]),
null,
Gio.DBusCallFlags.NONE,
50,
null
).recursiveUnpack()[0];
} catch {
return 0;
}
}
setPosition(value) {
this._playerProxy.get_connection().call_sync(
this._busName,
"/org/mpris/MediaPlayer2",
"org.mpris.MediaPlayer2.Player",
"SetPosition",
new GLib.Variant("(ox)", [this._trackId, value.toString()]),
null,
Gio.DBusCallFlags.NONE,
50,
null
);
}
_onPlayerProxyReady() {
this.signals.push(this._playerProxy.connectObject('g-properties-changed', () => this._updateInfo(), this));
this._updateInfo();
}
_updateSettings() {
if (St.Settings.get().color_scheme === 0 && GLib.get_os_info("NAME").includes("Ubuntu")) {
this.remove_style_class_name('progress-bar');
this.add_style_class_name('progress-bar-light');
} else if (St.Settings.get().color_scheme === 2) {
this.remove_style_class_name('progress-bar');
this.add_style_class_name('progress-bar-light');
} else {
this.remove_style_class_name('progress-bar-light');
this.add_style_class_name('progress-bar');
}
}
destroy() {
this.signals.map((i) => {
this.disconnect(i);
});
St.Settings.get().disconnect(this.updateSignal);
clearInterval(timeout);
this._playerProxy = null;
this.timestamps[0].destroy();
this.timestamps[1].destroy();
if (this.manager.bars[this._busName])
delete this.manager.bars[this._busName];
super.destroy();
}
}
GObject.registerClass(ProgressBarManager);
GObject.registerClass(ProgressBar);

View File

@ -0,0 +1,38 @@
/* Add your custom extension styling here */
.progress-bar {
-barlevel-height: 4px;
-slider-handle-radius: 0px;
-barlevel-active-background-color: white;
margin: 5px 5px 10px;
padding: 0;
color: white;
}
.progress-bar-light {
-barlevel-height: 4px;
-slider-handle-radius: 0px;
-barlevel-active-background-color: #282828;
margin: 5px 5px 10px;
padding: 0;
color: #282828;
}
.progress-bar-light:hover {
-slider-handle-radius: 5px;
-slider-handle-border-width: 0px;
height: 14px;
margin: 0 5px 5px;
}
.progress-bar:hover {
-slider-handle-radius: 5px;
-slider-handle-border-width: 0px;
height: 14px;
margin: 0 5px 5px;
}
.progressbar-timestamp {
font-family: Noto Sans;
margin: 0 15px 10px;
}