Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sound, sticky options to notify plugin #1053

Merged
merged 6 commits into from
Aug 23, 2017

Conversation

brenns10
Copy link
Contributor

The Notification API has a parameter called requireInteraction. When set to true, the notification will stay visible until the user interacts with it (clicking on settings or clicking the X button both count).

This pull request adds this option to the Notify plugin, so that if you don't notice the "kernel idle" notification, it will still be in your tray when you look. Unfortunately, sound is not yet supported in most browsers, otherwise I would have also added that feature.

@brenns10
Copy link
Contributor Author

Just a bump on this. Did I miss something from a contributor's guide? Screenshots, etc?

@jcb91
Copy link
Member

jcb91 commented Aug 22, 2017

Just a bump on this. Did I miss something from a contributor's guide? Screenshots, etc?

Nope, sorry, just nobody got round to looking at it, I think 😄

Just a couple of things I'd like to address about config loading.

The first is that it gets much less messy if each nbextension keeps its own top-level object for config, to avoid similarly-named parameters from colliding. You can use dots in parameter names for the configurator, as in e.g.
collapsible_headings.yaml#L9. That'd be a good thing to do here, I think, especially since other options may be added in future.

Second, is how the config is loaded. Although you've used a mechanism which occurs in many of our existing nbextensions, there is a better way! At the moment, lots of nbextneions are independently loading instances of the main notebook config, but the notebook loads one already, which you can use without requiring extra server requests. You can also use jquery to simplify the loading, if you've got a top-level object as I mentioned in the first point.

Finally, your current implementation doesn't actually wait for the config to definitely have loaded before using the parameter values - to do it properly, you need to use the .then pattern as with the updating the parameters.

So, all together, it would look something like

var load_ipython_extension = function () {
    return Jupyter.notebook.config.loaded.then(function () {
        $.extend(true, params, Jupyter.notebook.config.data.notify);
        ensure_permission();
        setup_notifier();
    });
};

This also means you don't need to require utils or config modules 😸

Hope that makes sense - let me know if anything's unclear!

@jcb91
Copy link
Member

jcb91 commented Aug 22, 2017

Also, thanks for your contribution, and apologies it took so long to look at this 😅

@jcb91
Copy link
Member

jcb91 commented Aug 22, 2017

Another thought - although the sound property isn't yet supported, does specifying it cause problems? if not, it could be added now to make this future-proof, I guess 🚀

@brenns10
Copy link
Contributor Author

@jcb91 Thank you, all that advice makes a lot of sense. I'm testing an update that implements those suggestions.

Also, thanks for your contribution, and apologies it took so long to look at this 😅

Hope I wasn't rude with my bump! I know this is nobody's full-time job :)

Another thought - although the sound property isn't yet supported, does specifying it cause problems? if not, it could be added now to make this future-proof, I guess 🚀

You're right, there shouldn't be any problem implementing it "ahead of time". The only problem then would be that I'd need to serve an appropriately licensed static sound file. I've found the file, but I don't know the mechanisms for serving static files in this project. If you could point me to an example, I would be glad to include the functionality.

@brenns10
Copy link
Contributor Author

Okay, I implemented the config loading changes. I also found an example of static file hosting in the zenmode extension, and added the support for the sound option. I did test this by inserting a code snippet that will just play the sound (rather than sending the sound option to the Notification API), and it worked properly.

Finally, I added the icon option, so that the browser notification shows the Jupyter logo. This is a feature of jupyter-notify that I missed.

@brenns10 brenns10 changed the title Add sticky notification option to notify plugin Add sound, sticky options to notify plugin Aug 22, 2017
Copy link
Member

@jcb91 jcb91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just some minor alterations to take care of

var n = new Notification(IPython.notebook.notebook_name, {body: "Kernel is now idle\n(ran for " + Math.round(elapsed_time) + " secs)"});
var opts = {
body: "Kernel is now idle\n(ran for " + Math.round(elapsed_time) + " secs)",
icon: "/static/base/images/favicon.ico",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat, but to work correctly with non-default base_url (e.g. on jupyterhub), this should be

Jupyter.notebook.base_url + 'static/base/images/favicon.ico'

"use strict";

var params = {
sticky: false,
sound: false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could support custom sounds by adding a url as a parameter. Maybe a name like play_sound might be better in case this gets added in future?

"jquery",
"base/js/namespace",
"require",
], function ($, IPython, require) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes more sense to assign the namespace to the Jupyter variable, since that's what it's now called, and what you've used later on in the file. For now, both work since both IPython and Jupyter are defined in the global namespace, but it's less confusing for people reading this file if we stick to the new namespace which we definitely get from the define call...

@brenns10
Copy link
Contributor Author

Latest commit renames IPython -> Jupyter throughout, renames sound -> play_sound in the config, and fixes the url path.

@brenns10
Copy link
Contributor Author

One other question: would it be crazy to implement sound support using the Audio API as a fallback? It's like two lines (four if you put it behind a configuration option). That way you can get notification sounds when your kernel completes, even though browsers don't support it yet.

I have to believe that's how most apps (e.g. the Facebook Messenger webapp) do sound for notifications.

@jcb91
Copy link
Member

jcb91 commented Aug 23, 2017

One other question: would it be crazy to implement sound support using the Audio API as a fallback? It's like two lines (four if you put it behind a configuration option). That way you can get notification sounds when your kernel completes, even though browsers don't support it yet.

I have to believe that's how most apps (e.g. the Facebook Messenger webapp) do sound for notifications.

Doesn't sound crazy to me, and as long as you make appropriate checks to ensure nothing breaks if it's not available/asupported, I can't see a reason not to do it 😄

icon: Jupyter.notebook.base_url + "static/base/images/favicon.ico",
requireInteraction: params.sticky
};
if (params.sound) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should now be play_sound?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. Javascript makes it so easy for these things to go unnoticed.

@brenns10
Copy link
Contributor Author

Okay, so it took a bit more than 4 lines :)

This last couple commits fixes the forgotten rename, and switches the notification sound mechanism to use the HTMLAudioElement API. This is well supported in HTML5, but shouldn't cause problems if unsupported. I also included the original implementation (the sound option of the Notification API) in comments so it would be easy to switch if browser support improves.

@jcb91
Copy link
Member

jcb91 commented Aug 23, 2017

Looks good to me, thanks @brenns10!

@jcb91 jcb91 merged commit 3b74c45 into ipython-contrib:master Aug 23, 2017
@brenns10
Copy link
Contributor Author

Thank you! Any idea when a new PyPI release will be?

@jcb91
Copy link
Member

jcb91 commented Aug 23, 2017

Any idea when a new PyPI release will be?

ASAP, I should hope, we (I) have been a bit lax and haven't made one for quite some time...

@jcb91
Copy link
Member

jcb91 commented Aug 23, 2017

so, 0.3.0 should now be live on pypi, conda-forge to follow...

@jfbercher
Copy link
Member

so, 0.3.0 should now be live on pypi, conda-forge to follow...

Wow!! 👍 👍

@brenns10
Copy link
Contributor Author

@jcb91 that's awesome, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants