minecraft-src/com/mojang/realmsclient/gui/screens/RealmsPendingInvitesScreen.java
2025-07-04 03:45:38 +03:00

206 lines
8.7 KiB
Java

package com.mojang.realmsclient.gui.screens;
import com.mojang.logging.LogUtils;
import com.mojang.realmsclient.RealmsMainScreen;
import com.mojang.realmsclient.client.RealmsClient;
import com.mojang.realmsclient.dto.PendingInvite;
import com.mojang.realmsclient.exception.RealmsServiceException;
import com.mojang.realmsclient.gui.RealmsDataFetcher;
import com.mojang.realmsclient.gui.RowButton;
import com.mojang.realmsclient.gui.screens.RealmsPendingInvitesScreen.Entry.AcceptRowButton;
import com.mojang.realmsclient.gui.screens.RealmsPendingInvitesScreen.Entry.RejectRowButton;
import com.mojang.realmsclient.util.RealmsUtil;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ObjectSelectionList;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.realms.RealmsScreen;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@Environment(EnvType.CLIENT)
public class RealmsPendingInvitesScreen extends RealmsScreen {
static final ResourceLocation ACCEPT_HIGHLIGHTED_SPRITE = ResourceLocation.withDefaultNamespace("pending_invite/accept_highlighted");
static final ResourceLocation ACCEPT_SPRITE = ResourceLocation.withDefaultNamespace("pending_invite/accept");
static final ResourceLocation REJECT_HIGHLIGHTED_SPRITE = ResourceLocation.withDefaultNamespace("pending_invite/reject_highlighted");
static final ResourceLocation REJECT_SPRITE = ResourceLocation.withDefaultNamespace("pending_invite/reject");
private static final Logger LOGGER = LogUtils.getLogger();
private static final Component NO_PENDING_INVITES_TEXT = Component.translatable("mco.invites.nopending");
static final Component ACCEPT_INVITE = Component.translatable("mco.invites.button.accept");
static final Component REJECT_INVITE = Component.translatable("mco.invites.button.reject");
private final Screen lastScreen;
private final CompletableFuture<List<PendingInvite>> pendingInvites = CompletableFuture.supplyAsync(() -> {
try {
return RealmsClient.getOrCreate().pendingInvites().pendingInvites;
} catch (RealmsServiceException var1) {
LOGGER.error("Couldn't list invites", (Throwable)var1);
return List.of();
}
}, Util.ioPool());
@Nullable
Component toolTip;
RealmsPendingInvitesScreen.PendingInvitationSelectionList pendingInvitationSelectionList;
private Button acceptButton;
private Button rejectButton;
public RealmsPendingInvitesScreen(Screen lastScreen, Component title) {
super(title);
this.lastScreen = lastScreen;
}
@Override
public void init() {
RealmsMainScreen.refreshPendingInvites();
this.pendingInvitationSelectionList = new RealmsPendingInvitesScreen.PendingInvitationSelectionList();
this.pendingInvites.thenAcceptAsync(list -> {
List<RealmsPendingInvitesScreen.Entry> list2 = list.stream().map(pendingInvite -> new RealmsPendingInvitesScreen.Entry(pendingInvite)).toList();
this.pendingInvitationSelectionList.replaceEntries(list2);
if (list2.isEmpty()) {
this.minecraft.getNarrator().say(NO_PENDING_INVITES_TEXT);
}
}, this.screenExecutor);
this.addRenderableWidget(this.pendingInvitationSelectionList);
this.acceptButton = this.addRenderableWidget(
Button.builder(ACCEPT_INVITE, button -> this.handleInvitation(true)).bounds(this.width / 2 - 174, this.height - 32, 100, 20).build()
);
this.addRenderableWidget(Button.builder(CommonComponents.GUI_DONE, button -> this.onClose()).bounds(this.width / 2 - 50, this.height - 32, 100, 20).build());
this.rejectButton = this.addRenderableWidget(
Button.builder(REJECT_INVITE, button -> this.handleInvitation(false)).bounds(this.width / 2 + 74, this.height - 32, 100, 20).build()
);
this.updateButtonStates();
}
@Override
public void onClose() {
this.minecraft.setScreen(this.lastScreen);
}
void handleInvitation(boolean accept) {
if (this.pendingInvitationSelectionList.getSelected() instanceof RealmsPendingInvitesScreen.Entry entry) {
String string = entry.pendingInvite.invitationId;
CompletableFuture.supplyAsync(() -> {
try {
RealmsClient realmsClient = RealmsClient.getOrCreate();
if (accept) {
realmsClient.acceptInvitation(string);
} else {
realmsClient.rejectInvitation(string);
}
return true;
} catch (RealmsServiceException var3) {
LOGGER.error("Couldn't handle invite", (Throwable)var3);
return false;
}
}, Util.ioPool()).thenAcceptAsync(boolean_ -> {
if (boolean_) {
this.pendingInvitationSelectionList.removeInvitation(entry);
this.updateButtonStates();
RealmsDataFetcher realmsDataFetcher = this.minecraft.realmsDataFetcher();
if (accept) {
realmsDataFetcher.serverListUpdateTask.reset();
}
realmsDataFetcher.pendingInvitesTask.reset();
}
}, this.screenExecutor);
}
}
@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
this.toolTip = null;
super.render(guiGraphics, mouseX, mouseY, partialTick);
guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 12, -1);
if (this.toolTip != null) {
guiGraphics.renderTooltip(this.font, this.toolTip, mouseX, mouseY);
}
if (this.pendingInvites.isDone() && this.pendingInvitationSelectionList.hasPendingInvites()) {
guiGraphics.drawCenteredString(this.font, NO_PENDING_INVITES_TEXT, this.width / 2, this.height / 2 - 20, -1);
}
}
void updateButtonStates() {
RealmsPendingInvitesScreen.Entry entry = this.pendingInvitationSelectionList.getSelected();
this.acceptButton.visible = entry != null;
this.rejectButton.visible = entry != null;
}
@Environment(EnvType.CLIENT)
class Entry extends ObjectSelectionList.Entry<RealmsPendingInvitesScreen.Entry> {
private static final int TEXT_LEFT = 38;
final PendingInvite pendingInvite;
private final List<RowButton> rowButtons;
Entry(final PendingInvite pendingInvite) {
this.pendingInvite = pendingInvite;
this.rowButtons = Arrays.asList(new AcceptRowButton(this), new RejectRowButton(this));
}
@Override
public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) {
this.renderPendingInvitationItem(guiGraphics, this.pendingInvite, left, top, mouseX, mouseY);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
RowButton.rowButtonMouseClicked(RealmsPendingInvitesScreen.this.pendingInvitationSelectionList, this, this.rowButtons, button, mouseX, mouseY);
return super.mouseClicked(mouseX, mouseY, button);
}
private void renderPendingInvitationItem(GuiGraphics guiGraphics, PendingInvite pendingInvite, int x, int y, int mouseX, int mouseY) {
guiGraphics.drawString(RealmsPendingInvitesScreen.this.font, pendingInvite.realmName, x + 38, y + 1, -1);
guiGraphics.drawString(RealmsPendingInvitesScreen.this.font, pendingInvite.realmOwnerName, x + 38, y + 12, 7105644);
guiGraphics.drawString(RealmsPendingInvitesScreen.this.font, RealmsUtil.convertToAgePresentationFromInstant(pendingInvite.date), x + 38, y + 24, 7105644);
RowButton.drawButtonsInRow(guiGraphics, this.rowButtons, RealmsPendingInvitesScreen.this.pendingInvitationSelectionList, x, y, mouseX, mouseY);
RealmsUtil.renderPlayerFace(guiGraphics, x, y, 32, pendingInvite.realmOwnerUuid);
}
@Override
public Component getNarration() {
Component component = CommonComponents.joinLines(
Component.literal(this.pendingInvite.realmName),
Component.literal(this.pendingInvite.realmOwnerName),
RealmsUtil.convertToAgePresentationFromInstant(this.pendingInvite.date)
);
return Component.translatable("narrator.select", component);
}
}
@Environment(EnvType.CLIENT)
class PendingInvitationSelectionList extends ObjectSelectionList<RealmsPendingInvitesScreen.Entry> {
public PendingInvitationSelectionList() {
super(Minecraft.getInstance(), RealmsPendingInvitesScreen.this.width, RealmsPendingInvitesScreen.this.height - 72, 32, 36);
}
@Override
public int getRowWidth() {
return 260;
}
@Override
public void setSelectedIndex(int selected) {
super.setSelectedIndex(selected);
RealmsPendingInvitesScreen.this.updateButtonStates();
}
public boolean hasPendingInvites() {
return this.getItemCount() == 0;
}
public void removeInvitation(RealmsPendingInvitesScreen.Entry entry) {
this.removeEntry(entry);
}
}
}