Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import com.rappytv.betterfriends.ui.hud.UnreadChatCountWidget;
import com.rappytv.betterfriends.ui.tags.FriendNoteNameTag;
import com.rappytv.betterfriends.ui.tags.FriendPinIconTag;
import com.rappytv.betterfriends.utils.FriendshipExpirationHandler;
import com.rappytv.betterfriends.utils.GroupHelper;
import com.rappytv.betterfriends.utils.VoiceChatHelper;
import net.labymod.api.Laby;
import net.labymod.api.addon.LabyAddon;
import net.labymod.api.client.component.Component;
Expand All @@ -37,16 +39,20 @@ public class BetterFriendsAddon extends LabyAddon<BetterFriendsConfig> {

private final LegacyComponentSerializer serializer = LegacyComponentSerializer.legacyAmpersand();
private static BetterFriendsAddon instance;
private final VoiceChatHelper voiceChatHelper = new VoiceChatHelper();
private FriendshipExpirationHandler expirationHandler;

@Override
protected void enable() {
instance = this;
this.registerSettingCategory();
GroupHelper.registerGroupIds();
this.expirationHandler = new FriendshipExpirationHandler(this);

this.registerCommand(new BetterFriendsCommand());

this.registerListener(new ChatReceiveListener(this));
this.registerListener(this.expirationHandler);
this.registerListener(new FriendAddListener(this));
this.registerListener(new FriendRemoveListener(this));
this.registerListener(new FriendRequestReceiveListener(this));
Expand Down Expand Up @@ -103,6 +109,18 @@ public static TextComponent getPrefix() {
.append(Component.space());
}

public static BetterFriendsAddon getInstance() {
return instance;
}

public FriendshipExpirationHandler getExpirationHandler() {
return this.expirationHandler;
}

public VoiceChatHelper getVoiceChatHelper() {
return this.voiceChatHelper;
}

public LegacyComponentSerializer getSerializer() {
return this.serializer;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.rappytv.betterfriends.config;

import com.rappytv.betterfriends.config.subconfig.FriendNoteTagConfig;
import com.rappytv.betterfriends.config.subconfig.FriendlistExpiryConfig;
import com.rappytv.betterfriends.config.subconfig.PinIconConfig;
import com.rappytv.betterfriends.ui.activities.config.FriendlistActivity;
import com.rappytv.betterfriends.ui.widgets.FriendlistFriendWidget;
Expand Down Expand Up @@ -36,6 +37,8 @@ public Activity advancedFriendlist() {
return new FriendlistActivity<>(FriendlistFriendWidget::new);
}

private final FriendlistExpiryConfig expiryConfig = new FriendlistExpiryConfig();

@SpriteSlot(size = 8, x = 4)
private final PinIconConfig pinIconConfig = new PinIconConfig();
@SpriteSlot(x = 3)
Expand Down Expand Up @@ -93,6 +96,9 @@ public ConfigProperty<Boolean> enabled() {
public ConfigProperty<Color> prefixColor() {
return this.prefixColor;
}
public FriendlistExpiryConfig expiryConfig() {
return this.expiryConfig;
}
public PinIconConfig pinIconConfig() {
return this.pinIconConfig;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.rappytv.betterfriends.config.subconfig;

import net.labymod.api.client.gui.screen.activity.Activity;
import net.labymod.api.client.gui.screen.widget.widgets.activity.settings.ActivitySettingWidget.ActivitySetting;
import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting;
import net.labymod.api.configuration.loader.Config;
import net.labymod.api.configuration.loader.annotation.Exclude;
import net.labymod.api.configuration.loader.property.ConfigProperty;
import net.labymod.api.util.MethodOrder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class FriendlistExpiryConfig extends Config {

@Exclude
private final Map<UUID, Long> expirations = new HashMap<>();

@SwitchSetting
private final ConfigProperty<Boolean> sendNotifications = new ConfigProperty<>(true);

@SwitchSetting
private final ConfigProperty<Boolean> notifyOnExpiration = new ConfigProperty<>(true);

@MethodOrder(after = "notifyOnExpiration")
@ActivitySetting
public Activity manageExpirationDates() {
return null;
}

public void addExpiration(UUID uuid, long expiration) {
this.expirations.put(uuid, expiration);
}

public void removeExpiration(UUID uuid) {
this.expirations.remove(uuid);
}

public Map<UUID, Long> getExpirations() {
return this.expirations;
}

public ConfigProperty<Boolean> sendNotifications() {
return this.sendNotifications;
}
public ConfigProperty<Boolean> notifyOnExpiration() {
return this.notifyOnExpiration;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.rappytv.betterfriends.listeners;

import com.rappytv.betterfriends.BetterFriendsAddon;
import net.labymod.addons.voicechat.api.audio.stream.AudioStreamState;
import net.labymod.addons.voicechat.api.client.VoiceConnector;
import net.labymod.addons.voicechat.core.VoiceChatAddon;
import com.rappytv.betterfriends.ui.activities.FriendlistExpirationActivity;
import net.labymod.api.Laby;
import net.labymod.api.client.component.Component;
import net.labymod.api.client.gui.icon.Icon;
import net.labymod.api.event.Subscribe;
import net.labymod.api.event.labymod.labyconnect.session.friend.LabyConnectFriendAddEvent;
import net.labymod.api.notification.Notification;
import net.labymod.api.notification.Notification.NotificationButton;

public class FriendAddListener {

Expand All @@ -18,28 +20,28 @@ public FriendAddListener(BetterFriendsAddon addon) {

@Subscribe
public void onFriendAdd(LabyConnectFriendAddEvent event) {
if (!this.addon.configuration().restartWhenMuted().get()) {
return;
if(this.addon.configuration().expiryConfig().sendNotifications().get()) {
Notification.builder()
.title(Component.translatable("betterfriends.notifications.friendshipExpiration.set.title"))
.text(Component.translatable("betterfriends.notifications.friendshipExpiration.set.description"))
.icon(Icon.head(event.friend().getUniqueId(), true))
.addButton(NotificationButton.of(
Component.translatable("betterfriends.notifications.friendshipExpiration.set.button"),
() -> Laby.labyAPI().minecraft().minecraftWindow().displayScreen(
new FriendlistExpirationActivity(event.friend())
)
))
.duration(20000)
.buildAndPush();
}

if (!Laby.labyAPI().addonService().isEnabled("voicechat")) {
if (!this.addon.configuration().restartWhenMuted().get()) {
return;
}

VoiceConnector client = VoiceChatAddon.INSTANCE.client();
if (!client.isAuthenticated() || !this.isSelfMuted()) {
if (!this.addon.getVoiceChatHelper().isEnabled()) {
return;
}

client.disconnect();
client.connect();
this.addon.getVoiceChatHelper().reconnect();
}

private boolean isSelfMuted() {
return VoiceChatAddon.INSTANCE
.referenceStorage()
.audioStreamRegistry()
.getState(Laby.labyAPI().getUniqueId(), false) == AudioStreamState.INPUT_GLOBAL_MUTED;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package com.rappytv.betterfriends.ui.activities;

import com.rappytv.betterfriends.BetterFriendsAddon;
import com.rappytv.betterfriends.utils.FriendshipExpirationHandler;
import com.rappytv.betterfriends.utils.FriendshipExpirationHandler.FriendshipExpirationType;
import com.rappytv.betterfriends.utils.VoiceChatHelper;
import net.labymod.api.Laby;
import net.labymod.api.client.component.Component;
import net.labymod.api.client.component.format.NamedTextColor;
import net.labymod.api.client.gui.icon.Icon;
import net.labymod.api.client.gui.screen.Parent;
import net.labymod.api.client.gui.screen.ScreenInstance;
import net.labymod.api.client.gui.screen.activity.AutoActivity;
import net.labymod.api.client.gui.screen.activity.Link;
import net.labymod.api.client.gui.screen.activity.types.SimpleActivity;
import net.labymod.api.client.gui.screen.widget.Widget;
import net.labymod.api.client.gui.screen.widget.widgets.ComponentWidget;
import net.labymod.api.client.gui.screen.widget.widgets.input.ButtonWidget;
import net.labymod.api.client.gui.screen.widget.widgets.input.TextFieldWidget;
import net.labymod.api.client.gui.screen.widget.widgets.input.dropdown.DropdownWidget;
import net.labymod.api.client.gui.screen.widget.widgets.layout.FlexibleContentWidget;
import net.labymod.api.client.gui.screen.widget.widgets.layout.list.HorizontalListWidget;
import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget;
import net.labymod.api.client.gui.screen.widget.widgets.renderer.IconWidget;
import net.labymod.api.labyconnect.protocol.model.friend.Friend;
import net.labymod.api.util.I18n;

@Link("expiration.lss")
@AutoActivity
public class FriendlistExpirationActivity extends SimpleActivity {

private final FriendshipExpirationHandler handler;
private final VoiceChatHelper voiceChatHelper;
private final Friend friend;
private TextFieldWidget customExpirationField;

public FriendlistExpirationActivity(Friend friend) {
this.handler = BetterFriendsAddon.getInstance().getExpirationHandler();
this.voiceChatHelper = BetterFriendsAddon.getInstance().getVoiceChatHelper();
this.friend = friend;
}

@Override
public void initialize(Parent parent) {
super.initialize(parent);

FlexibleContentWidget window = new FlexibleContentWidget()
.addId("window");

HorizontalListWidget profileWrapper = new HorizontalListWidget()
.addId("header");
IconWidget headIcon = new IconWidget(Icon.head(this.friend.getUniqueId())).addId("head");
ComponentWidget nameComponent = ComponentWidget.i18n(
"betterfriends.settings.advancedFriendlist.expiration.title",
this.friend.getName()
).addId("username");
VerticalListWidget<Widget> content = new VerticalListWidget<>().addId("content");

profileWrapper.addEntry(headIcon);
profileWrapper.addEntry(nameComponent);

DropdownWidget<FriendshipExpirationType> expirationTypeDropdown = new DropdownWidget<>();
if(Laby.labyAPI().minecraft().isIngame()) {
expirationTypeDropdown.add(FriendshipExpirationType.ON_SERVER_LEAVE);
}
if(this.voiceChatHelper.isEnabled()) {
long expiration = this.voiceChatHelper.getMuteExpiration(this.friend.getUniqueId());
if(expiration != -1) {
expirationTypeDropdown.add(FriendshipExpirationType.ON_MUTE_EXPIRATION);
}
}
expirationTypeDropdown.add(FriendshipExpirationType.CUSTOM_DATE);
expirationTypeDropdown.setSelected(expirationTypeDropdown.entries().getFirst());
expirationTypeDropdown.setTranslationKeyPrefix("betterfriends.settings.advancedFriendlist.expiration.types");

this.customExpirationField = new TextFieldWidget();
this.customExpirationField.placeholder(Component.text(I18n.translate(
"betterfriends.settings.advancedFriendlist.expiration.forExample"
) + " 6h, 2d, 4w, 1y"));
this.customExpirationField.setVisible(expirationTypeDropdown.getSelected() == FriendshipExpirationType.CUSTOM_DATE);

ButtonWidget saveButton = ButtonWidget.i18n(
"betterfriends.settings.advancedFriendlist.expiration.button", () -> {
switch (expirationTypeDropdown.getSelected()) {
case ON_SERVER_LEAVE ->
this.handler.scheduleServerLeaveExpiration(this.friend.getUniqueId());
case ON_MUTE_EXPIRATION ->
this.handler.scheduleVoiceUnmuteExpiration(this.friend.getUniqueId());
case CUSTOM_DATE -> {
long duration = getDuration(this.customExpirationField.getText());
this.handler.scheduleCustomExpiration(
this.friend.getUniqueId(),
System.currentTimeMillis() + duration
);
}
}
Laby.references().chatExecutor().displayClientMessage(
Component.empty()
.append(BetterFriendsAddon.getPrefix())
.append(Component.translatable(
"betterfriends.settings.advancedFriendlist.expiration.success",
NamedTextColor.GREEN
))
);
Laby.labyAPI().minecraft().minecraftWindow().displayScreen((ScreenInstance) null);
});
Runnable updateButtonVisibility = () -> saveButton.setEnabled(
expirationTypeDropdown.getSelected() != FriendshipExpirationType.CUSTOM_DATE
|| getDuration(this.customExpirationField.getText()) > 0
);
expirationTypeDropdown.setChangeListener((type) -> {
this.customExpirationField.setVisible(type == FriendshipExpirationType.CUSTOM_DATE);
updateButtonVisibility.run();
});
this.customExpirationField.updateListener((text) -> updateButtonVisibility.run());
updateButtonVisibility.run();

window.addContent(profileWrapper);
window.addContent(content);

content.addChild(expirationTypeDropdown);
content.addChild(this.customExpirationField);
content.addChild(saveButton);

this.document.addChild(window);
}

public static long getDuration(String timeArg) {
String format;
long duration;
try {
format = timeArg.substring(timeArg.length() - 1);
duration = Integer.parseInt(timeArg.substring(0, timeArg.length() - 1));
} catch (NumberFormatException | IndexOutOfBoundsException e) {
return -1;
}

return switch (format) {
case "s" -> duration * 1000;
case "m" -> duration * 1000 * 60;
case "h" -> duration * 1000 * 60 * 60;
case "d" -> duration * 1000 * 60 * 60 * 24;
case "w" -> duration * 1000 * 60 * 60 * 24 * 7;
case "y" -> duration * 1000 * 60 * 60 * 24 * 7 * 52;
default -> -1;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@
import net.labymod.api.client.gui.screen.widget.widgets.layout.list.VerticalListWidget;
import net.labymod.api.event.Phase;
import net.labymod.api.event.Subscribe;
import net.labymod.api.event.labymod.labyconnect.LabyConnectStateUpdateEvent;
import net.labymod.api.event.labymod.labyconnect.session.friend.LabyConnectFriendAddEvent;
import net.labymod.api.event.labymod.labyconnect.session.friend.LabyConnectFriendPinUpdateEvent;
import net.labymod.api.event.labymod.labyconnect.session.friend.LabyConnectFriendRemoveEvent;
import net.labymod.api.event.labymod.labyconnect.session.friend.LabyConnectFriendStatusEvent;
import net.labymod.api.event.labymod.labyconnect.session.login.LabyConnectFriendAddBulkEvent;
import net.labymod.api.event.labymod.user.UserUpdateDataEvent;
import net.labymod.api.labyconnect.LabyConnectSession;
Expand Down Expand Up @@ -202,6 +205,27 @@ public void onLabyConnectFriendRemove(LabyConnectFriendRemoveEvent event) {
);
}

@Subscribe
public void onLabyConnectStateUpdate(LabyConnectStateUpdateEvent event) {
this.initializeFriendlist(true);
}

@Subscribe
public void onLabyConnectStateUpdate(LabyConnectFriendPinUpdateEvent event) {
this.entries.reInitializeChildrenIf(
FriendWidget.class,
widget -> widget.getFriend().getUniqueId().equals(event.friend().getUniqueId())
);
}

@Subscribe
public void onLabyConnectFriendStatus(LabyConnectFriendStatusEvent event) {
this.entries.reInitializeChildrenIf(
FriendWidget.class,
widget -> widget.getFriend().getUniqueId().equals(event.friend().getUniqueId())
);
}

private enum SortingStrategy {
ONLINE_STATUS((a, b) -> Boolean.compare(b.isOnline(), a.isOnline())),
ROLE((a, b) -> Integer.compare(
Expand Down
Loading