Compare commits
No commits in common. "48db545c78c43ac61c7b700c1e475e77e918d4fa" and "8bcce51e56bcda79b0278538e7dda8685dd27999" have entirely different histories.
48db545c78
...
8bcce51e56
4 changed files with 47 additions and 109 deletions
1
index.js
1
index.js
|
@ -2,7 +2,6 @@ const render = require('./render');
|
||||||
const mpris = require('./mpris');
|
const mpris = require('./mpris');
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
process.title = 'bouncy';
|
|
||||||
mpris.init(render.error, render.warning, render.info);
|
mpris.init(render.error, render.warning, render.info);
|
||||||
setInterval(() => {render.render(mpris.getArtist(), mpris.getAlbum(), mpris.getTitle(), mpris.getSongStart(), mpris.getSongEnd(), mpris.getSongPauseSpot(), mpris.getSongPaused())}, render.refreshrate);
|
setInterval(() => {render.render(mpris.getArtist(), mpris.getAlbum(), mpris.getTitle(), mpris.getSongStart(), mpris.getSongEnd(), mpris.getSongPauseSpot(), mpris.getSongPaused())}, render.refreshrate);
|
||||||
}
|
}
|
||||||
|
|
BIN
logosmall.png
BIN
logosmall.png
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
|
@ -11,12 +11,8 @@ bouncy is a tiny script that hooks onto mpris to read your currently listening s
|
||||||
- a machine running dbus and mpris (typically linux)
|
- a machine running dbus and mpris (typically linux)
|
||||||
- nodejs >=14
|
- nodejs >=14
|
||||||
|
|
||||||
## how-to install
|
## how-to
|
||||||
|
|
||||||
`npm install` and `node index.js`
|
`npm install` and `node index.js`
|
||||||
|
|
||||||
the music player string defaults to `org.mpris.MediaPlayer2.rhythmbox`, however you can use the `BOUNCY_MUSICPLAYER` environment value to change it to another music player name
|
the music player string defaults to `org.mpris.MediaPlayer2.rhythmbox`, however you can use the `BOUNCY_MUSICPLAYER` environment value to change it to another music player name
|
||||||
|
|
||||||
## usage
|
|
||||||
|
|
||||||
press space to switch between modes
|
|
147
render.js
147
render.js
|
@ -1,29 +1,5 @@
|
||||||
const readline = require('readline');
|
const readline = require('readline');
|
||||||
|
|
||||||
readline.emitKeypressEvents(process.stdin);
|
|
||||||
|
|
||||||
if (process.stdin.isTTY) {
|
|
||||||
process.stdin.setRawMode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const modes = ['classic', 'bottom', 'top'];
|
|
||||||
let mode = 0;
|
|
||||||
|
|
||||||
let modePopup = 0;
|
|
||||||
const modePopupDuration = 2;
|
|
||||||
|
|
||||||
process.stdin.on('keypress', (str, key) => {
|
|
||||||
if (key.name === 'space') {
|
|
||||||
mode++;
|
|
||||||
mode = mode % modes.length;
|
|
||||||
modePopup = modePopupDuration;
|
|
||||||
}
|
|
||||||
if (key.sequence === '\x03' || key.sequence === '\x04') process.exit(0); // ctrl+c, ctrl+d
|
|
||||||
});
|
|
||||||
process.on('exit', () => {
|
|
||||||
process.stdout.write('\x1B[?25h\033[0m'); // show cursor
|
|
||||||
})
|
|
||||||
|
|
||||||
const plas = [' ', '.', '*', '/', '0'];
|
const plas = [' ', '.', '*', '/', '0'];
|
||||||
const progressChars = ['▏', '▎', '▍', '▌', '▋', '▊', '▉'];
|
const progressChars = ['▏', '▎', '▍', '▌', '▋', '▊', '▉'];
|
||||||
//const progressChars = ['0', '1', '2', '3', '4', '5', '6', '7'];
|
//const progressChars = ['0', '1', '2', '3', '4', '5', '6', '7'];
|
||||||
|
@ -54,8 +30,9 @@ function plasma(x, y, time, k) {
|
||||||
let displaytitle = '';
|
let displaytitle = '';
|
||||||
let displayalbum = '';
|
let displayalbum = '';
|
||||||
|
|
||||||
// type: 0 = error, 1 = warning, 2 = info
|
let errorText = '';
|
||||||
let popups = [];
|
let errorTimer = 0;
|
||||||
|
let errorType = 0; // 0 = error, 1 = warning, 2 = info
|
||||||
|
|
||||||
function transform(old, n) {
|
function transform(old, n) {
|
||||||
if (old.length < n.length) {
|
if (old.length < n.length) {
|
||||||
|
@ -82,7 +59,7 @@ let time = 0;
|
||||||
function render(artist, album, title, songStart, songEnd, pauseSpot, paused) {
|
function render(artist, album, title, songStart, songEnd, pauseSpot, paused) {
|
||||||
let dt = refreshrate / 1000
|
let dt = refreshrate / 1000
|
||||||
time += dt;
|
time += dt;
|
||||||
modePopup -= dt;
|
errorTimer -= dt;
|
||||||
let w = process.stdout.columns;
|
let w = process.stdout.columns;
|
||||||
let h = process.stdout.rows;
|
let h = process.stdout.rows;
|
||||||
|
|
||||||
|
@ -97,80 +74,34 @@ function render(artist, album, title, songStart, songEnd, pauseSpot, paused) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// leaving the coordinates as non-integer values is very undefined behavior
|
// leaving the coordinates as non-integer values is very undefined behavior
|
||||||
let texts = [];
|
let texts = [
|
||||||
|
{
|
||||||
switch (mode) {
|
value: ' ' + displaytitle + ' ',
|
||||||
case 0:
|
x: Math.round(w / 2 - displaytitle.length / 2 + Math.sin(time) * 5),
|
||||||
texts.push({
|
y: Math.floor(h / 2) - 1,
|
||||||
value: ' ' + displaytitle + ' ',
|
color: '\033[7;1m'
|
||||||
x: Math.round(w / 2 - displaytitle.length / 2 + Math.sin(time) * 5),
|
},
|
||||||
y: Math.floor(h / 2) - 1,
|
{
|
||||||
color: '\033[7;1m'
|
value: ' ' + displayalbum + ' ',
|
||||||
});
|
x: Math.round(w / 2 - displayalbum.length / 2 - Math.sin(time) * 5),
|
||||||
texts.push({
|
y: Math.floor(h / 2) + 1,
|
||||||
value: ' ' + displayalbum + ' ',
|
color: '\033[7m'
|
||||||
x: Math.round(w / 2 - displayalbum.length / 2 - Math.sin(time) * 5),
|
|
||||||
y: Math.floor(h / 2) + 1,
|
|
||||||
color: '\033[7m'
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
texts.push({
|
|
||||||
value: ' ' + displaytitle + ' '.repeat(w),
|
|
||||||
x: 0,
|
|
||||||
y: h - 3,
|
|
||||||
color: '\033[7;1m'
|
|
||||||
});
|
|
||||||
texts.push({
|
|
||||||
value: ' ' + displayalbum + ' '.repeat(w),
|
|
||||||
x: 0,
|
|
||||||
y: h - 2,
|
|
||||||
color: '\033[7m'
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
texts.push({
|
|
||||||
value: ' ' + displaytitle + ' '.repeat(w),
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
color: '\033[7;1m'
|
|
||||||
});
|
|
||||||
texts.push({
|
|
||||||
value: ' ' + displayalbum + ' '.repeat(w),
|
|
||||||
x: 0,
|
|
||||||
y: 1,
|
|
||||||
color: '\033[7m'
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = 0;
|
|
||||||
for (let popup of popups) {
|
|
||||||
popup.timer -= dt;
|
|
||||||
if (popup.timer < 0) {
|
|
||||||
popups.splice(i, 1);
|
|
||||||
} else {
|
|
||||||
let symbol = ['⚠️', '⚠️', 'ℹ'][popup.type];
|
|
||||||
let color = ['\033[41;37m', '\033[43;37m', '\033[44;37m'][popup.type];
|
|
||||||
let text = ` ${symbol} ${popup.text} `;
|
|
||||||
|
|
||||||
texts.push({
|
|
||||||
value: ' '.repeat(text.length) + text,
|
|
||||||
x: -text.length * 2 + Math.round((text.length + 3) * outCirc(Math.min(popup.timer, 1))),
|
|
||||||
y: 3 + i,
|
|
||||||
color: color
|
|
||||||
});
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
}
|
];
|
||||||
|
|
||||||
|
if (errorText && errorTimer > 0) {
|
||||||
|
let symbol = '⚠️';
|
||||||
|
if (errorType === 2) symbol = 'ℹ';
|
||||||
|
|
||||||
|
let color = '\033[41;37m';
|
||||||
|
if (errorType === 1) color = '\033[43;37m';
|
||||||
|
if (errorType === 2) color = '\033[44;37m';
|
||||||
|
|
||||||
if (modePopup > 0) {
|
|
||||||
texts.push({
|
texts.push({
|
||||||
value: modes[mode],
|
value: ` ${symbol} ${errorText} `,
|
||||||
x: Math.floor(w - ((modes[mode].length + 2) * outCirc(Math.min(modePopup, 1)))),
|
x: 4,
|
||||||
y: 0,
|
y: Math.round(3 * outCirc(Math.min(errorTimer, 1))),
|
||||||
color: '\033[40;37m'
|
color: color
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +154,7 @@ function render(artist, album, title, songStart, songEnd, pauseSpot, paused) {
|
||||||
let pChar = progressChars[Math.floor(blockProgress * progressChars.length)];
|
let pChar = progressChars[Math.floor(blockProgress * progressChars.length)];
|
||||||
|
|
||||||
let color = (x / (w - 1) > (Math.floor(progress * w) / w)) ? '\033[40;37m' : '\033[47;30m';
|
let color = (x / (w - 1) > (Math.floor(progress * w) / w)) ? '\033[40;37m' : '\033[47;30m';
|
||||||
|
|
||||||
let pause = (paused && x === (w - 2)) ? '⏸' : null;
|
let pause = (paused && x === (w - 2)) ? '⏸' : null;
|
||||||
|
|
||||||
sum += color + (pause || (timerString[x - 1] === ' ' ? null : timerString[x - 1]) || (inProgressArea ? pChar : ' ')) + '\033[0m';
|
sum += color + (pause || (timerString[x - 1] === ' ' ? null : timerString[x - 1]) || (inProgressArea ? pChar : ' ')) + '\033[0m';
|
||||||
|
@ -248,9 +179,21 @@ function render(artist, album, title, songStart, songEnd, pauseSpot, paused) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function error(content) {popups.push({text: content, timer: errorDuration, type: 0});}
|
function error(content) {
|
||||||
function warning(content) {popups.push({text: content, timer: errorDuration, type: 1});}
|
errorText = content;
|
||||||
function info(content) {popups.push({text: content, timer: errorDuration, type: 2});}
|
errorTimer = errorDuration;
|
||||||
|
errorType = 0;
|
||||||
|
}
|
||||||
|
function warning(content) {
|
||||||
|
errorText = content;
|
||||||
|
errorTimer = errorDuration;
|
||||||
|
errorType = 1;
|
||||||
|
}
|
||||||
|
function info(content) {
|
||||||
|
errorText = content;
|
||||||
|
errorTimer = errorDuration;
|
||||||
|
errorType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.render = render;
|
module.exports.render = render;
|
||||||
module.exports.refreshrate = refreshrate;
|
module.exports.refreshrate = refreshrate;
|
||||||
|
|
Loading…
Reference in a new issue