Skip to content

Commit

Permalink
Add a pop-up in the Video Settings screen asking the user to donate
Browse files Browse the repository at this point in the history
  • Loading branch information
jellysquid3 committed Jan 26, 2024
1 parent 523c39c commit b87a6f4
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ private static void updateFingerprint() {
if (saved == null || !current.looselyMatches(saved)) {
HashedFingerprint.writeToDisk(current.hashed());

CONFIG.notifications.hideDonationButton = false;
CONFIG.notifications.hasSeenDonationPrompt = false;
CONFIG.notifications.hasClearedDonationButton = false;

try {
UserConfig.writeToDisk(CONFIG);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ public static class QualitySettings {
}

public static class NotificationSettings {
public boolean hideDonationButton = false;
public boolean forceDisableDonationPrompts = false;

public boolean hasClearedDonationButton = false;
public boolean hasSeenDonationPrompt = false;
}

public enum GraphicsQuality implements TextProvider {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import me.jellysquid.mods.sodium.client.SodiumClientMod;
import me.jellysquid.mods.sodium.client.data.config.UserConfig;
import me.jellysquid.mods.sodium.client.data.fingerprint.HashedFingerprint;
import me.jellysquid.mods.sodium.client.gui.console.Console;
import me.jellysquid.mods.sodium.client.gui.console.message.MessageLevel;
import me.jellysquid.mods.sodium.client.gui.options.*;
Expand All @@ -13,6 +14,7 @@
import me.jellysquid.mods.sodium.client.gui.screen.ConfigCorruptedScreen;
import me.jellysquid.mods.sodium.client.gui.widgets.FlatButtonWidget;
import me.jellysquid.mods.sodium.client.util.Dim2i;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
Expand All @@ -27,6 +29,8 @@
import org.lwjgl.glfw.GLFW;

import java.io.IOException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
Expand Down Expand Up @@ -59,6 +63,61 @@ private RendererSettingsScreen(Screen prevScreen) {
this.pages.add(RendererSettingsLayout.quality());
this.pages.add(RendererSettingsLayout.performance());
this.pages.add(RendererSettingsLayout.advanced());

this.checkPromptTimers();
}

private void checkPromptTimers() {
// Never show the prompt in developer workspaces.
if (FabricLoader.getInstance().isDevelopmentEnvironment()) {
return;
}

var options = SodiumClientMod.options();

// If the user has disabled the nags forcefully (by config), or has already seen the prompt, don't show it again.
if (options.notifications.forceDisableDonationPrompts || options.notifications.hasSeenDonationPrompt) {
return;
}

HashedFingerprint fingerprint = null;

try {
fingerprint = HashedFingerprint.loadFromDisk();
} catch (Throwable t) {
SodiumClientMod.logger()
.error("Failed to read the fingerprint from disk", t);
}

// If the fingerprint doesn't exist, or failed to be loaded, abort.
if (fingerprint == null) {
return;
}

// The fingerprint records the installation time. If it's been a while since installation, show the user
// a prompt asking for them to consider donating.
var now = Instant.now();
var threshold = Instant.ofEpochSecond(fingerprint.timestamp())
.plus(3, ChronoUnit.DAYS);

if (now.isAfter(threshold)) {
this.openDonationPrompt(options);
}
}

private void openDonationPrompt(UserConfig options) {
var prompt = new ScreenPrompt(this, DONATION_PROMPT_MESSAGE, 320, 190,
new ScreenPrompt.Action(Text.literal("Buy us a coffee"), this::openDonationPage));
prompt.setFocused(true);

options.notifications.hasSeenDonationPrompt = true;

try {
UserConfig.writeToDisk(options);
} catch (IOException e) {
SodiumClientMod.logger()
.error("Failed to update config file", e);
}
}

public static Screen createScreen(Screen currentScreen) {
Expand Down Expand Up @@ -105,7 +164,7 @@ private void rebuildGUI() {
this.donateButton = new FlatButtonWidget(new Dim2i(this.width - 128, 6, 100, 20), Text.translatable("sodium.options.buttons.donate"), this::openDonationPage);
this.hideDonateButton = new FlatButtonWidget(new Dim2i(this.width - 26, 6, 20, 20), Text.literal("x"), this::hideDonationButton);

if (SodiumClientMod.options().notifications.hideDonationButton) {
if (SodiumClientMod.options().notifications.hasClearedDonationButton || SodiumClientMod.options().notifications.forceDisableDonationPrompts) {
this.setDonationButtonVisibility(false);
}

Expand All @@ -123,7 +182,7 @@ private void setDonationButtonVisibility(boolean value) {

private void hideDonationButton() {
UserConfig options = SodiumClientMod.options();
options.notifications.hideDonationButton = true;
options.notifications.hasClearedDonationButton = true;

try {
UserConfig.writeToDisk(options);
Expand Down Expand Up @@ -367,4 +426,16 @@ public ScreenPrompt getPrompt() {
public Dim2i getDimensions() {
return new Dim2i(0, 0, this.width, this.height);
}

private static final List<StringVisitable> DONATION_PROMPT_MESSAGE;

static {
DONATION_PROMPT_MESSAGE = List.of(
StringVisitable.concat(Text.literal("Hello!")),
StringVisitable.concat(Text.literal("It seems that you've been enjoying "), Text.literal("Sodium").withColor(0x27eb92), Text.literal(", the free and open-source optimization mod for Minecraft.")),
StringVisitable.concat(Text.literal("Mods like these are complex. They require "), Text.literal("thousands of hours").withColor(0xff6e00), Text.literal(" of development, debugging, and tuning to create the experience that players have come to expect.")),
StringVisitable.concat(Text.literal("If you'd like to show your token of appreciation, and support the development of our mod in the process, then consider "), Text.literal("buying us a coffee").withColor(0xed49ce), Text.literal(".")),
StringVisitable.concat(Text.literal("And thanks again for using our mod! We hope it helps you (and your computer.)"))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import net.minecraft.client.gui.Element;
import net.minecraft.text.StringVisitable;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;

Expand All @@ -19,16 +18,20 @@ public class ScreenPrompt implements Element, Drawable {
private final ScreenPromptable parent;
private final List<StringVisitable> text;

private final Action action;

private FlatButtonWidget closeButton, actionButton;

private final int width, height;

public ScreenPrompt(ScreenPromptable parent, List<StringVisitable> text, int width, int height) {
public ScreenPrompt(ScreenPromptable parent, List<StringVisitable> text, int width, int height, Action action) {
this.parent = parent;
this.text = text;

this.width = width;
this.height = height;

this.action = action;
}

public void render(DrawContext drawContext, int mouseX, int mouseY, float delta) {
Expand Down Expand Up @@ -64,7 +67,7 @@ public void render(DrawContext drawContext, int mouseX, int mouseY, float delta)
var formatted = textRenderer.wrapLines(paragraph, textMaxWidth);

for (var line : formatted) {
drawContext.drawText(textRenderer, line, textX, textY, 0x0, true);
drawContext.drawText(textRenderer, line, textX, textY, 0xFFFFFFFF, true);
textY += textRenderer.fontHeight + 2;
}

Expand All @@ -74,7 +77,7 @@ public void render(DrawContext drawContext, int mouseX, int mouseY, float delta)
this.closeButton = new FlatButtonWidget(new Dim2i((boxX + width) - 84, (boxY + height) - 24, 80, 20), Text.literal("Close"), this::close);
this.closeButton.setStyle(createButtonStyle());

this.actionButton = new FlatButtonWidget(new Dim2i((boxX + width) - 198, (boxY + height) - 24, 110, 20), Text.literal("Perform action"), this::close);
this.actionButton = new FlatButtonWidget(new Dim2i((boxX + width) - 198, (boxY + height) - 24, 110, 20), this.action.label, this::runAction);
this.actionButton.setStyle(createButtonStyle());

for (var button : getWidgets()) {
Expand Down Expand Up @@ -138,4 +141,13 @@ public boolean isFocused() {
private void close() {
this.parent.setPrompt(null);
}

private void runAction() {
this.action.runnable.run();
this.close();
}

public record Action(Text label, Runnable runnable) {

}
}

0 comments on commit b87a6f4

Please sign in to comment.