diff --git a/client/src/main/java/ctbrec/ui/Player.java b/client/src/main/java/ctbrec/ui/Player.java index 593e379b..f9c0d9fd 100644 --- a/client/src/main/java/ctbrec/ui/Player.java +++ b/client/src/main/java/ctbrec/ui/Player.java @@ -23,7 +23,7 @@ public class Player { private static final transient Logger LOG = LoggerFactory.getLogger(Player.class); private static PlayerThread playerThread; - public static void play(String url) { + public static boolean play(String url) { boolean singlePlayer = Config.getInstance().getSettings().singlePlayer; try { if (singlePlayer && playerThread != null && playerThread.isRunning()) { @@ -31,12 +31,14 @@ public class Player { } playerThread = new PlayerThread(url); + return true; } catch (Exception e1) { LOG.error("Couldn't start player", e1); + return false; } } - public static void play(Recording rec) { + public static boolean play(Recording rec) { boolean singlePlayer = Config.getInstance().getSettings().singlePlayer; try { if (singlePlayer && playerThread != null && playerThread.isRunning()) { @@ -44,12 +46,14 @@ public class Player { } playerThread = new PlayerThread(rec); + return true; } catch (Exception e1) { LOG.error("Couldn't start player", e1); + return false; } } - public static void play(Model model) { + public static boolean play(Model model) { try { if(model.isOnline(true)) { boolean singlePlayer = Config.getInstance().getSettings().singlePlayer; @@ -60,7 +64,7 @@ public class Player { Collections.sort(sources); StreamSource best = sources.get(sources.size()-1); LOG.debug("Playing {}", best.getMediaPlaylistUrl()); - Player.play(best.getMediaPlaylistUrl()); + return Player.play(best.getMediaPlaylistUrl()); } else { Platform.runLater(() -> { Alert alert = new AutosizeAlert(Alert.AlertType.INFORMATION); @@ -68,6 +72,7 @@ public class Player { alert.setHeaderText("Room is currently not public"); alert.showAndWait(); }); + return false; } } catch (Exception e1) { LOG.error("Couldn't get stream information for model {}", model, e1); @@ -78,6 +83,7 @@ public class Player { alert.setContentText(e1.getLocalizedMessage()); alert.showAndWait(); }); + return false; } } diff --git a/client/src/main/java/ctbrec/ui/RecordedModelsTab.java b/client/src/main/java/ctbrec/ui/RecordedModelsTab.java index 5874f8c2..e633a97b 100644 --- a/client/src/main/java/ctbrec/ui/RecordedModelsTab.java +++ b/client/src/main/java/ctbrec/ui/RecordedModelsTab.java @@ -25,6 +25,7 @@ import ctbrec.Recording; import ctbrec.recorder.Recorder; import ctbrec.sites.Site; import ctbrec.ui.autofilltextbox.AutoFillTextField; +import ctbrec.ui.controls.Toast; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.collections.ObservableList; @@ -328,8 +329,13 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener { private void openInPlayer(JavaFxModel selectedModel) { table.setCursor(Cursor.WAIT); new Thread(() -> { - Player.play(selectedModel); - Platform.runLater(() -> table.setCursor(Cursor.DEFAULT)); + boolean started = Player.play(selectedModel); + Platform.runLater(() -> { + if(started) { + Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500); + } + table.setCursor(Cursor.DEFAULT); + }); }).start(); } diff --git a/client/src/main/java/ctbrec/ui/RecordingsTab.java b/client/src/main/java/ctbrec/ui/RecordingsTab.java index b1f3d47b..5605dbee 100644 --- a/client/src/main/java/ctbrec/ui/RecordingsTab.java +++ b/client/src/main/java/ctbrec/ui/RecordingsTab.java @@ -33,6 +33,7 @@ import ctbrec.Recording.STATUS; import ctbrec.recorder.Recorder; import ctbrec.recorder.download.MergedHlsDownload; import ctbrec.sites.Site; +import ctbrec.ui.controls.Toast; import javafx.application.Platform; import javafx.beans.property.SimpleObjectProperty; import javafx.collections.FXCollections; @@ -483,7 +484,10 @@ public class RecordingsTab extends Tab implements TabSelectionListener { new Thread() { @Override public void run() { - Player.play(recording); + boolean started = Player.play(recording); + if(started) { + Platform.runLater(() -> Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500)); + } } }.start(); } else { @@ -492,7 +496,10 @@ public class RecordingsTab extends Tab implements TabSelectionListener { new Thread() { @Override public void run() { - Player.play(url); + boolean started = Player.play(url); + if(started) { + Platform.runLater(() -> Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500)); + } } }.start(); } diff --git a/client/src/main/java/ctbrec/ui/ThumbCell.java b/client/src/main/java/ctbrec/ui/ThumbCell.java index 8b563344..6d5a03f5 100644 --- a/client/src/main/java/ctbrec/ui/ThumbCell.java +++ b/client/src/main/java/ctbrec/ui/ThumbCell.java @@ -15,6 +15,7 @@ import com.iheartradio.m3u8.ParseException; import ctbrec.Config; import ctbrec.Model; import ctbrec.recorder.Recorder; +import ctbrec.ui.controls.Toast; import javafx.animation.FadeTransition; import javafx.animation.FillTransition; import javafx.animation.ParallelTransition; @@ -302,8 +303,13 @@ public class ThumbCell extends StackPane { void startPlayer() { setCursor(Cursor.WAIT); new Thread(() -> { - Player.play(model); - Platform.runLater(() -> setCursor(Cursor.DEFAULT)); + boolean started = Player.play(model); + Platform.runLater(() -> { + setCursor(Cursor.DEFAULT); + if (started) { + Toast.makeText(getScene(), "Starting Player", 2000, 500, 500); + } + }); }).start(); } diff --git a/client/src/main/java/ctbrec/ui/controls/Toast.java b/client/src/main/java/ctbrec/ui/controls/Toast.java new file mode 100644 index 00000000..bde087ce --- /dev/null +++ b/client/src/main/java/ctbrec/ui/controls/Toast.java @@ -0,0 +1,53 @@ +package ctbrec.ui.controls; + +import javafx.animation.KeyFrame; +import javafx.animation.KeyValue; +import javafx.animation.Timeline; +import javafx.scene.Scene; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.scene.text.Text; +import javafx.stage.Stage; +import javafx.stage.StageStyle; +import javafx.util.Duration; + +public final class Toast { + public static void makeText(Scene owner, String toastMsg, int toastDelay, int fadeInDelay, int fadeOutDelay) { + Stage toastStage = new Stage(); + toastStage.initOwner(owner.getWindow()); + toastStage.setResizable(false); + toastStage.initStyle(StageStyle.TRANSPARENT); + + Text text = new Text(toastMsg); + text.setFont(Font.font(30)); + text.setFill(Color.WHITE); + + StackPane root = new StackPane(text); + root.setStyle("-fx-background-radius: 20; -fx-background-color: rgba(0, 0, 0, 0.4); -fx-padding: 50px;"); + root.setOpacity(0); + + Scene scene = new Scene(root); + scene.setFill(Color.TRANSPARENT); + toastStage.setScene(scene); + toastStage.show(); + + Timeline fadeInTimeline = new Timeline(); + KeyFrame fadeInKey1 = new KeyFrame(Duration.millis(fadeInDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 1)); + fadeInTimeline.getKeyFrames().add(fadeInKey1); + fadeInTimeline.setOnFinished((ae) -> { + new Thread(() -> { + try { + Thread.sleep(toastDelay); + } catch (InterruptedException e) { + } + Timeline fadeOutTimeline = new Timeline(); + KeyFrame fadeOutKey1 = new KeyFrame(Duration.millis(fadeOutDelay), new KeyValue(toastStage.getScene().getRoot().opacityProperty(), 0)); + fadeOutTimeline.getKeyFrames().add(fadeOutKey1); + fadeOutTimeline.setOnFinished((aeb) -> toastStage.close()); + fadeOutTimeline.play(); + }).start(); + }); + fadeInTimeline.play(); + } +} \ No newline at end of file