mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +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 io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.comp.base.MultiContentComp;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
|
@ -29,13 +30,17 @@ public class StoreEntryListComp extends SimpleComp {
|
|||
|
||||
@Override
|
||||
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>();
|
||||
map.put(
|
||||
createList(),
|
||||
BindingsHelper.persist(
|
||||
Bindings.not(Bindings.isEmpty(StoreViewState.get().getShownEntries()))));
|
||||
|
||||
map.put(new StoreIntroComp(), StoreViewState.get().emptyProperty());
|
||||
map.put(new StoreIntroComp(), showIntro);
|
||||
map.put(
|
||||
new StoreNotFoundComp(),
|
||||
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.ScanAlert;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
|
@ -70,8 +71,9 @@ public class StoreIntroComp extends SimpleComp {
|
|||
v.getStyleClass().add("intro");
|
||||
|
||||
var sp = new StackPane(v);
|
||||
sp.setAlignment(Pos.CENTER);
|
||||
sp.setAlignment(Pos.BOTTOM_CENTER);
|
||||
sp.setPickOnBounds(false);
|
||||
sp.setPadding(new Insets(0, 0, 40, 0));
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,7 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
import io.xpipe.app.storage.StorageListener;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
@ -29,10 +27,6 @@ public class StoreViewState {
|
|||
private final ObservableList<StoreEntryWrapper> shownEntries =
|
||||
FXCollections.observableList(new CopyOnWriteArrayList<>());
|
||||
|
||||
private final ObservableBooleanValue empty = Bindings.createBooleanBinding(() -> {
|
||||
return allEntries.stream().allMatch(storeEntryWrapper -> !storeEntryWrapper.getEntry().getConfiguration().isRenameable());
|
||||
}, allEntries);
|
||||
|
||||
private StoreViewState() {
|
||||
try {
|
||||
addStorageGroupListeners();
|
||||
|
@ -107,12 +101,4 @@ public class StoreViewState {
|
|||
public ObservableList<StoreEntryWrapper> getShownEntries() {
|
||||
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.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class AppCache {
|
||||
|
@ -18,12 +17,6 @@ public class AppCache {
|
|||
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() {
|
||||
return AppProperties.get().getDataDir().resolve("cache");
|
||||
}
|
||||
|
@ -68,7 +61,7 @@ public class AppCache {
|
|||
FileUtils.deleteQuietly(path.toFile());
|
||||
}
|
||||
}
|
||||
return notPresent.get();
|
||||
return notPresent != null ? notPresent.get() : null;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
import io.xpipe.app.core.App;
|
||||
import io.xpipe.app.core.AppChecks;
|
||||
import io.xpipe.app.core.AppLogs;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.ErrorHandler;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
|
@ -87,6 +84,7 @@ public abstract class OperationMode {
|
|||
|
||||
TrackEvent.info("mode", "Initial setup");
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
XPipeSession.init(AppProperties.get().getBuildUuid());
|
||||
AppChecks.checkDirectoryPermissions();
|
||||
AppLogs.init();
|
||||
|
|
|
@ -3,8 +3,8 @@ package io.xpipe.app.issue;
|
|||
import io.sentry.*;
|
||||
import io.sentry.protocol.SentryId;
|
||||
import io.sentry.protocol.User;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.core.AppState;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
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
|
||||
if (!init) {
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
if (AppProperties.get().getSentryUrl() != null) {
|
||||
Sentry.init(options -> {
|
||||
options.setDsn(AppProperties.get().getSentryUrl());
|
||||
|
@ -110,7 +111,7 @@ public class SentryErrorHandler implements ErrorHandler {
|
|||
}
|
||||
|
||||
var user = new User();
|
||||
user.setId(AppCache.getCachedUserId().toString());
|
||||
user.setId(AppState.get().getUserId().toString());
|
||||
s.setUser(user);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ public class TerminalErrorHandler implements ErrorHandler {
|
|||
|
||||
try {
|
||||
AppProperties.init();
|
||||
AppState.init();
|
||||
AppExtensionManager.init(false);
|
||||
AppI18n.init();
|
||||
AppStyle.init();
|
||||
|
|
|
@ -16,6 +16,6 @@ storeIntroTitle=Adding Connections
|
|||
storeIntroDescription=Connect to remote systems, databases, and more.
|
||||
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.
|
||||
detectConnections=Detect connections
|
||||
detectConnections=Search for connections
|
||||
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:
|
||||
|
|
Loading…
Reference in a new issue