PDA

View Full Version : How to refresh the contents of a Jive Menu



Aesculus
2009-12-05, 19:02
I have a jive menu that needs to relect the change in the radio (check) status. I can confirm it works by manually changing the value in the called routine and then firing

$request->setStatusDone();

My problem though is that I have an asyncronous routine that runs and after it completes I need to set the new value. I have tried various techniques and none seem to cause anything to happen.

I have a global variable that contains the state of the menu item check that I have confirmed that I am updating so thats OK.

First I tried:

Slim::Control::Jive::refreshPluginMenus($client);

From the Jive debug I get
Slim::Control::Jive::refreshPluginMenus (592) Begin function
but it does not change the check value on the menu.

I also tried to call my routine that built the menu hoping that by recreating it I could refresh it.



$client->execute (['avpSM', $client]); # refresh menu

sub avpSM {
my $request = shift;
my $client = $request->client();
...
}


Any thoughts on how I can asynchronously get my menu updated?

Aesculus
2009-12-08, 08:44
Bump. Anybody know how to do this?

bklaas
2009-12-08, 08:57
Sorry for the delayed response.

Slim::Control::Jive uses an internal subroutine called _notifyJive() to refresh menu items on the Squeezeplay side. I'd use that as a template for what you need to do. The key component is the last line-- notifyFromArray(). Your async routine should assemble the updated menu items and call that with the action 'add'.



sub _notifyJive {
my ($menu, $client, $action) = @_;
$action ||= 'add';

my $id = _clientId($client);
my $menuForExport = $action eq 'add' ? _purgeMenu($menu) : $menu;

$menuForExport = [ map { _localizeMenuItemText( $client, $_ ) } @{$menuForExport} ];

Slim::Control::Request::notifyFromArray( $client, [ 'menustatus', $menuForExport, $action, $id ] );
}


hope that helps,
#!/ben

Aesculus
2009-12-08, 13:28
Ben: refreshPluginMenus from the Jive.pm file calls

_notifyJive(\@pluginMenus, $client);

I have used that but it does not force a refresh of the menu page. All I want to do is to have the menu repainted (in my case I need to move the check mark for the radio field to another menu item).

pippin
2009-12-08, 13:44
Hm, I believe the client is doing that (it re-requests the menu).
I also believe it's being triggered by a "nextWindow => 'refresh'" attribute.
Now how that one is being set, I don't know...

bklaas
2009-12-08, 13:50
Try sending the entire menu with the menu cli command

Slim::Control::Request::executeRequest( $client, [ 'menu' ] );

Aesculus
2009-12-08, 15:13
Try sending the entire menu with the menu cli command

Slim::Control::Request::executeRequest( $client, [ 'menu' ] );

Ben: Tried that. Same results. I ran a trace and it seems the execution is out of order.

avpSetSM calls the async process and when it gets its results calls updateSurroundMode



# ----------------------------------------------------------------------------
sub avpSetSM { # used to set the AVP surround mode
my $request = shift;
my $client = $request->client();

my $sMode = $request->getParam('_surroundMode'); #surround mode index
if ($sMode != $surroundMode) {
Plugins::DenonAvpControl::DenonAvpComms::SendNetAv pSurroundMode($gAvpIPAddress, $sMode, $client);
}
$log->debug("surroundMode: $surroundMode \n");
# $request->setStatusDone();
}

# ----------------------------------------------------------------------------
sub updateSurroundMode { #used to sync Surround Mode with AVP
my $class = shift;
my $client = shift;
$surroundMode = shift;

$log->debug("*** DenonAvpControl: New SM is: " . $surroundMode. "\n");

Slim::Control::Request::executeRequest( $client, [ 'avpSM' ] );
# Slim::Control::Jive::refreshPluginMenus($client);
}


see attachment

The new value gets set at line 172. Its logged in the menu routine at line 173 but the menu is painted at line 47?

bklaas
2009-12-08, 15:31
More or less understanding what you are trying to do now, and I'm not sure there's a pathway that will render exactly the UI you are looking for...

My understanding is: you have a menu of items that are each radio buttons. The callback command on those items executes a command from your Plugin, but that action executes asynchronously and you don't want the radio button to reflect any change until the anync command is done doing its thing? Is that correct?

If I'm understanding that correctly, I'd like to offer up a different UI model (apologies if this ruffles your feathers). Have the radio button immediately be checked (which should happen already?), and then send a showBriefly message to the client when the async command is completed.



$request->client->showBriefly(
{
'jive' =>
{
'type' => 'popupplay',
'text' => [ 'Some text to display on Squeezeplay' ],
},
}
);


I may be missing something in what you are trying to accomplish. Where necessary please fill in my gaps in understanding...

cheers,
#!/ben

Aesculus
2009-12-08, 16:19
More or less understanding what you are trying to do now, and I'm not sure there's a pathway that will render exactly the UI you are looking for...

My understanding is: you have a menu of items that are each radio buttons. The callback command on those items executes a command from your Plugin, but that action executes asynchronously and you don't want the radio button to reflect any change until the anync command is done doing its thing? Is that correct?

If I'm understanding that correctly, I'd like to offer up a different UI model (apologies if this ruffles your feathers). Have the radio button immediately be checked (which should happen already?), and then send a showBriefly message to the client when the async command is completed.



$request->client->showBriefly(
{
'jive' =>
{
'type' => 'popupplay',
'text' => [ 'Some text to display on Squeezeplay' ],
},
}
);


I may be missing something in what you are trying to accomplish. Where necessary please fill in my gaps in understanding...

cheers,
#!/ben

Ben. Your summary is correct. I can post the change immediately. It happens with the commented $request->setStatusDone(); if I change the $sMode variable to the radio index ( $surroundMode ).

But this may not be true if the async process cannot accomplish the request. The indicator (radio) will be wrong.

I still caanot comprehend that this request to just have Jive rebuild the menu is not something you support.

In theory it looks like Slim::Control::Jive::refreshPluginMenus($client); sould support exactly this.

BTW: My main client is iPeng native and the Controller.

Aesculus
2009-12-09, 08:02
Ben and others:

This seems to related to the async way I am doing things and the use of a global variable. It appears that the global is not getting set under the covers before the routine fires. I confirmed that I can fire the executeRequest and have it refresh the menu.

The problem is that even when I set the global variable before requesting the executeRequest, it still does not pick it up until after the execution of the redrawing. I even put in a 1 second timer and it still did not take.

What I am thinking to do now is to pass back the variable with the executeRequest so it arrives at the same time. This would be the correct way anyway but I got lazy and fell back to old times using globals.

But I do not know how to pass a parameter in the call for executeRequest. It is set up now to be executeRequest($client, 'menuSub').

Is there a way to pass a variable at the same time, or is there another method to get the variable updated for sure before I call the routine?

Boy I just love async processes, multithreaded, object and interpretive languages :-(

Aesculus
2009-12-13, 15:04
If I'm understanding that correctly, I'd like to offer up a different UI model (apologies if this ruffles your feathers). Have the radio button immediately be checked (which should happen already?), and then send a showBriefly message to the client when the async command is completed.

...
#!/ben

Well I gave up and basically did this. Most of the time it will be correct but if the system fails for some reason or the user changes the receiver outside of Squeezebox Server, then it will be wrong and they will have to go into the menus a few times until it gets in sync.

It would be best if the Execute procedure could accept parameters so I could insure they get picked up in context.