mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-04-22 15:40:31 -04:00
Rework
This commit is contained in:
@@ -454,7 +454,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||
}
|
||||
|
||||
{
|
||||
var order = new Menu(AppI18n.get("order"), new FontIcon("mdi2b-bookmark-multiple-outline"));
|
||||
var order = new Menu(AppI18n.get("order"), new FontIcon("mdi2f-format-list-bulleted"));
|
||||
|
||||
var index = new MenuItem(AppI18n.get("index"), new FontIcon("mdi2o-order-numeric-ascending"));
|
||||
index.setOnAction(event -> {
|
||||
@@ -475,14 +475,14 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||
order.getItems().add(noOrder);
|
||||
}
|
||||
|
||||
var first = new MenuItem(AppI18n.get("moveToTop"), new FontIcon("mdi2o-order-bool-descending"));
|
||||
var first = new MenuItem(AppI18n.get("moveToFirst"), new FontIcon("mdi2o-order-bool-descending"));
|
||||
first.setOnAction(event -> {
|
||||
getWrapper().orderFirst();
|
||||
event.consume();
|
||||
});
|
||||
order.getItems().add(first);
|
||||
|
||||
var last = new MenuItem(AppI18n.get("moveToBottom"), new FontIcon("mdi2o-order-bool-ascending"));
|
||||
var last = new MenuItem(AppI18n.get("moveToLast"), new FontIcon("mdi2o-order-bool-ascending"));
|
||||
last.setOnAction(event -> {
|
||||
getWrapper().orderLast();
|
||||
event.consume();
|
||||
@@ -492,7 +492,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||
order.getItems().add(new SeparatorMenuItem());
|
||||
|
||||
var top = new MenuItem(
|
||||
AppI18n.get("stickToTop"), new FontIcon("mdi2o-order-bool-descending-variant"));
|
||||
AppI18n.get("keepFirst"), new FontIcon("mdi2o-order-bool-descending-variant"));
|
||||
top.setOnAction(event -> {
|
||||
getWrapper().orderStickFirst();
|
||||
event.consume();
|
||||
@@ -501,7 +501,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||
order.getItems().add(top);
|
||||
|
||||
var bottom = new MenuItem(
|
||||
AppI18n.get("stickToBottom"), new FontIcon("mdi2o-order-bool-ascending-variant"));
|
||||
AppI18n.get("keepLast"), new FontIcon("mdi2o-order-bool-ascending-variant"));
|
||||
bottom.setOnAction(event -> {
|
||||
getWrapper().orderStickLast();
|
||||
event.consume();
|
||||
@@ -538,6 +538,32 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||
});
|
||||
items.add(move);
|
||||
}
|
||||
|
||||
if (getWrapper().getPinToTop().getValue() || section.getDepth() > 1) {
|
||||
var pinToTop = new MenuItem();
|
||||
pinToTop.graphicProperty()
|
||||
.bind(Bindings.createObjectBinding(
|
||||
() -> {
|
||||
var is = getWrapper().getPinToTop().get();
|
||||
return is
|
||||
? new FontIcon("mdi2p-pin-off-outline")
|
||||
: new FontIcon("mdi2p-pin-outline");
|
||||
},
|
||||
getWrapper().getPinToTop()));
|
||||
pinToTop.textProperty()
|
||||
.bind(Bindings.createStringBinding(
|
||||
() -> {
|
||||
var is = getWrapper().getPinToTop().get();
|
||||
return is
|
||||
? AppI18n.get("unpinFromTop")
|
||||
: AppI18n.get("pinToTop");
|
||||
},
|
||||
AppI18n.activeLanguage(),
|
||||
getWrapper().getPinToTop()));
|
||||
pinToTop.setOnAction(event -> getWrapper()
|
||||
.togglePinToTop());
|
||||
items.add(pinToTop);
|
||||
}
|
||||
}
|
||||
|
||||
if (cat == StoreActionCategory.DELETION) {
|
||||
|
||||
@@ -64,6 +64,7 @@ public class StoreEntryWrapper {
|
||||
private final BooleanProperty largeCategoryOptimizations = new SimpleBooleanProperty();
|
||||
private final BooleanProperty readOnly = new SimpleBooleanProperty();
|
||||
private final BooleanProperty renaming = new SimpleBooleanProperty();
|
||||
private final BooleanProperty pinToTop = new SimpleBooleanProperty();
|
||||
private final IntegerProperty orderIndex = new SimpleIntegerProperty();
|
||||
|
||||
private boolean effectiveBusyProviderBound = false;
|
||||
@@ -197,6 +198,7 @@ public class StoreEntryWrapper {
|
||||
perUser.setValue(
|
||||
!category.getValue().getRoot().equals(StoreViewState.get().getAllIdentitiesCategory())
|
||||
&& entry.isPerUserStore());
|
||||
pinToTop.setValue(entry.isPinToTop());
|
||||
|
||||
var storeChanged = store.getValue() != entry.getStore();
|
||||
store.setValue(entry.getStore());
|
||||
@@ -416,6 +418,23 @@ public class StoreEntryWrapper {
|
||||
this.expanded.set(!expanded.getValue());
|
||||
}
|
||||
|
||||
public void togglePinToTop() {
|
||||
if (getEntry().isPinToTop()) {
|
||||
getEntry().setPinToTop(false);
|
||||
StoreViewState.get().triggerStoreListUpdate();
|
||||
} else {
|
||||
var root = StoreViewState.get().getCurrentTopLevelSection().getAllChildren().getList().stream().filter(
|
||||
storeSection -> storeSection.anyMatches(storeEntryWrapper -> storeEntryWrapper == this)).findFirst();
|
||||
var sortMode = StoreSectionSortMode.DATE_DESC;
|
||||
var date = root.isPresent() ? sortMode.date(sortMode.getRepresentative(root.get())).plus(Duration.ofSeconds(1)) : Instant.now();
|
||||
getEntry().setPinToTop(!getEntry().isPinToTop());
|
||||
StoreViewState.get().triggerStoreListUpdate();
|
||||
getEntry().setLastUsed(date);
|
||||
getEntry().setLastModified(date);
|
||||
StoreViewState.get().triggerStoreListUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean matchesFilter(String filter) {
|
||||
if (filter == null || name.getValue().toLowerCase().contains(filter.toLowerCase())) {
|
||||
return true;
|
||||
|
||||
@@ -57,9 +57,9 @@ public interface StoreSectionSortMode {
|
||||
.reversed();
|
||||
}
|
||||
};
|
||||
StoreSectionSortMode DATE_DESC = new StoreSectionSortMode.DateSortMode() {
|
||||
StoreSectionSortMode.DateSortMode DATE_DESC = new StoreSectionSortMode.DateSortMode() {
|
||||
|
||||
protected Instant date(StoreSection s) {
|
||||
public Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccess().getValue();
|
||||
if (la == null) {
|
||||
return Instant.MAX;
|
||||
@@ -78,9 +78,9 @@ public interface StoreSectionSortMode {
|
||||
return "date-desc";
|
||||
}
|
||||
};
|
||||
StoreSectionSortMode DATE_ASC = new StoreSectionSortMode.DateSortMode() {
|
||||
StoreSectionSortMode.DateSortMode DATE_ASC = new StoreSectionSortMode.DateSortMode() {
|
||||
|
||||
protected Instant date(StoreSection s) {
|
||||
public Instant date(StoreSection s) {
|
||||
var la = s.getWrapper().getLastAccess().getValue();
|
||||
if (la == null) {
|
||||
return Instant.MIN;
|
||||
@@ -117,7 +117,7 @@ public interface StoreSectionSortMode {
|
||||
private int entriesListObservableIndex = -1;
|
||||
private final Map<StoreSection, StoreSection> cachedRepresentatives = new IdentityHashMap<>();
|
||||
|
||||
private StoreSection computeRepresentative(StoreSection s) {
|
||||
public StoreSection computeRepresentative(StoreSection s) {
|
||||
return Stream.concat(
|
||||
s.getShownChildren().getList().stream()
|
||||
.filter(section -> section.getWrapper()
|
||||
@@ -130,7 +130,7 @@ public interface StoreSectionSortMode {
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
private StoreSection getRepresentative(StoreSection s) {
|
||||
public StoreSection getRepresentative(StoreSection s) {
|
||||
if (StoreViewState.get().getEntriesListUpdateObservable().get() != entriesListObservableIndex) {
|
||||
cachedRepresentatives.clear();
|
||||
entriesListObservableIndex =
|
||||
@@ -146,7 +146,7 @@ public interface StoreSectionSortMode {
|
||||
return r;
|
||||
}
|
||||
|
||||
protected abstract Instant date(StoreSection s);
|
||||
public abstract Instant date(StoreSection s);
|
||||
|
||||
protected abstract int compare(Instant s1, Instant s2);
|
||||
|
||||
|
||||
@@ -862,6 +862,10 @@ public abstract class DataStorage {
|
||||
// Get operations
|
||||
|
||||
public boolean isRootEntry(DataStoreEntry entry, DataStoreCategory current) {
|
||||
if (entry.isPinToTop()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var parent = getDefaultDisplayParent(entry);
|
||||
var noParent = parent.isEmpty();
|
||||
if (noParent) {
|
||||
|
||||
@@ -79,6 +79,10 @@ public class DataStoreEntry extends StorageElement {
|
||||
@Getter
|
||||
boolean freeze;
|
||||
|
||||
@NonFinal
|
||||
@Getter
|
||||
boolean pinToTop;
|
||||
|
||||
@Getter
|
||||
@NonFinal
|
||||
int orderIndex;
|
||||
@@ -100,6 +104,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
String notes,
|
||||
String icon,
|
||||
boolean freeze,
|
||||
boolean pinToTop,
|
||||
int orderIndex) {
|
||||
super(directory, uuid, name, lastUsed, lastModified, expanded, dirty);
|
||||
this.color = color;
|
||||
@@ -112,6 +117,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
this.notes = notes;
|
||||
this.icon = icon;
|
||||
this.freeze = freeze;
|
||||
this.pinToTop = pinToTop;
|
||||
this.orderIndex = orderIndex;
|
||||
}
|
||||
|
||||
@@ -133,6 +139,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
0);
|
||||
}
|
||||
|
||||
@@ -171,6 +178,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
0);
|
||||
return entry;
|
||||
}
|
||||
@@ -228,6 +236,9 @@ public class DataStoreEntry extends StorageElement {
|
||||
var freeze = Optional.ofNullable(json.get("freeze"))
|
||||
.map(jsonNode -> jsonNode.booleanValue())
|
||||
.orElse(false);
|
||||
var pinToTop = Optional.ofNullable(json.get("pinToTop"))
|
||||
.map(jsonNode -> jsonNode.booleanValue())
|
||||
.orElse(false);
|
||||
|
||||
var iconNode = json.get("icon");
|
||||
String icon = iconNode != null && !iconNode.isNull() ? iconNode.asText() : null;
|
||||
@@ -305,6 +316,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
notes,
|
||||
icon,
|
||||
freeze,
|
||||
pinToTop,
|
||||
orderIndex));
|
||||
}
|
||||
|
||||
@@ -464,6 +476,7 @@ public class DataStoreEntry extends StorageElement {
|
||||
obj.set("color", mapper.valueToTree(color));
|
||||
obj.set("icon", mapper.valueToTree(icon));
|
||||
obj.put("freeze", freeze);
|
||||
obj.put("pinToTop", pinToTop);
|
||||
obj.put("orderIndex", orderIndex);
|
||||
|
||||
ObjectNode stateObj = JsonNodeFactory.instance.objectNode();
|
||||
@@ -519,6 +532,15 @@ public class DataStoreEntry extends StorageElement {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPinToTop(boolean newValue) {
|
||||
var changed = pinToTop != newValue;
|
||||
this.pinToTop = newValue;
|
||||
if (changed) {
|
||||
notifyUpdate(false, false);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDisabled() {
|
||||
return validity == Validity.LOAD_FAILED;
|
||||
}
|
||||
|
||||
13
lang/strings/translations_en.properties
generated
13
lang/strings/translations_en.properties
generated
@@ -442,9 +442,12 @@ skipAll=Skip all
|
||||
notes=Notes
|
||||
addNotes=Add notes
|
||||
#context: verb, to reorder
|
||||
order=Order ...
|
||||
stickToTop=Keep on top
|
||||
stickToBottom=Keep on bottom
|
||||
#force
|
||||
order=Order
|
||||
keepFirst=Keep first
|
||||
keepLast=Keep last
|
||||
pinToTop=Pin to top
|
||||
unpinFromTop=Unpin from top
|
||||
orderAheadOf=Order ahead of ...
|
||||
httpServer=HTTP server
|
||||
httpServerConfiguration=HTTP server configuration
|
||||
@@ -1525,8 +1528,8 @@ appleContainers=Apple containers
|
||||
changeOrderIndexTitle=Change order index
|
||||
orderIndex=Index
|
||||
orderIndexDescription=Explicit index to order this entry relative to others. Lowest indices are shown on top, highest on the bottom
|
||||
moveToBottom=Move to bottom
|
||||
moveToTop=Move to top
|
||||
moveToFirst=Move to first
|
||||
moveToLast=Move to last
|
||||
category=Category
|
||||
includeRoot=Include root
|
||||
excludeRoot=Exclude root
|
||||
|
||||
Reference in New Issue
Block a user