diff --git a/client/src/main/java/ctbrec/ui/menu/ModelMenuContributor.java b/client/src/main/java/ctbrec/ui/menu/ModelMenuContributor.java index ffa1b218..86649713 100644 --- a/client/src/main/java/ctbrec/ui/menu/ModelMenuContributor.java +++ b/client/src/main/java/ctbrec/ui/menu/ModelMenuContributor.java @@ -14,14 +14,17 @@ import ctbrec.Model; import ctbrec.ModelGroup; import ctbrec.recorder.Recorder; import ctbrec.ui.AutosizeAlert; +import ctbrec.ui.DesktopIntegration; import ctbrec.ui.SiteUiFactory; import ctbrec.ui.StreamSourceSelectionDialog; import ctbrec.ui.action.AddToGroupAction; import ctbrec.ui.action.IgnoreModelsAction; +import ctbrec.ui.action.OpenRecordingsDir; import ctbrec.ui.action.PlayAction; import ctbrec.ui.action.SetStopDateAction; import ctbrec.ui.action.StartRecordingAction; import ctbrec.ui.action.StopRecordingAction; +import ctbrec.ui.action.TipAction; import ctbrec.ui.action.TriConsumer; import ctbrec.ui.controls.Dialogs; import ctbrec.ui.tabs.FollowedTab; @@ -32,6 +35,8 @@ import javafx.scene.control.Alert; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; import javafx.scene.control.SeparatorMenuItem; +import javafx.scene.input.Clipboard; +import javafx.scene.input.ClipboardContent; public class ModelMenuContributor { @@ -83,6 +88,8 @@ public class ModelMenuContributor { followCallback = Optional.ofNullable(followCallback).orElse((m, f, s) -> {}); ignoreCallback = Optional.ofNullable(ignoreCallback).orElse(m -> {}); addOpenInPlayer(menu, selectedModels); + addOpenInBrowser(menu, selectedModels); + addCopyUrl(menu, selectedModels); menu.getItems().add(new SeparatorMenuItem()); addStartOrStop(menu, selectedModels); addStartRecordingWithTimeLimit(menu, selectedModels); @@ -92,7 +99,53 @@ public class ModelMenuContributor { addGroupMenu(menu, selectedModels); menu.getItems().add(new SeparatorMenuItem()); addFollowUnfollow(menu, selectedModels); + addSendTip(menu, selectedModels); addIgnore(menu, selectedModels); + addOpenRecDir(menu, selectedModels); + } + + private void addOpenRecDir(ContextMenu menu, List selectedModels) { + if (selectedModels == null || selectedModels.isEmpty()) { + return; + } + var model = selectedModels.get(0); + var openRecDir = new MenuItem("Open recording directory"); + openRecDir.setOnAction(e -> new OpenRecordingsDir(source, model).execute()); + menu.getItems().add(openRecDir); + } + + private void addOpenInBrowser(ContextMenu menu, List selectedModels) { + var openInBrowser = new MenuItem("Open in browser"); + openInBrowser.setOnAction(e -> selectedModels.forEach(model -> DesktopIntegration.open(model.getUrl()))); + menu.getItems().add(openInBrowser); + } + + private void addCopyUrl(ContextMenu menu, List selectedModels) { + if (selectedModels == null || selectedModels.isEmpty()) { + return; + } + var model = selectedModels.get(0); + var copyUrl = new MenuItem("Copy URL"); + copyUrl.setOnAction(e -> { + final var content = new ClipboardContent(); + content.putString(model.getUrl()); + Clipboard.getSystemClipboard().setContent(content); + }); + menu.getItems().add(copyUrl); + } + + private void addSendTip(ContextMenu menu, List selectedModels) { + if (selectedModels == null || selectedModels.isEmpty()) { + return; + } + var model = selectedModels.get(0); + var site = model.getSite(); + if (site.supportsTips()) { + var sendTip = new MenuItem("Send Tip"); + sendTip.setOnAction(e -> new TipAction(model, source).execute()); + sendTip.setDisable(!site.credentialsAvailable()); + menu.getItems().add(sendTip); + } } private void addIgnore(ContextMenu menu, List selectedModels) { diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java index 50fa6fdb..6de06e3e 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbOverviewTab.java @@ -33,8 +33,6 @@ import ctbrec.ui.AutosizeAlert; import ctbrec.ui.DesktopIntegration; import ctbrec.ui.SiteUiFactory; import ctbrec.ui.TokenLabel; -import ctbrec.ui.action.OpenRecordingsDir; -import ctbrec.ui.action.TipAction; import ctbrec.ui.controls.CustomMouseBehaviorContextMenu; import ctbrec.ui.controls.FasterVerticalScrollPaneSkin; import ctbrec.ui.controls.SearchBox; @@ -74,8 +72,6 @@ import javafx.scene.control.Tab; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; -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; @@ -455,26 +451,14 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { } private ContextMenu createContextMenu(ThumbCell cell) { - var model = cell.getModel(); - var selectedModels = getSelectedThumbCells(cell).stream().map(ThumbCell::getModel).collect(Collectors.toList()); - - var refresh = new MenuItem("Refresh Overview"); - refresh.setOnAction(e -> refresh()); - - var openRecDir = new MenuItem("Open recording directory"); - openRecDir.setOnAction(e -> new OpenRecordingsDir(cell, model).execute()); - - var copyUrl = createCopyUrlMenuItem(cell); - var openInBrowser = createOpenInBrowser(cell); - var sendTip = createTipMenuItem(cell); - - configureItemsForSelection(cell, copyUrl, sendTip); + removeSelectionIfNeeded(cell); ContextMenu contextMenu = new CustomMouseBehaviorContextMenu(); contextMenu.setAutoHide(true); contextMenu.setHideOnEscape(true); contextMenu.setAutoFix(true); + var selectedModels = getSelectedThumbCells(cell).stream().map(ThumbCell::getModel).collect(Collectors.toList()); ModelMenuContributor.newContributor(getTabPane(), Config.getInstance(), recorder) .withStartStopCallback(m -> { getTabPane().setCursor(Cursor.DEFAULT); @@ -494,10 +478,10 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { })) .contributeToMenu(selectedModels, contextMenu); - if (site.supportsTips()) { - contextMenu.getItems().add(sendTip); - } - contextMenu.getItems().addAll(copyUrl, openInBrowser, refresh, openRecDir); + var refresh = new MenuItem("Refresh Overview"); + refresh.setOnAction(e -> refresh()); + contextMenu.getItems().addAll(refresh); + var model = cell.getModel(); if (model instanceof MyFreeCamsModel && Objects.equals(System.getenv("CTBREC_DEV"), "1")) { var debug = new MenuItem("debug"); debug.setOnAction(e -> MyFreeCamsClient.getInstance().getSessionState(model)); @@ -531,40 +515,12 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { * check, if other cells are selected, too. in that case, we have to disable menu items, which make sense only for single selections. but only do that, if * the popup has been triggered on a selected cell. otherwise remove the selection and show the normal menu */ - private void configureItemsForSelection(ThumbCell cell, MenuItem copyUrl, MenuItem sendTip) { - if (selectedThumbCells.size() > 1 || selectedThumbCells.size() == 1 && selectedThumbCells.get(0) != cell) { - if (cell.isSelected()) { - copyUrl.setDisable(true); - sendTip.setDisable(true); - } else { - removeSelection(); - } + private void removeSelectionIfNeeded(ThumbCell cell) { + if ((selectedThumbCells.size() > 1 || selectedThumbCells.size() == 1 && selectedThumbCells.get(0) != cell) && !cell.isSelected()) { + removeSelection(); } } - private MenuItem createOpenInBrowser(ThumbCell cell) { - var openInBrowser = new MenuItem("Open in browser"); - openInBrowser.setOnAction(e -> DesktopIntegration.open(cell.getModel().getUrl())); - return openInBrowser; - } - - private MenuItem createCopyUrlMenuItem(ThumbCell cell) { - var copyUrl = new MenuItem("Copy URL"); - copyUrl.setOnAction(e -> { - final var content = new ClipboardContent(); - content.putString(cell.getModel().getUrl()); - Clipboard.getSystemClipboard().setContent(content); - }); - return copyUrl; - } - - private MenuItem createTipMenuItem(ThumbCell cell) { - var sendTip = new MenuItem("Send Tip"); - sendTip.setOnAction(e -> new TipAction(cell.getModel(), cell).execute()); - sendTip.setDisable(!site.credentialsAvailable()); - return sendTip; - } - private List getSelectedThumbCells(ThumbCell cell) { if (selectedThumbCells.isEmpty()) { return Collections.singletonList(cell);