diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListOverviewComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListOverviewComp.java index 9867bba25..92a3640b5 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListOverviewComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListOverviewComp.java @@ -8,6 +8,7 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.impl.FilterComp; import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.util.BindingsHelper; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.util.ThreadHelper; import io.xpipe.core.process.OsType; @@ -148,15 +149,15 @@ public class StoreEntryListOverviewComp extends SimpleComp { } private Comp createAlphabeticalSortButton() { - var icon = Bindings.createStringBinding( + var icon = Bindings.createObjectBinding( () -> { if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_ASC) { - return "mdi2s-sort-alphabetical-descending"; + return new LabelGraphic.IconGraphic("mdi2s-sort-alphabetical-descending"); } if (sortMode.getValue() == StoreSortMode.ALPHABETICAL_DESC) { - return "mdi2s-sort-alphabetical-ascending"; + return new LabelGraphic.IconGraphic("mdi2s-sort-alphabetical-ascending"); } - return "mdi2s-sort-alphabetical-descending"; + return new LabelGraphic.IconGraphic("mdi2s-sort-alphabetical-descending"); }, sortMode); var alphabetical = new IconButtonComp(icon, () -> { @@ -189,15 +190,15 @@ public class StoreEntryListOverviewComp extends SimpleComp { } private Comp createDateSortButton() { - var icon = Bindings.createStringBinding( + var icon = Bindings.createObjectBinding( () -> { if (sortMode.getValue() == StoreSortMode.DATE_ASC) { - return "mdi2s-sort-clock-ascending-outline"; + return new LabelGraphic.IconGraphic("mdi2s-sort-clock-ascending-outline"); } if (sortMode.getValue() == StoreSortMode.DATE_DESC) { - return "mdi2s-sort-clock-descending-outline"; + return new LabelGraphic.IconGraphic("mdi2s-sort-clock-descending-outline"); } - return "mdi2s-sort-clock-ascending-outline"; + return new LabelGraphic.IconGraphic("mdi2s-sort-clock-ascending-outline"); }, sortMode); var date = new IconButtonComp(icon, () -> { diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java index 154e72013..266d966bc 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java @@ -7,6 +7,7 @@ import io.xpipe.app.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.storage.DataColor; import io.xpipe.app.util.ThreadHelper; @@ -68,11 +69,11 @@ public class StoreSectionComp extends Comp> { private Comp> createExpandButton() { var expandButton = new IconButtonComp( - Bindings.createStringBinding( - () -> section.getWrapper().getExpanded().get() + Bindings.createObjectBinding( + () -> new LabelGraphic.IconGraphic(section.getWrapper().getExpanded().get() && section.getShownChildren().getList().size() > 0 ? "mdal-keyboard_arrow_down" - : "mdal-keyboard_arrow_right", + : "mdal-keyboard_arrow_right"), section.getWrapper().getExpanded(), section.getShownChildren().getList()), () -> { diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java index 9e35bf600..24fa46adf 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionMiniComp.java @@ -8,6 +8,7 @@ import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.VerticalComp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.storage.DataColor; import javafx.beans.binding.Bindings; @@ -81,8 +82,8 @@ public class StoreSectionMiniComp extends Comp> { new SimpleBooleanProperty(section.getWrapper().getExpanded().get() && section.getShownChildren().getList().size() > 0); var button = new IconButtonComp( - Bindings.createStringBinding( - () -> expanded.get() ? "mdal-keyboard_arrow_down" : "mdal-keyboard_arrow_right", + Bindings.createObjectBinding( + () -> new LabelGraphic.IconGraphic(expanded.get() ? "mdal-keyboard_arrow_down" : "mdal-keyboard_arrow_right"), expanded), () -> { expanded.set(!expanded.get()); diff --git a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java index b63102895..07dc49e84 100644 --- a/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java +++ b/app/src/main/java/io/xpipe/app/core/AppLayoutModel.java @@ -5,22 +5,22 @@ import io.xpipe.app.browser.session.BrowserSessionComp; import io.xpipe.app.browser.session.BrowserSessionModel; import io.xpipe.app.comp.store.StoreLayoutComp; import io.xpipe.app.fxcomps.Comp; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.prefs.AppPrefsComp; import io.xpipe.app.util.Hyperlinks; import io.xpipe.app.util.LicenseProvider; - import javafx.beans.property.Property; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; - import lombok.Builder; import lombok.Data; import lombok.Getter; import lombok.extern.jackson.Jacksonized; +import java.time.*; import java.util.ArrayList; import java.util.List; @@ -75,43 +75,43 @@ public class AppLayoutModel { var l = new ArrayList<>(List.of( new Entry( AppI18n.observable("browser"), - "mdi2f-file-cabinet", + new LabelGraphic.IconGraphic("mdi2f-file-cabinet"), new BrowserSessionComp(BrowserSessionModel.DEFAULT), null, new KeyCodeCombination(KeyCode.DIGIT1, KeyCombination.SHORTCUT_DOWN)), new Entry( AppI18n.observable("connections"), - "mdi2c-connection", + new LabelGraphic.IconGraphic("mdi2c-connection"), new StoreLayoutComp(), null, new KeyCodeCombination(KeyCode.DIGIT2, KeyCombination.SHORTCUT_DOWN)), new Entry( AppI18n.observable("settings"), - "mdsmz-miscellaneous_services", + new LabelGraphic.IconGraphic("mdsmz-miscellaneous_services"), new AppPrefsComp(), null, new KeyCodeCombination(KeyCode.DIGIT3, KeyCombination.SHORTCUT_DOWN)), new Entry( AppI18n.observable("explorePlans"), - "mdi2p-professional-hexagon", + new LabelGraphic.IconGraphic("mdi2p-professional-hexagon"), LicenseProvider.get().overviewPage(), null, null), new Entry( AppI18n.observable("visitGithubRepository"), - "mdi2g-github", + new LabelGraphic.IconGraphic("mdi2g-github"), null, () -> Hyperlinks.open(Hyperlinks.GITHUB), null), new Entry( AppI18n.observable("discord"), - "mdi2d-discord", + new LabelGraphic.IconGraphic("mdi2d-discord"), null, () -> Hyperlinks.open(Hyperlinks.DISCORD), null), new Entry( AppI18n.observable("api"), - "mdi2c-code-json", + new LabelGraphic.IconGraphic("mdi2c-code-json"), null, () -> Hyperlinks.open( "http://localhost:" + AppBeaconServer.get().getPort()), @@ -123,6 +123,20 @@ public class AppLayoutModel { // () -> Hyperlinks.open(Hyperlinks.GITHUB_WEBTOP), // null) )); + + var now = Instant.now(); + var zone = ZoneId.of(ZoneId.SHORT_IDS.get("PST")); + var phStart = ZonedDateTime.of(2024,10,22,0,1, 0, 0, zone).toInstant(); + var phEnd = ZonedDateTime.of(2024,10,22,23,59, 0, 0, zone).toInstant(); + var phShow = now.isAfter(phStart) && now.isBefore(phEnd); + if (phShow) { + l.add(new Entry( + AppI18n.observable("api"), + new LabelGraphic.ImageGraphic("app:producthunt-color.png", 24), + null, + () -> Hyperlinks.open(Hyperlinks.PRODUCT_HUNT), + null)); + } return l; } @@ -135,6 +149,5 @@ public class AppLayoutModel { double browserConnectionsWidth; } - public record Entry( - ObservableValue name, String icon, Comp comp, Runnable action, KeyCombination combination) {} + public record Entry(ObservableValue name, LabelGraphic icon, Comp comp, Runnable action, KeyCombination combination) {} } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java index 438247b0e..33f51a327 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/impl/IconButtonComp.java @@ -1,38 +1,45 @@ package io.xpipe.app.fxcomps.impl; +import atlantafx.base.theme.Styles; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.CompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure; +import io.xpipe.app.fxcomps.util.LabelGraphic; import io.xpipe.app.fxcomps.util.PlatformThread; - import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.css.Size; import javafx.css.SizeUnits; import javafx.scene.control.Button; - -import atlantafx.base.theme.Styles; import org.kordamp.ikonli.javafx.FontIcon; public class IconButtonComp extends Comp> { - private final ObservableValue icon; + private final ObservableValue icon; private final Runnable listener; public IconButtonComp(String defaultVal) { + this(new SimpleObjectProperty<>(new LabelGraphic.IconGraphic(defaultVal)), null); + } + + public IconButtonComp(String defaultVal, Runnable listener) { + this(new SimpleObjectProperty<>(new LabelGraphic.IconGraphic(defaultVal)), listener); + } + + public IconButtonComp(LabelGraphic defaultVal) { this(new SimpleObjectProperty<>(defaultVal), null); } - public IconButtonComp(ObservableValue icon) { + public IconButtonComp(ObservableValue icon) { this.icon = icon; this.listener = null; } - public IconButtonComp(String defaultVal, Runnable listener) { + public IconButtonComp(LabelGraphic defaultVal, Runnable listener) { this(new SimpleObjectProperty<>(defaultVal), listener); } - public IconButtonComp(ObservableValue icon, Runnable listener) { + public IconButtonComp(ObservableValue icon, Runnable listener) { this.icon = PlatformThread.sync(icon); this.listener = listener; } @@ -41,18 +48,17 @@ public class IconButtonComp extends Comp> { public CompStructure