From 96b5c2627761618b83658c02957fda6bacd7bcdf Mon Sep 17 00:00:00 2001 From: 0xboobface <0xboobface@gmail.com> Date: Sun, 2 Dec 2018 17:02:17 +0100 Subject: [PATCH] Implement notification messages with SystemTray and notify-send --- .../java/ctbrec/ui/CamrecApplication.java | 15 ++-- common/src/main/java/ctbrec/OS.java | 75 +++++++++++++++++++ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/client/src/main/java/ctbrec/ui/CamrecApplication.java b/client/src/main/java/ctbrec/ui/CamrecApplication.java index 58cfb1ef..c59708fe 100644 --- a/client/src/main/java/ctbrec/ui/CamrecApplication.java +++ b/client/src/main/java/ctbrec/ui/CamrecApplication.java @@ -12,7 +12,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,6 +24,7 @@ import com.squareup.moshi.Types; import ctbrec.Config; import ctbrec.EventBusHolder; import ctbrec.Model; +import ctbrec.OS; import ctbrec.StringUtil; import ctbrec.Version; import ctbrec.io.HttpClient; @@ -37,7 +37,6 @@ import ctbrec.sites.cam4.Cam4; import ctbrec.sites.camsoda.Camsoda; import ctbrec.sites.chaturbate.Chaturbate; import ctbrec.sites.mfc.MyFreeCams; -import eu.hansolo.enzo.notification.Notification; import javafx.application.Application; import javafx.application.HostServices; import javafx.application.Platform; @@ -48,7 +47,6 @@ import javafx.scene.control.Alert; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.image.Image; -import javafx.scene.media.AudioClip; import javafx.scene.paint.Color; import javafx.stage.Stage; import okhttp3.Request; @@ -66,7 +64,6 @@ public class CamrecApplication extends Application { private TabPane rootPane = new TabPane(); private List sites = new ArrayList<>(); public static HttpClient httpClient; - private Notification.Notifier notifier = Notification.Notifier.INSTANCE; @Override public void start(Stage primaryStage) throws Exception { @@ -210,13 +207,13 @@ public class CamrecApplication extends Application { // don't register before 1 minute has passed, because directly after // the start of ctbrec, an event for every online model would be fired, // which is annoying as f - Thread.sleep(TimeUnit.MINUTES.toMillis(1)); + //Thread.sleep(TimeUnit.MINUTES.toMillis(1)); + Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } LOG.debug("Alert System registered"); Platform.runLater(() -> { - Notification.Notifier.setNotificationOwner(primaryStage); EventBusHolder.BUS.register(new Object() { @Subscribe public void modelEvent(Map e) { @@ -227,9 +224,9 @@ public class CamrecApplication extends Application { Model model = (Model) e.get("model"); if (Objects.equals("online", status)) { Platform.runLater(() -> { - notifier.notifyInfo("Model Online", model.getName() + " is now online"); - AudioClip clip = new AudioClip(getClass().getResource("/Oxygen-Im-Highlight-Msg.mp3").toString()); - clip.play(); + String header = "Model Online"; + String msg = model.getDisplayName() + " is now online"; + OS.notification(primaryStage.getTitle(), header, msg); }); } } diff --git a/common/src/main/java/ctbrec/OS.java b/common/src/main/java/ctbrec/OS.java index cc9fbb45..c388e3c1 100644 --- a/common/src/main/java/ctbrec/OS.java +++ b/common/src/main/java/ctbrec/OS.java @@ -1,12 +1,27 @@ package ctbrec; +import java.awt.AWTException; +import java.awt.Image; +import java.awt.SystemTray; +import java.awt.Toolkit; +import java.awt.TrayIcon; +import java.awt.TrayIcon.MessageType; import java.io.File; +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map.Entry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ctbrec.io.StreamRedirectThread; +import javafx.scene.media.AudioClip; + public class OS { + private static final transient Logger LOG = LoggerFactory.getLogger(OS.class); + public static enum TYPE { LINUX, MAC, @@ -72,4 +87,64 @@ public class OS { } return env; } + + public static void notification(String title, String header, String msg) { + if(OS.getOsType() == OS.TYPE.LINUX) { + notifyLinux(title, header, msg); + } else if(OS.getOsType() == OS.TYPE.WINDOWS) { + notifyWindows(title, header, msg); + } else if(OS.getOsType() == OS.TYPE.MAC) { + // TODO find out, if it makes a sound or if we have to play a sound + notifyMac(title, header, msg); + } else { + // unknown system, try systemtray notification anyways + notifySystemTray(title, header, msg); + } + } + + private static void notifyLinux(String title, String header, String msg) { + try { + Process p = Runtime.getRuntime().exec(new String[] { + "notify-send", + "-u", "normal", + "-t", "5000", + "-a", title, + header, + msg.replaceAll("-", "\\\\-").replaceAll("\\s", "\\\\ "), + "--icon=dialog-information" + }); + new Thread(new StreamRedirectThread(p.getInputStream(), System.out)).start(); + new Thread(new StreamRedirectThread(p.getErrorStream(), System.err)).start(); + AudioClip clip = new AudioClip(OS.class.getResource("/Oxygen-Im-Highlight-Msg.mp3").toString()); + clip.play(); + } catch (IOException e1) { + LOG.error("Notification failed", e1); + } + } + + private static void notifyWindows(String title, String header, String msg) { + notifySystemTray(title, header, msg); + } + + private static void notifyMac(String title, String header, String msg) { + notifySystemTray(title, header, msg); + } + + private static void notifySystemTray(String title, String header, String msg) { + if(SystemTray.isSupported()) { + SystemTray tray = SystemTray.getSystemTray(); + Image image = Toolkit.getDefaultToolkit().createImage(OS.class.getResource("/icon64.png")); + TrayIcon trayIcon = new TrayIcon(image, title); + trayIcon.setImageAutoSize(true); + trayIcon.setToolTip(title); + try { + tray.add(trayIcon); + } catch (AWTException e) { + LOG.error("Coulnd't add tray icon", e); + } + trayIcon.displayMessage(header, msg, MessageType.INFO); + } else { + LOG.error("SystemTray notifications not supported by this OS"); + } + } }