package com.mojang.realmsclient.gui.screens; import com.mojang.realmsclient.RealmsAvailability; import com.mojang.realmsclient.dto.RealmsNotification; import com.mojang.realmsclient.gui.RealmsDataFetcher; import com.mojang.realmsclient.gui.task.DataFetcher.Subscription; import java.util.Objects; import java.util.concurrent.CompletableFuture; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.GameNarrator; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.TitleScreen; import net.minecraft.client.renderer.RenderType; import net.minecraft.realms.RealmsScreen; import net.minecraft.resources.ResourceLocation; import org.jetbrains.annotations.Nullable; @Environment(EnvType.CLIENT) public class RealmsNotificationsScreen extends RealmsScreen { private static final ResourceLocation UNSEEN_NOTIFICATION_SPRITE = ResourceLocation.withDefaultNamespace("icon/unseen_notification"); private static final ResourceLocation NEWS_SPRITE = ResourceLocation.withDefaultNamespace("icon/news"); private static final ResourceLocation INVITE_SPRITE = ResourceLocation.withDefaultNamespace("icon/invite"); private static final ResourceLocation TRIAL_AVAILABLE_SPRITE = ResourceLocation.withDefaultNamespace("icon/trial_available"); private final CompletableFuture validClient = RealmsAvailability.get().thenApply(result -> result.type() == RealmsAvailability.Type.SUCCESS); @Nullable private Subscription realmsDataSubscription; @Nullable private RealmsNotificationsScreen.DataFetcherConfiguration currentConfiguration; private volatile int numberOfPendingInvites; private static boolean trialAvailable; private static boolean hasUnreadNews; private static boolean hasUnseenNotifications; private final RealmsNotificationsScreen.DataFetcherConfiguration showAll = new RealmsNotificationsScreen.DataFetcherConfiguration() { @Override public Subscription initDataFetcher(RealmsDataFetcher dataFetcher) { Subscription subscription = dataFetcher.dataFetcher.createSubscription(); RealmsNotificationsScreen.this.addNewsAndInvitesSubscriptions(dataFetcher, subscription); RealmsNotificationsScreen.this.addNotificationsSubscriptions(dataFetcher, subscription); return subscription; } @Override public boolean showOldNotifications() { return true; } }; private final RealmsNotificationsScreen.DataFetcherConfiguration onlyNotifications = new RealmsNotificationsScreen.DataFetcherConfiguration() { @Override public Subscription initDataFetcher(RealmsDataFetcher dataFetcher) { Subscription subscription = dataFetcher.dataFetcher.createSubscription(); RealmsNotificationsScreen.this.addNotificationsSubscriptions(dataFetcher, subscription); return subscription; } @Override public boolean showOldNotifications() { return false; } }; public RealmsNotificationsScreen() { super(GameNarrator.NO_TITLE); } @Override public void init() { if (this.realmsDataSubscription != null) { this.realmsDataSubscription.forceUpdate(); } } @Override public void added() { super.added(); this.minecraft.realmsDataFetcher().notificationsTask.reset(); } @Nullable private RealmsNotificationsScreen.DataFetcherConfiguration getConfiguration() { boolean bl = this.inTitleScreen() && (Boolean)this.validClient.getNow(false); if (!bl) { return null; } else { return this.getRealmsNotificationsEnabled() ? this.showAll : this.onlyNotifications; } } @Override public void tick() { RealmsNotificationsScreen.DataFetcherConfiguration dataFetcherConfiguration = this.getConfiguration(); if (!Objects.equals(this.currentConfiguration, dataFetcherConfiguration)) { this.currentConfiguration = dataFetcherConfiguration; if (this.currentConfiguration != null) { this.realmsDataSubscription = this.currentConfiguration.initDataFetcher(this.minecraft.realmsDataFetcher()); } else { this.realmsDataSubscription = null; } } if (this.realmsDataSubscription != null) { this.realmsDataSubscription.tick(); } } private boolean getRealmsNotificationsEnabled() { return this.minecraft.options.realmsNotifications().get(); } private boolean inTitleScreen() { return this.minecraft.screen instanceof TitleScreen; } @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { super.render(guiGraphics, mouseX, mouseY, partialTick); if ((Boolean)this.validClient.getNow(false)) { this.drawIcons(guiGraphics); } } @Override public void renderBackground(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { } private void drawIcons(GuiGraphics guiGraphics) { int i = this.numberOfPendingInvites; int j = 24; int k = this.height / 4 + 48; int l = this.width / 2 + 100; int m = k + 48 + 2; int n = l - 3; if (hasUnseenNotifications) { guiGraphics.blitSprite(RenderType::guiTextured, UNSEEN_NOTIFICATION_SPRITE, n - 12, m + 3, 10, 10); n -= 16; } if (this.currentConfiguration != null && this.currentConfiguration.showOldNotifications()) { if (hasUnreadNews) { guiGraphics.blitSprite(RenderType::guiTextured, NEWS_SPRITE, n - 14, m + 1, 14, 14); n -= 16; } if (i != 0) { guiGraphics.blitSprite(RenderType::guiTextured, INVITE_SPRITE, n - 14, m + 1, 14, 14); n -= 16; } if (trialAvailable) { guiGraphics.blitSprite(RenderType::guiTextured, TRIAL_AVAILABLE_SPRITE, n - 10, m + 4, 8, 8); } } } void addNewsAndInvitesSubscriptions(RealmsDataFetcher dataFetcher, Subscription subscription) { subscription.subscribe(dataFetcher.pendingInvitesTask, integer -> this.numberOfPendingInvites = integer); subscription.subscribe(dataFetcher.trialAvailabilityTask, boolean_ -> trialAvailable = boolean_); subscription.subscribe(dataFetcher.newsTask, realmsNews -> { dataFetcher.newsManager.updateUnreadNews(realmsNews); hasUnreadNews = dataFetcher.newsManager.hasUnreadNews(); }); } void addNotificationsSubscriptions(RealmsDataFetcher dataFetcher, Subscription subscription) { subscription.subscribe(dataFetcher.notificationsTask, list -> { hasUnseenNotifications = false; for (RealmsNotification realmsNotification : list) { if (!realmsNotification.seen()) { hasUnseenNotifications = true; break; } } }); } @Environment(EnvType.CLIENT) interface DataFetcherConfiguration { Subscription initDataFetcher(RealmsDataFetcher dataFetcher); boolean showOldNotifications(); } }