mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-22 07:30:24 +00:00
Improve detection for initial launch
This commit is contained in:
parent
4152d6e1db
commit
e9af3d5bc7
9 changed files with 55 additions and 31 deletions
|
@ -3,6 +3,7 @@ package io.xpipe.app.comp.storage.store;
|
||||||
import atlantafx.base.theme.Styles;
|
import atlantafx.base.theme.Styles;
|
||||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||||
import io.xpipe.app.comp.base.MultiContentComp;
|
import io.xpipe.app.comp.base.MultiContentComp;
|
||||||
|
import io.xpipe.app.core.AppState;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
|
@ -29,13 +30,17 @@ public class StoreEntryListComp extends SimpleComp {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
|
var initialCount = StoreViewState.get().getAllEntries().size();
|
||||||
|
var showIntro = Bindings.createBooleanBinding(() -> {
|
||||||
|
return initialCount == StoreViewState.get().getAllEntries().size() && AppState.get().isInitialLaunch();
|
||||||
|
}, StoreViewState.get().getAllEntries());
|
||||||
var map = new LinkedHashMap<Comp<?>, ObservableBooleanValue>();
|
var map = new LinkedHashMap<Comp<?>, ObservableBooleanValue>();
|
||||||
map.put(
|
map.put(
|
||||||
createList(),
|
createList(),
|
||||||
BindingsHelper.persist(
|
BindingsHelper.persist(
|
||||||
Bindings.not(Bindings.isEmpty(StoreViewState.get().getShownEntries()))));
|
Bindings.not(Bindings.isEmpty(StoreViewState.get().getShownEntries()))));
|
||||||
|
|
||||||
map.put(new StoreIntroComp(), StoreViewState.get().emptyProperty());
|
map.put(new StoreIntroComp(), showIntro);
|
||||||
map.put(
|
map.put(
|
||||||
new StoreNotFoundComp(),
|
new StoreNotFoundComp(),
|
||||||
BindingsHelper.persist(Bindings.and(
|
BindingsHelper.persist(Bindings.and(
|
||||||
|
|
|
@ -6,6 +6,7 @@ import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.util.Hyperlinks;
|
import io.xpipe.app.util.Hyperlinks;
|
||||||
import io.xpipe.app.util.ScanAlert;
|
import io.xpipe.app.util.ScanAlert;
|
||||||
import io.xpipe.core.impl.LocalStore;
|
import io.xpipe.core.impl.LocalStore;
|
||||||
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
|
@ -70,8 +71,9 @@ public class StoreIntroComp extends SimpleComp {
|
||||||
v.getStyleClass().add("intro");
|
v.getStyleClass().add("intro");
|
||||||
|
|
||||||
var sp = new StackPane(v);
|
var sp = new StackPane(v);
|
||||||
sp.setAlignment(Pos.CENTER);
|
sp.setAlignment(Pos.BOTTOM_CENTER);
|
||||||
sp.setPickOnBounds(false);
|
sp.setPickOnBounds(false);
|
||||||
|
sp.setPadding(new Insets(0, 0, 40, 0));
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,7 @@ import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.storage.DataStoreEntry;
|
import io.xpipe.app.storage.DataStoreEntry;
|
||||||
import io.xpipe.app.storage.StorageListener;
|
import io.xpipe.app.storage.StorageListener;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
|
||||||
import javafx.beans.property.SimpleObjectProperty;
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.value.ObservableBooleanValue;
|
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
|
@ -29,10 +27,6 @@ public class StoreViewState {
|
||||||
private final ObservableList<StoreEntryWrapper> shownEntries =
|
private final ObservableList<StoreEntryWrapper> shownEntries =
|
||||||
FXCollections.observableList(new CopyOnWriteArrayList<>());
|
FXCollections.observableList(new CopyOnWriteArrayList<>());
|
||||||
|
|
||||||
private final ObservableBooleanValue empty = Bindings.createBooleanBinding(() -> {
|
|
||||||
return allEntries.stream().allMatch(storeEntryWrapper -> !storeEntryWrapper.getEntry().getConfiguration().isRenameable());
|
|
||||||
}, allEntries);
|
|
||||||
|
|
||||||
private StoreViewState() {
|
private StoreViewState() {
|
||||||
try {
|
try {
|
||||||
addStorageGroupListeners();
|
addStorageGroupListeners();
|
||||||
|
@ -107,12 +101,4 @@ public class StoreViewState {
|
||||||
public ObservableList<StoreEntryWrapper> getShownEntries() {
|
public ObservableList<StoreEntryWrapper> getShownEntries() {
|
||||||
return shownEntries;
|
return shownEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return empty.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObservableBooleanValue emptyProperty() {
|
|
||||||
return empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class AppCache {
|
public class AppCache {
|
||||||
|
@ -18,12 +17,6 @@ public class AppCache {
|
||||||
return Optional.ofNullable(get(key, type, () -> null));
|
return Optional.ofNullable(get(key, type, () -> null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UUID getCachedUserId() {
|
|
||||||
var id = get("userId", UUID.class, UUID::randomUUID);
|
|
||||||
update("userId", id);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Path getBasePath() {
|
private static Path getBasePath() {
|
||||||
return AppProperties.get().getDataDir().resolve("cache");
|
return AppProperties.get().getDataDir().resolve("cache");
|
||||||
}
|
}
|
||||||
|
@ -68,7 +61,7 @@ public class AppCache {
|
||||||
FileUtils.deleteQuietly(path.toFile());
|
FileUtils.deleteQuietly(path.toFile());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return notPresent.get();
|
return notPresent != null ? notPresent.get() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> void update(String key, T val) {
|
public static <T> void update(String key, T val) {
|
||||||
|
|
38
app/src/main/java/io/xpipe/app/core/AppState.java
Normal file
38
app/src/main/java/io/xpipe/app/core/AppState.java
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package io.xpipe.app.core;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class AppState {
|
||||||
|
|
||||||
|
private static AppState INSTANCE;
|
||||||
|
|
||||||
|
UUID userId;
|
||||||
|
boolean initialLaunch;
|
||||||
|
|
||||||
|
public AppState() {
|
||||||
|
UUID id = AppCache.get("userId", UUID.class, null);
|
||||||
|
if (id == null) {
|
||||||
|
initialLaunch = AppCache.getIfPresent("lastBuild", String.class).isEmpty();
|
||||||
|
userId = UUID.randomUUID();
|
||||||
|
AppCache.update("userId", userId);
|
||||||
|
} else {
|
||||||
|
userId = id;
|
||||||
|
initialLaunch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
if (INSTANCE != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANCE = new AppState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AppState get() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,6 @@
|
||||||
package io.xpipe.app.core.mode;
|
package io.xpipe.app.core.mode;
|
||||||
|
|
||||||
import io.xpipe.app.core.App;
|
import io.xpipe.app.core.*;
|
||||||
import io.xpipe.app.core.AppChecks;
|
|
||||||
import io.xpipe.app.core.AppLogs;
|
|
||||||
import io.xpipe.app.core.AppProperties;
|
|
||||||
import io.xpipe.app.issue.ErrorEvent;
|
import io.xpipe.app.issue.ErrorEvent;
|
||||||
import io.xpipe.app.issue.ErrorHandler;
|
import io.xpipe.app.issue.ErrorHandler;
|
||||||
import io.xpipe.app.issue.TrackEvent;
|
import io.xpipe.app.issue.TrackEvent;
|
||||||
|
@ -87,6 +84,7 @@ public abstract class OperationMode {
|
||||||
|
|
||||||
TrackEvent.info("mode", "Initial setup");
|
TrackEvent.info("mode", "Initial setup");
|
||||||
AppProperties.init();
|
AppProperties.init();
|
||||||
|
AppState.init();
|
||||||
XPipeSession.init(AppProperties.get().getBuildUuid());
|
XPipeSession.init(AppProperties.get().getBuildUuid());
|
||||||
AppChecks.checkDirectoryPermissions();
|
AppChecks.checkDirectoryPermissions();
|
||||||
AppLogs.init();
|
AppLogs.init();
|
||||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.issue;
|
||||||
import io.sentry.*;
|
import io.sentry.*;
|
||||||
import io.sentry.protocol.SentryId;
|
import io.sentry.protocol.SentryId;
|
||||||
import io.sentry.protocol.User;
|
import io.sentry.protocol.User;
|
||||||
import io.xpipe.app.core.AppCache;
|
|
||||||
import io.xpipe.app.core.AppProperties;
|
import io.xpipe.app.core.AppProperties;
|
||||||
|
import io.xpipe.app.core.AppState;
|
||||||
import io.xpipe.app.core.mode.OperationMode;
|
import io.xpipe.app.core.mode.OperationMode;
|
||||||
import io.xpipe.app.prefs.AppPrefs;
|
import io.xpipe.app.prefs.AppPrefs;
|
||||||
import io.xpipe.app.update.XPipeDistributionType;
|
import io.xpipe.app.update.XPipeDistributionType;
|
||||||
|
@ -28,6 +28,7 @@ public class SentryErrorHandler implements ErrorHandler {
|
||||||
// Assume that this object is wrapped by a synchronous error handler
|
// Assume that this object is wrapped by a synchronous error handler
|
||||||
if (!init) {
|
if (!init) {
|
||||||
AppProperties.init();
|
AppProperties.init();
|
||||||
|
AppState.init();
|
||||||
if (AppProperties.get().getSentryUrl() != null) {
|
if (AppProperties.get().getSentryUrl() != null) {
|
||||||
Sentry.init(options -> {
|
Sentry.init(options -> {
|
||||||
options.setDsn(AppProperties.get().getSentryUrl());
|
options.setDsn(AppProperties.get().getSentryUrl());
|
||||||
|
@ -110,7 +111,7 @@ public class SentryErrorHandler implements ErrorHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = new User();
|
var user = new User();
|
||||||
user.setId(AppCache.getCachedUserId().toString());
|
user.setId(AppState.get().getUserId().toString());
|
||||||
s.setUser(user);
|
s.setUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class TerminalErrorHandler implements ErrorHandler {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AppProperties.init();
|
AppProperties.init();
|
||||||
|
AppState.init();
|
||||||
AppExtensionManager.init(false);
|
AppExtensionManager.init(false);
|
||||||
AppI18n.init();
|
AppI18n.init();
|
||||||
AppStyle.init();
|
AppStyle.init();
|
||||||
|
|
|
@ -16,6 +16,6 @@ storeIntroTitle=Adding Connections
|
||||||
storeIntroDescription=Connect to remote systems, databases, and more.
|
storeIntroDescription=Connect to remote systems, databases, and more.
|
||||||
storeStreamDescription=Stream connections produce raw byte data\nthat can be used to construct data sources from.
|
storeStreamDescription=Stream connections produce raw byte data\nthat can be used to construct data sources from.
|
||||||
storeMachineDescription=You can quickly search for available remote connections automatically.\nAlternatively, you can also of course add them manually.
|
storeMachineDescription=You can quickly search for available remote connections automatically.\nAlternatively, you can also of course add them manually.
|
||||||
detectConnections=Detect connections
|
detectConnections=Search for connections
|
||||||
storeDatabaseDescription=Database connections allow you to connect to\na database server and interact with its contained data.
|
storeDatabaseDescription=Database connections allow you to connect to\na database server and interact with its contained data.
|
||||||
storeDocumentation=In case you prefer a more structured approach to\nfamiliarizing yourself with X-Pipe, check out the documentation:
|
storeDocumentation=In case you prefer a more structured approach to\nfamiliarizing yourself with X-Pipe, check out the documentation:
|
||||||
|
|
Loading…
Reference in a new issue