diff --git a/CHANGELOG.md b/CHANGELOG.md index f3046481..1bf026f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ======================== * Fixed MVLive recordings once again * Fix: "Check URLs" button stays inactive after the first run -* Fix: recordings for some Cam4 models still didn't start +* ~~Fix: recordings for some Cam4 models still didn't start~~ +* Added menu item to add models in paused state to the "Recording" tab * Added server setting to choose between fast and accurate playlist generation * Some smaller tweaks here and there diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java index 1930253c..1026b708 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java @@ -1,8 +1,25 @@ package ctbrec.ui.tabs; +import static ctbrec.Model.State.*; +import static ctbrec.io.HttpConstants.*; + +import java.io.IOException; +import java.util.Locale; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; + import ctbrec.Config; import ctbrec.Model; import ctbrec.Model.State; @@ -47,18 +64,6 @@ import javafx.scene.text.TextAlignment; import javafx.util.Duration; import okhttp3.Request; import okhttp3.Response; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Locale; -import java.util.Objects; -import java.util.concurrent.*; -import java.util.function.Function; - -import static ctbrec.Model.State.OFFLINE; -import static ctbrec.Model.State.ONLINE; -import static ctbrec.io.HttpConstants.*; public class ThumbCell extends StackPane { @@ -466,7 +471,7 @@ public class ThumbCell extends StackPane { alert.showAndWait(); }); } finally { - setCursor(Cursor.DEFAULT); + Platform.runLater(() -> setCursor(Cursor.DEFAULT)); } }).start(); } @@ -485,7 +490,7 @@ public class ThumbCell extends StackPane { LOG.error(COULDNT_START_STOP_RECORDING, e1); Dialogs.showError(getScene(), COULDNT_START_STOP_RECORDING, "I/O error while starting/stopping the recording: ", e1); } finally { - setCursor(Cursor.DEFAULT); + Platform.runLater(() -> setCursor(Cursor.DEFAULT)); } }).start(); } @@ -520,7 +525,7 @@ public class ThumbCell extends StackPane { Dialogs.showError(getScene(), "Couldn't follow/unfollow model", msg, e1); return false; } finally { - setCursor(Cursor.DEFAULT); + Platform.runLater(() -> setCursor(Cursor.DEFAULT)); } }); } @@ -645,4 +650,9 @@ public class ThumbCell extends StackPane { public BooleanProperty preserveAspectRatioProperty() { return preserveAspectRatio; } + + void addInPausedState() { + model.setSuspended(true); + startStopAction(true); + } } diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java index 90d2e163..bf21b2ae 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java @@ -1,5 +1,31 @@ package ctbrec.ui.tabs; +import static ctbrec.ui.controls.Dialogs.*; + +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import ctbrec.Config; import ctbrec.Model; import ctbrec.event.EventBusHolder; @@ -7,13 +33,21 @@ import ctbrec.recorder.Recorder; import ctbrec.sites.Site; import ctbrec.sites.mfc.MyFreeCamsClient; import ctbrec.sites.mfc.MyFreeCamsModel; -import ctbrec.ui.*; +import ctbrec.ui.AutosizeAlert; +import ctbrec.ui.DesktopIntegration; +import ctbrec.ui.SiteUiFactory; +import ctbrec.ui.TipDialog; +import ctbrec.ui.TokenLabel; import ctbrec.ui.action.OpenRecordingsDir; import ctbrec.ui.controls.FasterVerticalScrollPaneSkin; import ctbrec.ui.controls.SearchBox; import ctbrec.ui.controls.SearchPopover; import ctbrec.ui.controls.SearchPopoverTreeList; -import javafx.animation.*; +import javafx.animation.FadeTransition; +import javafx.animation.Interpolator; +import javafx.animation.ParallelTransition; +import javafx.animation.ScaleTransition; +import javafx.animation.TranslateTransition; import javafx.application.Platform; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; @@ -29,24 +63,33 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.Parent; -import javafx.scene.control.*; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Label; +import javafx.scene.control.MenuItem; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.control.Tab; +import javafx.scene.control.TabPane; +import javafx.scene.control.TextField; +import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; -import javafx.scene.input.*; -import javafx.scene.layout.*; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.ContextMenuEvent; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.Priority; +import javafx.scene.layout.StackPane; import javafx.scene.transform.Transform; import javafx.util.Duration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.text.DecimalFormat; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.ReentrantLock; -import java.util.stream.Collectors; - -import static ctbrec.ui.controls.Dialogs.showError; public class ThumbOverviewTab extends Tab implements TabSelectionListener { private static final Logger LOG = LoggerFactory.getLogger(ThumbOverviewTab.class); @@ -410,6 +453,8 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { } private ContextMenu createContextMenu(ThumbCell cell) { + Model model = cell.getModel(); + boolean modelIsTrackedByRecorder = recorder.isTracked(model); MenuItem openInPlayer = new MenuItem("Open in Player"); openInPlayer.setOnAction(e -> startPlayer(getSelectedThumbCells(cell))); @@ -419,6 +464,13 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { stop.setOnAction(e -> startStopAction(getSelectedThumbCells(cell), false)); MenuItem startStop = recorder.isTracked(cell.getModel()) ? stop : start; + MenuItem addPaused = new MenuItem("Add in paused state"); + addPaused.setOnAction(e -> addPaused(getSelectedThumbCells(cell))); + MenuItem recordUntil = new MenuItem("Record Until"); + recordUntil.setOnAction(e -> LOG.debug("Record Later not implemented, yet")); + MenuItem recordLater = new MenuItem("Record Later"); + recordLater.setOnAction(e -> LOG.debug("Record Later not implemented, yet")); + MenuItem pause = new MenuItem("Pause Recording"); pause.setOnAction(e -> pauseResumeAction(getSelectedThumbCells(cell), true)); MenuItem resume = new MenuItem("Resume Recording"); @@ -433,7 +485,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { MenuItem ignore = new MenuItem("Ignore"); ignore.setOnAction(e -> ignore(getSelectedThumbCells(cell))); - MenuItem refresh = new MenuItem("Refresh"); + MenuItem refresh = new MenuItem("Refresh Overview"); refresh.setOnAction(e -> refresh()); MenuItem openRecDir = new MenuItem("Open recording directory"); @@ -448,10 +500,13 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { contextMenu.setAutoHide(true); contextMenu.setHideOnEscape(true); contextMenu.setAutoFix(true); - contextMenu.getItems().addAll(openInPlayer, startStop); - if(recorder.isTracked(cell.getModel())) { + contextMenu.getItems().addAll(openInPlayer, new SeparatorMenuItem(), startStop); + if(modelIsTrackedByRecorder) { contextMenu.getItems().add(pauseResume); + } else { + contextMenu.getItems().addAll(addPaused/*, recordUntil, recordLater*/); } + contextMenu.getItems().add(new SeparatorMenuItem()); if(site.supportsFollow()) { MenuItem followOrUnFollow = (this instanceof FollowedTab) ? unfollow : follow; followOrUnFollow.setDisable(!site.credentialsAvailable()); @@ -621,6 +676,12 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { } } + private void addPaused(List selection) { + for (ThumbCell thumbCell : selection) { + thumbCell.addInPausedState(); + } + } + private void pauseResumeAction(List selection, boolean pause) { for (ThumbCell thumbCell : selection) { thumbCell.pauseResumeAction(pause);