Skip to content

Commit

Permalink
Merge pull request #1532 from rern/UPDATE
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
rern authored Dec 16, 2023
2 parents 25519cb + 245a9fc commit b8ad922
Show file tree
Hide file tree
Showing 37 changed files with 413 additions and 445 deletions.
11 changes: 5 additions & 6 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ alias=r1

. /srv/http/bash/settings/addons.sh

# 20231216
if [[ $( pacman -Q python-websockets ) != 'python-websockets 11.0-1' ]]; then
pacman -Sy --needed --noconfirm python-websockets
fi

# 202312010
file=$dirsystem/display.json
for k in albumyear composername conductorname; do
Expand Down Expand Up @@ -99,9 +104,3 @@ installfinish
# 20231125
[[ $websocketrestart ]] && systemctl restart websocket
[[ $mpdrestart ]] && $dirsettings/player-conf.sh

# 20231013
if ! grep -q smbdfree /etc/samba/smb.conf; then
sed -i '/^.USB/ a\\tdfree command = /srv/http/bash/smbdfree.sh' /etc/samba/smb.conf
systemctl try-restart smb
fi
30 changes: 10 additions & 20 deletions srv/http/assets/css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@font-face {
font-family : rern;
src : url( '/assets/fonts/rern.woff2?v=1701344782' );
src : url( '/assets/fonts/rern.woff2?v=1702394239' );
}
@font-face {
font-family : Lato;
Expand Down Expand Up @@ -230,6 +230,7 @@ i {
.i-wifi2::before { content: '\F59A'; position: absolute; }
.i-wifi2::after { content: '\F59B'; color: var( --cga ); }
.i-wlan::before { content: '\F597' }
#divoutput .i-gear::before { content: '\F516' }

html {
height : 100%;
Expand Down Expand Up @@ -483,33 +484,22 @@ input[type=range]::-moz-range-track {
background: var( --track );
border: var( --trackborder );
}
.range .value,
#infoRange {
text-align: center;
}
#infoRange .value {
height: 30px;
font-size: 18px;
font-weight: 300;
}
.range .min,
.range .max,
#infoRange .min,
#infoRange .max {
#infoRange i {
position: relative;
display: inline-block;
width: 40px;
padding: 0 10px;
vertical-align: 16px;
text-align: right;
color: var( --cg60 );
width: 40px !important;
line-height: 40px;
vertical-align: 14px !important;
color: var( --cg60 ) !important;
cursor: pointer;
}
.range .max,
#infoRange .max {
text-align: left;
}
.range,
#infoRange {
text-align: center;
}

/* info */
.infobtn,
Expand Down
24 changes: 21 additions & 3 deletions srv/http/assets/js/camilla.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,20 @@ function psOnClose() {
if ( wscamilla ) wscamilla.close();
$( '#divstate .label' ).html( 'Buffer · Sampling' );
}
function playbackButton() {
var play = S.state === 'play';
if ( S.player === 'mpd' ) {
if ( S.pllength ) {
var btn = play ? 'pause' : 'play';
} else {
var btn = 'play disabled';
}
} else {
var btn = play ? 'stop' : 'play disabled';
}
$( '.icon' ).prop( 'class', 'icon i-'+ S.player );
$( '.playback' ).prop( 'class', 'playback i-'+ btn );
}
function psVolume( data ) {
var vol = data.val;
if ( [ 'mute', 'unmute' ].includes( data.type ) ) {
Expand Down Expand Up @@ -524,7 +538,11 @@ var render = {
if ( DEV.enable_rate_adjust ) V.statusget.push( 'GetRateAdjust' );
V.statuslast = V.statusget[ V.statusget.length - 1 ];
render.statusValue();
$( '#divconfiguration .name' ).html( 'Configuration'+ ( S.bluetooth ? ico( 'bluetooth' ) : '' ) );
if ( S.bluetooth ) {
if ( ! $( '#divconfiguration .col-l i' ).length ) $( '#divconfiguration a' ).after( ico( 'bluetooth' ) );
} else {
$( '#divconfiguration .col-l i' ).remove();
}
$( '#configuration' )
.html( htmlOption( S.lsconfigs ) )
.val( S.configname );
Expand Down Expand Up @@ -1197,7 +1215,7 @@ var setting = {
k = Object.keys( kv );
k.forEach( key => {
if ( key === 'format' ) {
var s = jsonClone( C.format );
var s = jsonClone( dev === 'capture' ? C.format : S.format );
var v = { format: data.format };
} else if ( key === 'device' ) {
var s = jsonClone( C.devices[ dev ] );
Expand Down Expand Up @@ -1518,7 +1536,7 @@ var util = {
return capitalized
}
, save2file : () => {
bash( [ 'settings/camilla.py' ] );
bash( [ 'saveconfig' ] );
}
, volume : ( pageX, type ) => {
var bandW = $( '#volume .slide' ).width();
Expand Down
130 changes: 76 additions & 54 deletions srv/http/assets/js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,16 +243,14 @@ select: [U] [D] - check
*/
if ( ! I.active ) return

e.stopPropagation(); // suppress others
var key = e.key;
switch ( key ) {
case 'Enter':
if ( ! $( '#infoOk' ).hasClass( 'disabled' ) && ! $( 'textarea' ).is( ':focus' ) ) $( '#infoOk' ).trigger( 'click' );
break;
case 'Escape':
if ( I.active ) {
$( '#infoX' ).trigger( 'click' );
local(); // prevent toggle setting menu
}
$( '#infoX' ).trigger( 'click' );
break;
case 'ArrowLeft':
case 'ArrowRight':
Expand Down Expand Up @@ -445,7 +443,7 @@ function info( json ) {
if ( I.passwordlabel ) {
infoKey2array( 'passwordlabel' );
htmls.password = '';
I.passwordlabel.forEach( lbl => htmls.password += '<tr class="trpassword"><td>'+ lbl +'</td><td><input type="password"></td></tr>' );
I.passwordlabel.forEach( lbl => htmls.password += '<tr class="trpassword"><td>'+ lbl +'</td><td><input type="password"></td><td>'+ ico( 'eye' ) +'</td></tr>' );
}
if ( I.textarea ) {
htmls.textarea = '<textarea></textarea>';
Expand Down Expand Up @@ -534,7 +532,7 @@ function info( json ) {
I.rangelabel.forEach( range => {
htmls.range += '<div class="name">'+ I.rangelabel +'</div>'
+'<div class="value gr"></div>'
+'<a class="min">0</a><input type="range" min="0" max="100"><a class="max">100</a>'
+ ico( 'minus dn' ) +'<input type="range" min="0" max="100">'+ ico( 'plus' )
+ ( I.rangesub ? '<div class="sub gr">'+ I.rangesub +'</div>' : '' )
} );
htmls.range += '</div>';
Expand All @@ -556,6 +554,7 @@ function info( json ) {
$( '#infoOverlay' ).removeClass( 'hide' );
$( '#infoBox' ).css( 'margin-top', $( window ).scrollTop() );
infoButtonWidth();
$( '#infoOverlay' ).focus();
return
}

Expand Down Expand Up @@ -595,27 +594,10 @@ function info( json ) {
infoButtonWidth();
// set width: text / password / textarea
infoWidth();
if ( I.rangelabel ) {
$( '#infoRange input' ).on( 'input', function() {
$( '#infoRange .value' ).text( $( this ).val() );
} );
if ( I.rangeupdn ) {
$( '#infoRange a' ).on( 'click', function() {
var updn = $( this ).hasClass( 'max' ) ? 1 : -1;
var $range = $( '#infoRange input' );
var val = +$range.val() + updn;
$range.val( val );
$( '#infoRange .value' ).text( val );
if ( typeof I.rangeupdn === 'function' ) I.rangeupdn( val );
} );
}
}
if ( I.tab && $input.length === 1 ) $( '#infoContent' ).css( 'padding', '30px' );
// custom function before show
$( '#infoContent input:password' ).parent().after( '<td>'+ ico( 'eye' ) +'</td>' );
if ( [ 'localhost', '127.0.0.1' ].includes( location.hostname ) ) $( '#infoContent a' ).removeAttr( 'href' );
// set at current scroll position
$( '#infoBox' ).css( 'margin-top', $( window ).scrollTop() );
if ( I.tab && $input.length === 1 ) $( '#infoContent' ).css( 'padding', '30px' );
// check inputs: blank / length / change
if ( I.checkblank ) {
if ( I.checkblank === true ) I.checkblank = [ ...Array( $inputbox.length ).keys() ];
Expand All @@ -634,6 +616,38 @@ function info( json ) {
I.nochange = I.values && I.checkchanged ? true : false;
$( '#infoOk' ).toggleClass( 'disabled', I.blank || I.notip || I.short || I.nochange ); // initial check
infoCheckSet();
if ( I.rangelabel ) {
var $range = $( '#infoRange input' );
var timeout, val;
$range.on( 'input', function() { // drag/click
val = +$range.val();
$( '#infoRange .value' ).text( val );
if ( I.rangechange ) I.rangechange( val );
} ).on( 'touchend mouseup keyup', function() { // drag stop
if ( I.rangestop ) setTimeout( () => I.rangestop( val ), 300 );
} );
$( '#infoRange i' ).on( 'mouseup keyup', function() { // increment up/dn
clearTimeout( timeout );
if ( ! V.press ) {
val = +$range.val();
$( this ).hasClass( 'dn' ) ? val-- : val++;
$range
.val( val )
.trigger( 'input' );
}
if ( I.rangestop ) timeout = setTimeout( () => I.rangestop( val ), 600 );
} ).press( function( e ) {
val = +$range.val();
var up = $( e.target ).hasClass( 'dn' )
timeout = setInterval( () => {
up ? val-- : val++;
$range
.val( val )
.trigger( 'input' );
}, 100 );
} );
}
// custom function before show
if ( I.beforeshow ) I.beforeshow();
} );
$( '#infoContent .i-eye' ).on( 'click', function() {
Expand Down Expand Up @@ -1105,45 +1119,47 @@ window.onpageshow = pageActive;

// websocket
var ws, wsvolume;
function volumeSet( vol, type ) {
if ( ! type ) volumePush( vol );
wsvolume.send( [ 'volume', S.volume, vol, S.control, S.card, 'CMD CURRENT TARGET CONTROL CARD' ].join( '\n' ) );
}
function volumeSetAt() { // drag / press / updn
wsvolume.send( [ 'volumesetat', S.volume, S.control, S.card, 'CMD TARGET CONTROL CARD' ].join( '\n' ) );
function volumeMuteToggle() {
S.volumemute ? volumePush( S.volumemute, 'unmute' ) : volumePush( S.volume, 'mute' );
volumeSet( S.volumemute, 'toggle' );
}
function volumePush( vol, type ) {
local();
wsPush( 'volume', '{ "type": "'+ ( type || 'push' ) +'", "val": '+ ( vol || S.volume ) +' }' );
}
function volumeMuteToggle() {
S.volumemute ? volumePush( S.volumemute, 'unmute' ) : volumePush( S.volume, 'mute' );
volumeSet( S.volumemute, 'toggle' );
function volumeSet( vol, type ) {
if ( ! type ) volumePush( vol );
wsvolume.send( [ 'volume', S.volume, vol, S.control, S.card, 'CMD CURRENT TARGET CONTROL CARD' ].join( '\n' ) );
}
function websocketConnect( reboot ) {
if ( ! page || page === 'camilla' ) {
if ( ! wsvolume || wsvolume.readyState !== 1 ) wsvolume = new WebSocket( 'ws://'+ window.location.host +':8080/volume' );
function volumeSetAt( val ) { // drag / press / updn
wsvolume.send( [ 'volumesetat', val || S.volume, S.control, S.card, 'CMD TARGET CONTROL CARD' ].join( '\n' ) );
}
function websocketConnect() {
if ( [ '', 'camilla', 'player' ].includes( page ) ) {
if ( ! websocketOk( wsvolume ) ) wsvolume = new WebSocket( 'ws://'+ window.location.host +':8080/volume' );
}
if ( ws && ws.readyState === 1 ) return
if ( websocketOk( ws ) ) return

ws = new WebSocket( 'ws://'+ window.location.host +':8080' );
ws.onopen = () => websocketReady( ws );
ws.onclose = () => ws = null;
ws.onmessage = message => psOnMessage( message ); // data pushed from server
ws.onready = () => { // custom
ws.send( 'clientadd' );
if ( ! reboot ) return

if ( S.login ) {
location.href = '/';
} else {
refreshData();
loaderHide();
bannerHide();
if ( V.reboot ) {
delete V.reboot
if ( S.login ) {
location.href = '/';
} else {
refreshData();
loaderHide();
bannerHide();
}
}
}
ws.onopen = () => {
websocketReady( ws );
}
ws.onclose = () => ws = null;
ws.onmessage = message => psOnMessage( message ); // data pushed from server
}
function websocketOk( socket ) {
return socket !== null && typeof socket === 'object' && socket.readyState === 1
}
function websocketReady( socket ) {
var interval = setTimeout( () => {
Expand All @@ -1153,6 +1169,12 @@ function websocketReady( socket ) {
}
}, 100 );
}
function websocketReconnect() {
fetch( '/data/shm/startup' )
.then( response => {
response.ok ? websocketConnect() : setTimeout( websocketReconnect, 1000 );
} );
}
function wsPush( channel, data ) {
ws.send( '{ "channel": "'+ channel +'", "data": '+ data +' }' );
}
Expand Down Expand Up @@ -1180,17 +1202,17 @@ function psNotify( data ) {
}
function psPower( data ) {
loader();
V.off = data.type === 'off';
V[ data.type ] = true;
banner( data.type +' blink', 'Power', V.off ? 'Off ...' : 'Reboot ...', -1 );
ws.close();
if ( typeof wsvolume === 'object' ) wsvolume.close();
if ( V.off ) {
$( '#loader' ).css( 'background', '#000000' );
setTimeout( () => {
$( '#loader svg' ).css( 'animation', 'none' );
bannerHide();
}, 10000 );
} else { // reconnect after reboot
setTimeout( () => {
websocketConnect( 'reboot' );
}, data.wait * 1000 );
setTimeout( websocketReconnect, data.startup + 5000 ); // add shutdown 5s
}
}
7 changes: 4 additions & 3 deletions srv/http/assets/js/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ function bookmarkNew() {
} );
}
function currentSet() {
bash( [ 'mpcsetcurrent', V.list.index + 1, 'CMD POS' ] );
S.song = V.list.index;
setPlaylistScroll();
local();
bash( [ 'mpcskip', V.list.index + 1, 'CMD POS' ] );
}
function directoryList() {
if ( [ 'album', 'latest' ].includes( V.mode ) ) {
Expand Down Expand Up @@ -430,8 +433,6 @@ function webRadioCoverart() {
var name = V.list.name;
}
var imagefilenoext = '/srv/http/data/'+ mode +'/img/'+ url.replace( /\//g, '|' );
$( '#coverart' ).removeAttr( 'style' );
$( '.coveredit' ).remove();
info( {
icon : 'coverart'
, title : ( mode === 'webradio' ? 'Web' : 'DAB' ) +' Radio Cover Art'
Expand Down
16 changes: 6 additions & 10 deletions srv/http/assets/js/features.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,12 @@ $( '#setting-localbrowser' ).on( 'click', function() {
$( '.brightness' ).on( 'click', function() {
switchCancel();
info( {
icon : 'firefox'
, title : 'Browser on RPi'
, rangelabel : 'Brightness'
, values : S.brightness
, beforeshow : () => {
$( '#infoRange input' ).on( 'input', function() {
bash( [ 'brightness', $( this ).val(), 'CMD VAL' ] );
} );
}
, okno : true
icon : 'firefox'
, title : 'Browser on RPi'
, rangelabel : 'Brightness'
, values : S.brightness
, rangechange : val => bash( [ 'brightness', val, 'CMD VAL' ] )
, okno : true
} );
} );
$( '.reload' ).on( 'click', function() {
Expand Down
Loading

0 comments on commit b8ad922

Please sign in to comment.