From 8441195f1653836b638efe4a52a77fb22b3574e4 Mon Sep 17 00:00:00 2001 From: Josiah Glosson Date: Fri, 19 Jul 2024 19:01:53 -0500 Subject: [PATCH] Rework some UI stuff --- .../worldhost/gui/screen/AddFriendScreen.java | 119 ++++++++------- .../worldhost/gui/screen/FriendsScreen.java | 20 +-- .../worldhost/gui/widget/UserListWidget.java | 141 +++++++++++------- .../worldhost/plugin/FriendAdder.java | 11 +- .../worldhost/plugin/FriendListFriend.java | 4 + .../plugin/vanilla/WorldHostFriendAdder.java | 28 ++-- .../vanilla/WorldHostFriendListFriend.java | 5 + .../protocol/WorldHostS2CMessage.java | 2 +- .../worldhost/versions/ButtonBuilder.java | 7 +- 9 files changed, 189 insertions(+), 148 deletions(-) diff --git a/src/main/java/io/github/gaming32/worldhost/gui/screen/AddFriendScreen.java b/src/main/java/io/github/gaming32/worldhost/gui/screen/AddFriendScreen.java index bcb48f44..02b930cf 100644 --- a/src/main/java/io/github/gaming32/worldhost/gui/screen/AddFriendScreen.java +++ b/src/main/java/io/github/gaming32/worldhost/gui/screen/AddFriendScreen.java @@ -1,13 +1,11 @@ package io.github.gaming32.worldhost.gui.screen; import io.github.gaming32.worldhost.WorldHost; -import io.github.gaming32.worldhost.gui.widget.FriendAdderSelectorButton; import io.github.gaming32.worldhost.gui.widget.UserListWidget; import io.github.gaming32.worldhost.plugin.FriendAdder; import io.github.gaming32.worldhost.plugin.FriendListFriend; import io.github.gaming32.worldhost.versions.Components; import net.minecraft.Util; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.CommonComponents; @@ -16,8 +14,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; +import java.util.function.BiConsumer; //#if MC >= 1.20.0 import net.minecraft.client.gui.GuiGraphics; @@ -27,26 +26,29 @@ public class AddFriendScreen extends WorldHostScreen { private static final Component FRIEND_USERNAME_TEXT = Components.translatable("world-host.add_friend.enter_username"); + private static final Component ADD_FRIEND_TEXT = Component.literal("+"); + private static final Component ADD_FRIEND_SILENT_TEXT = Component.literal("+\ud83d\udd08"); + private static final Component ADD_FRIEND_NOTIFY_TEXT = Component.literal("+\ud83d\udd0a"); + private static final Component ADD_FRIEND_SILENT_TOOLTIP = Components.translatable("world-host.add_friend.tooltip"); + private static final Component ADD_FRIEND_NOTIFY_TOOLTIP = Components.translatable("world-host.friends.add_silently.tooltip"); private final Screen parent; - private final Consumer addAction; + private final BiConsumer addAction; private FriendListFriend prefilledFriend; private final List friendAdders = WorldHost.getFriendAdders(); - private FriendAdder friendAdder = friendAdders.getFirst(); private int maxFriends; private UserListWidget userList; private EditBox nameField; private long lastTyping; - private boolean delayedFriendUpdate; - private int reloadCount; + private Runnable delayedLookup; public AddFriendScreen( Screen parent, Component title, @Nullable FriendListFriend prefilledFriend, - Consumer addAction + BiConsumer addAction ) { super(title); this.parent = parent; @@ -54,18 +56,17 @@ public AddFriendScreen( this.prefilledFriend = prefilledFriend; } - private void resolveFriends(String name) { - final int currentReloadCount = ++reloadCount; - friendAdder.searchFriends(name, maxFriends) - .thenAcceptAsync(friends -> { - if (reloadCount == currentReloadCount && userList != null) { - userList.setUsers(friends); + private void resolveFriends(FriendAdder adder, String name) { + assert minecraft != null; + adder.searchFriends( + name, + maxFriends - userList.getUsersCount(), + friend -> minecraft.execute(() -> { + if (nameField.getValue().equals(name)) { + userList.addUser(friend); } - }, Minecraft.getInstance()) - .exceptionally(t -> { - WorldHost.LOGGER.error("Failed to request friend with name '{}'", name, t); - return null; - }); + }) + ); } @Override @@ -83,31 +84,29 @@ protected void init() { //#endif nameField.setResponder(name -> { lastTyping = Util.getMillis(); - if (friendAdder.delayLookup(name)) { - delayedFriendUpdate = true; + userList.clearUsers(); + final List delayedAdders = new ArrayList<>(); + for (final FriendAdder adder : friendAdders) { + if (adder.delayLookup(name)) { + delayedAdders.add(adder); + } else { + resolveFriends(adder, name); + } + } + if (!delayedAdders.isEmpty()) { + delayedLookup = () -> { + for (final FriendAdder adder : delayedAdders) { + resolveFriends(adder, name); + } + }; } else { - delayedFriendUpdate = false; - resolveFriends(name); + delayedLookup = null; } }); final int widgetsX = width / 2 - 100; final int widgetsWidth = 200; - int topWidgetsY = 90; - if (showFriendAddersButton()) { - addRenderableWidget(new FriendAdderSelectorButton( - widgetsX, topWidgetsY, widgetsWidth, 20, - Components.translatable("world-host.add_friend.friend_adder"), - button -> { - friendAdder = button.getValue(); - resolveFriends(nameField.getValue()); - }, - friendAdders.toArray(FriendAdder[]::new) - )); - topWidgetsY += 24; - } - int cancelY = 216; while (cancelY + 24 < height / 4 + 156) { cancelY += 24; @@ -120,17 +119,11 @@ protected void init() { ); maxFriends = (cancelY - 90) / 24; - if (showFriendAddersButton()) { - maxFriends--; - } userList = addRenderableWidget(new UserListWidget( font, - widgetsX, topWidgetsY, widgetsWidth, cancelY - topWidgetsY, - friend -> { - addAction.accept(friend); - minecraft.setScreen(parent); - }, + widgetsX, 90, widgetsWidth, cancelY - 90, + this::getActions, userList )); if (prefilledFriend != null) { @@ -139,17 +132,31 @@ protected void init() { } } - @Override - public void resize(Minecraft minecraft, int width, int height) { - final int oldMaxFriends = maxFriends; - super.resize(minecraft, width, height); - if (maxFriends != oldMaxFriends) { - resolveFriends(nameField.getValue()); + private List getActions(FriendListFriend user) { + if (user.supportsNotifyAdd()) { + return List.of( + new UserListWidget.Action( + ADD_FRIEND_NOTIFY_TEXT, ADD_FRIEND_NOTIFY_TOOLTIP, + getAddRunnable(user, true) + ), + new UserListWidget.Action( + ADD_FRIEND_SILENT_TEXT, ADD_FRIEND_SILENT_TOOLTIP, + getAddRunnable(user, false) + ) + ); + } else { + return List.of( + new UserListWidget.Action(ADD_FRIEND_TEXT, getAddRunnable(user, false)) + ); } } - private boolean showFriendAddersButton() { - return friendAdders.size() > 1; + private Runnable getAddRunnable(FriendListFriend user, boolean notify) { + assert minecraft != null; + return () -> { + addAction.accept(user, notify); + minecraft.setScreen(parent); + }; } @Override @@ -168,9 +175,9 @@ public void tick() { //#if MC < 1.20.2 //$$ nameField.tick(); //#endif - if (Util.getMillis() - 300 > lastTyping && delayedFriendUpdate) { - delayedFriendUpdate = false; - resolveFriends(nameField.getValue()); + if (Util.getMillis() - 300 > lastTyping && delayedLookup != null) { + delayedLookup.run(); + delayedLookup = null; } } diff --git a/src/main/java/io/github/gaming32/worldhost/gui/screen/FriendsScreen.java b/src/main/java/io/github/gaming32/worldhost/gui/screen/FriendsScreen.java index 136cef99..c4490bad 100644 --- a/src/main/java/io/github/gaming32/worldhost/gui/screen/FriendsScreen.java +++ b/src/main/java/io/github/gaming32/worldhost/gui/screen/FriendsScreen.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import io.github.gaming32.worldhost.WorldHost; import io.github.gaming32.worldhost.WorldHostComponents; +import io.github.gaming32.worldhost.gui.widget.UserListWidget; import io.github.gaming32.worldhost.plugin.FriendListFriend; import io.github.gaming32.worldhost.plugin.InfoTextsCategory; import io.github.gaming32.worldhost.plugin.ProfileInfo; @@ -25,7 +26,6 @@ public class FriendsScreen extends ScreenWithInfoTexts { public static final Component ADD_FRIEND_TEXT = Components.translatable("world-host.add_friend"); - private static final Component ADD_SILENTLY_TEXT = Components.translatable("world-host.friends.add_silently"); private final Screen parent; private Button removeButton; @@ -61,24 +61,17 @@ protected void init() { assert minecraft != null; minecraft.setScreen(new AddFriendScreen( this, ADD_FRIEND_TEXT, null, - friend -> friend.addFriend(true, refresher) + (friend, notify) -> friend.addFriend(notify, refresher) )); }).width(152) .pos(width / 2 - 154, height - 54) - .tooltip(Components.translatable("world-host.add_friend.tooltip")) .build() ); addRenderableWidget( - button(ADD_SILENTLY_TEXT, button -> { - assert minecraft != null; - minecraft.setScreen(new AddFriendScreen( - this, ADD_SILENTLY_TEXT, null, - friend -> friend.addFriend(false, refresher) - )); + button(Component.empty(), button -> { }).width(152) .pos(width / 2 - 154, height - 30) - .tooltip(Components.translatable("world-host.friends.add_silently.tooltip")) .build() ); @@ -190,12 +183,7 @@ public Component getNarration() { } public Component getNameWithTag() { - return friend.tag() - .map(component -> Components.translatable( - "world-host.friends.tagged_friend", - profile.name(), component - )) - .orElseGet(() -> Components.literal(profile.name())); + return UserListWidget.getNameWithTag(friend, profile); } @Override diff --git a/src/main/java/io/github/gaming32/worldhost/gui/widget/UserListWidget.java b/src/main/java/io/github/gaming32/worldhost/gui/widget/UserListWidget.java index a00b8ca6..0a44493b 100644 --- a/src/main/java/io/github/gaming32/worldhost/gui/widget/UserListWidget.java +++ b/src/main/java/io/github/gaming32/worldhost/gui/widget/UserListWidget.java @@ -5,19 +5,24 @@ import io.github.gaming32.worldhost.plugin.FriendListFriend; import io.github.gaming32.worldhost.plugin.ProfileInfo; import io.github.gaming32.worldhost.toast.IconRenderer; +import io.github.gaming32.worldhost.versions.Components; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.AbstractContainerWidget; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.locale.Language; +import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; +import net.minecraft.util.FormattedCharSequence; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; +import java.util.function.Function; import static io.github.gaming32.worldhost.gui.screen.WorldHostScreen.button; import static io.github.gaming32.worldhost.gui.screen.WorldHostScreen.drawString; @@ -29,28 +34,31 @@ //#endif public final class UserListWidget extends AbstractContainerWidget { - private final List users = new ArrayList<>(); - private final List