DTG: Add notification service to display popup messages

unused for now
This commit is contained in:
zzz
2021-12-01 08:37:51 -05:00
parent dd439bc9be
commit 890a8927a5
3 changed files with 168 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ import net.i2p.I2PAppContext;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientAppState;
import static net.i2p.app.ClientAppState.*;
import net.i2p.app.NotificationService;
import net.i2p.desktopgui.router.RouterManager;
import net.i2p.router.RouterContext;
import net.i2p.router.app.RouterApp;
@@ -28,7 +29,7 @@ import net.i2p.util.I2PProperties.I2PPropertyCallback;
/**
* The main class of the application.
*/
public class Main implements RouterApp {
public class Main implements RouterApp, NotificationService {
// non-null
private final I2PAppContext _appContext;
@@ -204,6 +205,46 @@ public class Main implements RouterApp {
t.start();
}
/////// NotificationService methods
/**
* Send a notification to the user.
*
* @param source unsupported
* @param category unsupported
* @param priority unsupported
* @param title for the popup, translated
* @param message translated
* @param path unsupported
* @return 0, or -1 on failure
*/
public int notify(String source, String category, int priority, String title, String message, String path) {
TrayManager tm = _trayManager;
if (tm == null)
return -1;
return tm.displayMessage(priority, title, message, path);
}
/**
* Cancel a notification if possible.
* Unsupported.
*
* @return false always
*/
public boolean cancel(int id) {
return false;
}
/**
* Update the text of a notification if possible.
* Unsupported.
*
* @return false always
*/
public boolean update(int id, String title, String message, String path) {
return false;
}
/////// ClientApp methods
/** @since 0.9.26 */

View File

@@ -8,21 +8,27 @@ import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.SwingWorker;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import net.i2p.I2PAppContext;
import net.i2p.apps.systray.UrlLauncher;
import net.i2p.desktopgui.i18n.DesktopguiTranslator;
import net.i2p.util.Log;
import net.i2p.util.SystemVersion;
/**
@@ -204,6 +210,72 @@ abstract class TrayManager {
return image;
}
/**
* Send a notification to the user.
*
* @param title for the popup, translated
* @param message translated
* @param path unsupported
* @return 0, or -1 on failure
*/
public int displayMessage(int priority, String title, String message, String path) {
final TrayIcon ti = trayIcon;
if (ti == null)
return -1;
TrayIcon.MessageType type;
if (priority <= Log.DEBUG)
type = TrayIcon.MessageType.NONE;
else if (priority <= Log.INFO)
type = TrayIcon.MessageType.INFO;
else if (priority <= Log.WARN)
type = TrayIcon.MessageType.WARNING;
else
type = TrayIcon.MessageType.ERROR;
ti.displayMessage(title, message, type);
/*
* There's apparently no way to bind a particular message to an action
that comes back. We can't keep a queue because we don't get
an action back when the message is removed via timeout or user x-out.
On OSX, new messages dismiss previous ones.
On LXDE (and Gnome?), new messages go under previous ones. Timeout is only 10 seconds.
Message timeout is platform-dependent.
So the order of events is unknowable.
This only works if there is only one message ever.
if (path != null && path.length() > 0) {
if (path.charAt(0) == '/');
path = path.substring(1);
final String url = _appContext.portMapper().getConsoleURL() + path;
ti.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
ti.removeActionListener(this);
new SwingWorker<Object, Object>() {
@Override
protected Object doInBackground() throws Exception {
System.out.println("DIB " + arg0);
UrlLauncher launcher = new UrlLauncher(_appContext, null, null);
try {
launcher.openUrl(url);
System.out.println("DIB success " + url);
} catch (IOException e1) {
System.out.println("DIB fail " + url);
}
return null;
}
@Override
protected void done() {
System.out.println("done " + arg0);
}
}.execute();
}
});
}
*/
return 0;
}
protected String _t(String s) {
return DesktopguiTranslator._t(_appContext, s);
}

View File

@@ -0,0 +1,54 @@
package net.i2p.app;
/**
* A service to send messages to users.
* This service is currently provided by desktopgui (when supported and enabled).
* Other applications may support this interface in the future.
*
* Example usage:
*
* <pre>
* ClientAppManager cmgr = _context.clientAppManager();
* if (cmgr != null) {
* NotificationService ns = (NotificationService) cmgr.getRegisteredApp("desktopgui");
* if (ns != null)
* ns.notify("foo", null, Log.INFO, _t("foo"), _t("message"), "/foo/bar");
* }
* <pre>
*
* @since 0.9.53
*/
public interface NotificationService {
/**
* Send a (possibly delayed) notification to the user.
*
* @param source e.g. "i2psnark"
* @param category may be null, probably unused
* @param priority higher is higher, Log.INFO etc. recommended, probably unused
* @param title for the popup, translated
* @param message translated
* @param path in console for more information, starting with /, must be URL-escaped, or null
* @return an ID to use with cancel() or update(), or -1 on failure
*/
public int notify(String source, String category, int priority, String title, String message, String path);
/**
* Cancel a notification if possible.
*
* @param id as received from notify()
* @return success
*/
public boolean cancel(int id);
/**
* Update the text of a notification if possible.
*
* @param id as received from notify()
* @param title for the popup, translated
* @param message translated
* @param path in console starting with /, must be URL-escaped, or null
* @return success
*/
public boolean update(int id, String title, String message, String path);
}