mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-04-22 07:29:05 -04:00
Rework start on init stores
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.comp.CompStructure;
|
||||
import io.xpipe.app.comp.SimpleCompStructure;
|
||||
import io.xpipe.app.comp.augment.ContextMenuAugment;
|
||||
import io.xpipe.app.platform.ContextMenuHelper;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.css.Size;
|
||||
import javafx.css.SizeUnits;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.MenuItem;
|
||||
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DropdownComp extends Comp<CompStructure<Button>> {
|
||||
|
||||
private final List<Comp<?>> items;
|
||||
|
||||
public DropdownComp(List<Comp<?>> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<Button> createBase() {
|
||||
var cm = ContextMenuHelper.create();
|
||||
cm.getItems()
|
||||
.setAll(items.stream()
|
||||
.map(comp -> {
|
||||
return new MenuItem(null, comp.createRegion());
|
||||
})
|
||||
.toList());
|
||||
|
||||
Button button = (Button) new ButtonComp(null, () -> {})
|
||||
.apply(new ContextMenuAugment<>(e -> true, null, () -> {
|
||||
return cm;
|
||||
}))
|
||||
.createRegion();
|
||||
|
||||
List<? extends ObservableValue<Boolean>> l = cm.getItems().stream()
|
||||
.map(menuItem -> menuItem.getGraphic().visibleProperty())
|
||||
.toList();
|
||||
button.visibleProperty()
|
||||
.bind(Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return l.stream().anyMatch(booleanObservableValue -> booleanObservableValue.getValue());
|
||||
},
|
||||
l.toArray(ObservableValue[]::new)));
|
||||
|
||||
var graphic = new FontIcon("mdi2c-chevron-double-down");
|
||||
button.fontProperty().subscribe(c -> {
|
||||
graphic.setIconSize((int) new Size(c.getSize(), SizeUnits.PT).pixels());
|
||||
});
|
||||
|
||||
button.setGraphic(graphic);
|
||||
button.getStyleClass().add("dropdown-comp");
|
||||
button.setAccessibleText("Dropdown actions");
|
||||
|
||||
return new SimpleCompStructure<>(button);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package io.xpipe.app.core;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import io.xpipe.app.issue.ErrorEventFactory;
|
||||
import io.xpipe.core.JacksonMapper;
|
||||
|
||||
@@ -45,8 +47,12 @@ public class AppCache {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getNonNull(String key, Class<?> type, Supplier<T> notPresent) {
|
||||
return getNonNull(key, TypeFactory.defaultInstance().constructType(type), notPresent);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T getNonNull(String key, JavaType type, Supplier<T> notPresent) {
|
||||
var path = getPath(key);
|
||||
if (Files.exists(path)) {
|
||||
try {
|
||||
@@ -58,7 +64,7 @@ public class AppCache {
|
||||
}
|
||||
|
||||
var r = (T) JacksonMapper.getDefault().treeToValue(tree, type);
|
||||
if (r == null || !type.isAssignableFrom(r.getClass())) {
|
||||
if (r == null) {
|
||||
FileUtils.deleteQuietly(path.toFile());
|
||||
return notPresent.get();
|
||||
} else {
|
||||
@@ -75,6 +81,7 @@ public class AppCache {
|
||||
return notPresent.get();
|
||||
}
|
||||
|
||||
|
||||
public static boolean getBoolean(String key, boolean notPresent) {
|
||||
var path = getPath(key);
|
||||
if (Files.exists(path)) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import io.xpipe.app.core.window.AppMainWindow;
|
||||
import io.xpipe.app.core.window.AppWindowTitle;
|
||||
import io.xpipe.app.ext.DataStoreProviders;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.ext.StartOnInitStore;
|
||||
import io.xpipe.app.hub.comp.StoreViewState;
|
||||
import io.xpipe.app.icon.SystemIconManager;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
@@ -162,6 +163,7 @@ public class BaseMode extends OperationMode {
|
||||
|
||||
ActionProvider.initProviders();
|
||||
DataStoreProviders.init();
|
||||
StartOnInitStore.init();
|
||||
|
||||
AppConfigurationDialog.showIfNeeded();
|
||||
AppGnomeScaleDialog.showIfNeeded();
|
||||
|
||||
65
app/src/main/java/io/xpipe/app/ext/StartOnInitStore.java
Normal file
65
app/src/main/java/io/xpipe/app/ext/StartOnInitStore.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package io.xpipe.app.ext;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.icon.SystemIconSource;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.app.util.ThreadHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface StartOnInitStore extends SelfReferentialStore, DataStore {
|
||||
|
||||
static void init() {
|
||||
ThreadHelper.runFailableAsync(() -> {
|
||||
var enabled = getEnabledStores();
|
||||
for (DataStoreEntry e : DataStorage.get().getStoreEntries()) {
|
||||
if (e.getStore() instanceof StartOnInitStore i && e.getValidity().isUsable() && enabled.contains(i.getSelfEntry().ref())) {
|
||||
i.startOnInit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static Set<DataStoreEntryRef<?>> getEnabledStores() {
|
||||
synchronized (StartOnInitStore.class) {
|
||||
var type = TypeFactory.defaultInstance().constructType(new TypeReference<Set<DataStoreEntryRef<?>>>() {});
|
||||
Set<DataStoreEntryRef<?>> cached = AppCache.getNonNull("startOnInitStores", type, () -> Set.of());
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
static void setEnabledStores(Set<DataStoreEntryRef<?>> stores) {
|
||||
synchronized (StartOnInitStore.class) {
|
||||
AppCache.update("startOnInitStores", stores);
|
||||
}
|
||||
}
|
||||
|
||||
default boolean isEnabled() {
|
||||
return getEnabledStores().contains(getSelfEntry().ref());
|
||||
}
|
||||
|
||||
default void enable() {
|
||||
synchronized (StartOnInitStore.class) {
|
||||
var enabled = new HashSet<>(getEnabledStores());
|
||||
enabled.add(getSelfEntry().ref());
|
||||
setEnabledStores(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
default void disable() {
|
||||
synchronized (StartOnInitStore.class) {
|
||||
var enabled = new HashSet<>(getEnabledStores());
|
||||
enabled.remove(getSelfEntry().ref());
|
||||
setEnabledStores(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void startOnInit() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package io.xpipe.app.hub.action.impl;
|
||||
|
||||
import io.xpipe.app.browser.BrowserFullSessionModel;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppLayoutModel;
|
||||
import io.xpipe.app.ext.StartOnInitStore;
|
||||
import io.xpipe.app.ext.ProcessControlProvider;
|
||||
import io.xpipe.app.hub.action.HubLeafProvider;
|
||||
import io.xpipe.app.hub.action.StoreAction;
|
||||
import io.xpipe.app.hub.action.StoreActionCategory;
|
||||
import io.xpipe.app.platform.LabelGraphic;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
import io.xpipe.core.FilePath;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
public class StartOnInitHubLeafProvider implements HubLeafProvider<StartOnInitStore> {
|
||||
|
||||
@Override
|
||||
public Action createAction(DataStoreEntryRef<StartOnInitStore> ref) {
|
||||
return Action.builder().ref(ref).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoreActionCategory getCategory() {
|
||||
return StoreActionCategory.CUSTOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObservableValue<String> getName(DataStoreEntryRef<StartOnInitStore> store) {
|
||||
return AppI18n.observable(store.getStore().isEnabled() ? "disableStartOnInit" : "enableStartOnInit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LabelGraphic getIcon(DataStoreEntryRef<StartOnInitStore> store) {
|
||||
return new LabelGraphic.IconGraphic(store.getStore().isEnabled() ? "mdi2t-toggle-switch-off-outline" : "mdi2t-toggle-switch-outline");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<StartOnInitStore> getApplicableClass() {
|
||||
return StartOnInitStore.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "toggleStartOnInit";
|
||||
}
|
||||
|
||||
@Jacksonized
|
||||
@SuperBuilder
|
||||
public static class Action extends StoreAction<StartOnInitStore> {
|
||||
|
||||
@Override
|
||||
public void executeImpl() throws Exception {
|
||||
if (ref.getStore().isEnabled()) {
|
||||
ref.getStore().disable();
|
||||
} else {
|
||||
ref.getStore().enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,7 @@ open module io.xpipe.app {
|
||||
OpenDirectoryMenuProvider,
|
||||
OpenDirectoryInNewTabMenuProvider,
|
||||
ScanHubLeafProvider,
|
||||
StartOnInitHubLeafProvider,
|
||||
BrowseHubLeafProvider,
|
||||
RefreshActionProvider,
|
||||
ToggleActionProvider,
|
||||
|
||||
2
lang/strings/translations_en.properties
generated
2
lang/strings/translations_en.properties
generated
@@ -1629,3 +1629,5 @@ enableTerminalStartupBell=Enable terminal startup bell
|
||||
enableTerminalStartupBellDescription=Play a beep/bell command in a newly terminal session. If your terminal emulator supports bells, this can be used to make identifying newly launched terminal instances easier.
|
||||
rdpSmartSizing=Enable smart sizing
|
||||
rdpSmartSizingDescription=When enabled, mstsc will scale down the desktop size if the window is too small to display it in its full resolution. The aspect ratio of the desktop is preserved when scaled down.
|
||||
disableStartOnInit=Disable automatic startup
|
||||
enableStartOnInit=Enable automatic startup
|
||||
|
||||
Reference in New Issue
Block a user