diff --git a/src/chatty/Chatty.java b/src/chatty/Chatty.java index 4b32a2046..4b037192d 100644 --- a/src/chatty/Chatty.java +++ b/src/chatty/Chatty.java @@ -53,7 +53,7 @@ public class Chatty { * by points. May contain a single "b" for beta versions, which are counted * as older (so 0.8.7b4 is older than 0.8.7). */ - public static final String VERSION = "0.9.3.136"; + public static final String VERSION = "0.9.3.137"; /** * Enable Version Checker (if you compile and distribute this yourself, you diff --git a/src/chatty/Helper.java b/src/chatty/Helper.java index 892703aa8..0c348ebf9 100644 --- a/src/chatty/Helper.java +++ b/src/chatty/Helper.java @@ -669,7 +669,7 @@ public static String makeBanInfo(long duration, String reason, return banInfo; } - public static String makeBanCommand(User user, long duration, String reason, String id) { + public static String makeBanCommand(User user, long duration, String id) { if (duration > 0) { return StringUtil.concats("timeout", user.getName(), duration).trim(); } @@ -753,4 +753,33 @@ public static String encodeFilename2(String input) { return input.replaceAll("[%\\.\"\\*/:<>\\?\\\\\\|\\+,\\.;=\\[\\]]", "_"); } + /** + * Returns commands split up by '|' and trimmed for leading and trailing + * whitespace. Only non-empty commands are included. + * + * Use '||' to use the '|' character literally. + * + * Example: '/chain /echo first | /echo second || third' + * Returns: '/echo first' and '/echo second | third' + * + * @param input + * @return + */ + public static List getChainedCommands(String input) { + if (StringUtil.isNullOrEmpty(input)) { + return new ArrayList<>(); + } + List result = new ArrayList<>(); + // A '|' not preceeded or followed by '|' + String[] split = input.split("(?(), Setting.LIST); // Message Colors @@ -611,7 +613,7 @@ void defineSettings() { /** * Tries to load the settings from file. */ - void loadSettingsFromFile() { + public void loadSettingsFromFile() { settings.loadSettingsFromJson(); } @@ -620,7 +622,7 @@ void loadSettingsFromFile() { * performed in (seconds). The backup manager will decide whether to * actually make a backup. */ - void backupFiles() { + public void backupFiles() { long backupDelay = DateTime.DAY * settings.getLong("backupDelay"); backup.performBackup((int)backupDelay, (int)settings.getLong("backupCount")); } @@ -633,7 +635,7 @@ void backupFiles() { * * @param args Map with commandline settings, key=value pairs */ - void loadCommandLineSettings(Map args) { + public void loadCommandLineSettings(Map args) { for (String key : args.keySet()) { // Go through all commandline options String value = args.get(key); @@ -687,7 +689,7 @@ void loadCommandLineSettings(Map args) { /** * Override some now unused settings or change settings on version change. */ - void overrideSettings() { + public void overrideSettings() { settings.setBoolean("ignoreJoinsParts", false); if (switchedFromVersionBefore("0.7.2")) { String value = settings.getString("timeoutButtons"); @@ -790,10 +792,16 @@ void overrideSettings() { // Turn off Highlight Background if using dark background (if not loaded // from the settings yet) Color bgColor = HtmlColors.decode(settings.getString("backgroundColor")); - if (HtmlColors.getBrightness(bgColor) < 128 && !settings.isValueSet("highlightBackground")) { + if (ColorCorrection.isDarkColor(bgColor) && !settings.isValueSet("highlightBackground")) { settings.setBoolean("highlightBackground", false); } + if (switchedFromVersionBefore("0.9.3-b5")) { + if (!settings.getBoolean("colorCorrection")) { + settings.setString("nickColorCorrection", "off"); + } + } + overrideHotkeySettings(); } diff --git a/src/chatty/TwitchClient.java b/src/chatty/TwitchClient.java index ef72f9ab2..af6a86f8c 100644 --- a/src/chatty/TwitchClient.java +++ b/src/chatty/TwitchClient.java @@ -21,6 +21,7 @@ import chatty.gui.GuiUtil; import chatty.gui.LaF; import chatty.gui.MainGui; +import chatty.gui.components.textpane.ModLogInfo; import chatty.gui.components.updating.Stuff; import chatty.splash.Splash; import chatty.util.BTTVEmotes; @@ -66,6 +67,7 @@ import chatty.util.settings.Settings; import chatty.util.settings.SettingsListener; import chatty.util.srl.SpeedrunsLive; +import java.awt.Color; import java.awt.Point; import java.awt.SplashScreen; import java.io.File; @@ -124,6 +126,7 @@ public class TwitchClient { public final TwitchApi api; public final chatty.util.api.pubsub.Manager pubsub; + private final PubSubResults pubsubListener = new PubSubResults(); public final TwitchEmotes twitchemotes; @@ -229,7 +232,7 @@ public TwitchClient(Map args) { Language.setLanguage(settings.getString("language")); pubsub = new chatty.util.api.pubsub.Manager( - settings.getString("pubsub"), new PubSubResults(), api); + settings.getString("pubsub"), pubsubListener, api); frankerFaceZ = new FrankerFaceZ(new EmoticonsListener(), settings); @@ -240,7 +243,7 @@ public TwitchClient(Map args) { usercolorManager = new UsercolorManager(settings); usericonManager = new UsericonManager(settings); - customCommands = new CustomCommands(settings, api); + customCommands = new CustomCommands(settings, api, this); customCommands.loadFromSettings(); botNameManager = new BotNameManager(settings); settings.addSettingsListener(new SettingSaveListener()); @@ -457,7 +460,7 @@ private void checkNewVersion() { */ private void createTestUser(String name, String channel) { testUser = new User(name, name, Room.createRegular(channel)); - testUser.setColor("blue"); + testUser.setColor(new Color(94, 0, 211)); testUser.setGlobalMod(true); //testUser.setBot(true); //testUser.setTurbo(true); @@ -725,7 +728,10 @@ public void textInput(Room room, String text, Parameters commandParameters) { return; } String channel = room.getChannel(); - if (text.startsWith("/")) { + if (text.startsWith("//")) { + anonCustomCommand(room, text.substring(1), commandParameters); + } + else if (text.startsWith("/")) { commandInput(room, text, commandParameters); } else { @@ -1160,6 +1166,16 @@ else if (c.command(channel, command, parameter, null)) { else if (g.commandGui(channel, command, parameter)) { // Already done if true :P } + + else if (command.equals("chain")) { + List commands = Helper.getChainedCommands(parameter); + if (commands.isEmpty()) { + g.printSystem("No valid commands"); + } + for (String chainedCommand : commands) { + textInput(room, chainedCommand, parameters); + } + } // Has to be tested last, so regular commands with the same name take // precedence @@ -1372,20 +1388,24 @@ else if (command.equals("bantest")) { } else if (command.equals("psdisconnect")) { pubsub.disconnect(); } else if (command.equals("modaction")) { + String by = "Blahfasel"; String action = "timeout"; List args = new ArrayList<>(); if (parameter != null && !parameter.isEmpty()) { String[] split = parameter.split(" "); - action = split[0]; - for (int i=1;i args = new ArrayList<>(); args.add("tduva"); @@ -1441,6 +1461,14 @@ public void run() { } } + private void anonCustomCommand(Room room, String text, Parameters parameters) { + CustomCommand command = CustomCommand.parse(text); + if (parameters == null) { + parameters = Parameters.create(null); + } + anonCustomCommand(room, command, parameters); + } + public void anonCustomCommand(Room room, CustomCommand command, Parameters parameters) { if (command.hasError()) { g.printLine("Custom command invalid: "+command.getError()); @@ -1573,12 +1601,17 @@ private void commandServer(String parameter) { * * @param channel */ - public void commandJoinChannel(String channel) { - if (channel == null) { + public void commandJoinChannel(String channelString) { + if (channelString == null) { g.printLine("A channel to join needs to be specified."); } else { - channel = StringUtil.toLowerCase(channel.trim()); - c.joinChannel(channel); + String[] channelList = channelString.split(" "); + for (String channel: channelList) + { + channel = StringUtil.toLowerCase(channel.trim()); + c.joinChannel(channel); + } + } } @@ -1948,12 +1981,21 @@ public void messageReceived(Message message) { if (message.data != null && message.data instanceof ModeratorActionData) { ModeratorActionData data = (ModeratorActionData)message.data; if (data.stream != null) { + String channel = Helper.toChannel(data.stream); g.printModerationAction(data, data.created_by.equals(c.getUsername())); chatLog.modAction(data); - User modUser = c.getUser(Helper.toChannel(data.stream), data.created_by); - modUser.addModAction(data.getCommandAndParameters()); + User modUser = c.getUser(channel, data.created_by); + modUser.addModAction(data); g.updateUserinfo(modUser); + + String bannedUsername = ModLogInfo.getBannedUsername(data); + if (bannedUsername != null) { + // If this is actually a ban, add info to banned user + User bannedUser = c.getUser(channel, bannedUsername); + bannedUser.addBanInfo(data); + g.updateUserinfo(bannedUser); + } } } } @@ -2859,6 +2901,10 @@ public ChannelState getChannelState(String channel) { return c.getChannelState(channel); } + public Collection getOpenChannels() { + return c.getOpenChannels(); + } + private class ChannelStateUpdater implements ChannelStateListener { @Override diff --git a/src/chatty/TwitchConnection.java b/src/chatty/TwitchConnection.java index e92443815..eb85214e9 100644 --- a/src/chatty/TwitchConnection.java +++ b/src/chatty/TwitchConnection.java @@ -1352,6 +1352,10 @@ public void onChannelCommand(MsgTags tags, String nick, } if (!tags.isEmpty("room-id")) { listener.onRoomId(channel, tags.get("room-id")); + // Set id for room (this should not run too often to + // worry about object creation and stuff) + Room roomWithId = Room.createRegularWithId(channel, tags.get("room-id")); + rooms.addRoom(roomWithId); } } } else if (command.equals("SERVERCHANGE")) { diff --git a/src/chatty/User.java b/src/chatty/User.java index 79c3b7d15..ba9e3a1b4 100644 --- a/src/chatty/User.java +++ b/src/chatty/User.java @@ -4,12 +4,16 @@ import chatty.gui.colors.UsercolorManager; import chatty.util.api.usericons.Usericon; import chatty.util.api.usericons.UsericonManager; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.NamedColor; +import chatty.gui.components.textpane.ModLogInfo; +import chatty.util.Debugging; import chatty.util.StringUtil; +import chatty.util.api.pubsub.ModeratorActionData; import java.awt.Color; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -289,11 +293,13 @@ public synchronized void addMessage(String line, boolean action, String id, Stri * @param id */ public synchronized void addBan(long duration, String reason, String id) { - addLine(new BanMessage(System.currentTimeMillis(), duration, reason, id)); + addLine(new BanMessage(System.currentTimeMillis(), duration, reason, id, null)); + replayCachedBanInfo(); } public synchronized void addMsgDeleted(String targetMsgId, String msg) { - addLine(new MsgDeleted(System.currentTimeMillis(), targetMsgId, msg)); + addLine(new MsgDeleted(System.currentTimeMillis(), targetMsgId, msg, null)); + replayCachedBanInfo(); } public synchronized void addSub(String message, String text) { @@ -304,8 +310,67 @@ public synchronized void addInfo(String message, String text) { addLine(new InfoMessage(System.currentTimeMillis(), message, text)); } - public synchronized void addModAction(String commandAndParameters) { - addLine(new ModAction(System.currentTimeMillis(), commandAndParameters)); + public synchronized void addModAction(ModeratorActionData data) { + addLine(new ModAction(System.currentTimeMillis(), data.getCommandAndParameters())); + } + + private final List cachedBanInfo = new ArrayList<>(); + + /** + * Add ban info (by/reason) for this user. Must be for this user. + * + * @param data + */ + public synchronized void addBanInfo(ModeratorActionData data) { + if (!addBanInfoNow(data)) { + // Adding failed, cache and wait to see if it works later + Debugging.println("modlog", "[UserModLogInfo] Caching: %s", data.getCommandAndParameters()); + cachedBanInfo.add(data); + } + } + + private static final int BAN_INFO_WAIT = 500; + + private synchronized void replayCachedBanInfo() { + Debugging.println("modlog", "[UserModLogInfo] Replaying: %s", cachedBanInfo); + Iterator it = cachedBanInfo.iterator(); + while (it.hasNext()) { + ModeratorActionData data = it.next(); + if (System.currentTimeMillis() - data.created_at > BAN_INFO_WAIT) { + it.remove(); + Debugging.println("modlog", "[UserModLogInfo] Abandoned: %s", data); + } else { + if (addBanInfoNow(data)) { + it.remove(); + Debugging.println("modlog", "[UserModLogInfo] Added: %s", data); + } + } + } + } + + private synchronized boolean addBanInfoNow(ModeratorActionData data) { + String command = ModLogInfo.makeCommand(data); + for (int i=messages.size() - 1; i>=0; i--) { + Message m = messages.get(i); + // Too old, abort (associated message might not be here yet) + if (System.currentTimeMillis() - m.getTime() > BAN_INFO_WAIT) { + return false; + } + if (m instanceof BanMessage) { + BanMessage bm = (BanMessage)m; + if (command.equals(Helper.makeBanCommand(this, bm.duration, bm.id))) { + messages.set(i, bm.addModLogInfo(data.created_by, ModLogInfo.getReason(data))); + return true; + } + } else if (m instanceof MsgDeleted) { + MsgDeleted dm = (MsgDeleted)m; + if (command.equals(Helper.makeBanCommand(this, -2, dm.targetMsgId))) { + messages.set(i, dm.addModLogInfo(data.created_by)); + return true; + } + } + } + return false; } public synchronized void addAutoModMessage(String line, String id) { @@ -495,7 +560,8 @@ public synchronized boolean hasCustomColor() { /** * Returns the corrected color for this nick. This is the original Twitch * Chat color (either received from chat or default), which was corrected - * for better readability against the current background. + * for better readability against the current background. It may be the same + * as the original color. * * @return The corrected color or null if none was set */ @@ -503,6 +569,12 @@ public synchronized Color getCorrectedColor() { return correctedColor; } + /** + * This merely means that the color has gone through color correction, it + * may not be different from the original color. + * + * @return + */ public synchronized boolean hasCorrectedColor() { return hasCorrectedColor; } @@ -924,12 +996,23 @@ public static class BanMessage extends Message { public final long duration; public final String reason; public final String id; + public final String by; - public BanMessage(Long time, long duration, String reason, String id) { + public BanMessage(Long time, long duration, String reason, String id, + String by) { super(BAN, time); this.duration = duration; this.reason = reason; this.id = id; + this.by = by; + } + + public BanMessage addModLogInfo(String by, String reason) { + if (reason == null) { + // Probably not set anyway, but just in case + reason = this.reason; + } + return new BanMessage(getTime(), duration, reason, id, by); } } @@ -938,11 +1021,17 @@ public static class MsgDeleted extends Message { public final String targetMsgId; public final String msg; + public final String by; - public MsgDeleted(Long time, String targetMsgId, String msg) { + public MsgDeleted(Long time, String targetMsgId, String msg, String by) { super(MSG_DELETED, time); this.targetMsgId = targetMsgId; this.msg = msg; + this.by = by; + } + + public MsgDeleted addModLogInfo(String by) { + return new MsgDeleted(getTime(), targetMsgId, msg, by); } } diff --git a/src/chatty/gui/Highlighter.java b/src/chatty/gui/Highlighter.java index e95cd156a..9cd2aba02 100644 --- a/src/chatty/gui/Highlighter.java +++ b/src/chatty/gui/Highlighter.java @@ -1,6 +1,7 @@ package chatty.gui; +import chatty.util.colors.HtmlColors; import chatty.Addressbook; import chatty.Helper; import chatty.User; diff --git a/src/chatty/gui/MainGui.java b/src/chatty/gui/MainGui.java index 67b0d099f..f1f3b49d7 100644 --- a/src/chatty/gui/MainGui.java +++ b/src/chatty/gui/MainGui.java @@ -1,6 +1,7 @@ package chatty.gui; +import chatty.util.colors.HtmlColors; import chatty.Addressbook; import chatty.gui.components.textpane.UserMessage; import chatty.gui.components.DebugWindow; diff --git a/src/chatty/gui/StyleManager.java b/src/chatty/gui/StyleManager.java index f67a8ee89..5d7a7db71 100644 --- a/src/chatty/gui/StyleManager.java +++ b/src/chatty/gui/StyleManager.java @@ -1,9 +1,12 @@ package chatty.gui; +import chatty.util.colors.HtmlColors; import chatty.gui.components.textpane.ChannelTextPane.Attribute; import chatty.gui.components.textpane.ChannelTextPane.Setting; import chatty.gui.components.textpane.MyStyleConstants; +import chatty.util.colors.ColorCorrectionNew; +import chatty.util.colors.ColorCorrector; import chatty.util.settings.Settings; import java.awt.Color; import java.awt.Component; @@ -43,10 +46,10 @@ public class StyleManager implements StyleServer { "inputFont","emoteScale", "emoteMaxHeight", "botBadgeEnabled", "filterCombiningCharacters", "pauseChatOnMouseMove", "pauseChatOnMouseMoveCtrlRequired", "showAnimatedEmotes", - "colorCorrection", "banReasonAppended", "banDurationAppended", + "banReasonAppended", "banDurationAppended", "banDurationMessage", "banReasonMessage", "displayNamesMode", "paragraphSpacing", "bufferSizes", "userlistFont", - "showImageTooltips", "highlightMatches", + "showImageTooltips", "highlightMatches", "nickColorCorrection", "inputHistoryMultirowRequireCtrl" // Not delievered through this )); @@ -68,6 +71,8 @@ public class StyleManager implements StyleServer { private Color searchResultColor2; private Color infoColor; + private ColorCorrector colorCorrector; + private final Settings settings; private final Component dummyComponent = new JDialog(); @@ -157,7 +162,6 @@ private void makeStyles() { addBooleanSetting(Setting.PAUSE_ON_MOUSEMOVE, "pauseChatOnMouseMove"); addBooleanSetting(Setting.PAUSE_ON_MOUSEMOVE_CTRL_REQUIRED, "pauseChatOnMouseMoveCtrlRequired"); addBooleanSetting(Setting.EMOTICONS_SHOW_ANIMATED, "showAnimatedEmotes"); - addBooleanSetting(Setting.COLOR_CORRECTION, "colorCorrection"); addLongSetting(Setting.BOTTOM_MARGIN, "bottomMargin"); // Deleted Messages Settings String deletedMessagesMode = settings.getString("deletedMessagesMode"); @@ -169,6 +173,8 @@ private void makeStyles() { } other.addAttribute(Setting.DELETED_MESSAGES_MODE, deletedMessagesModeNumeric); addLongSetting(Setting.DISPLAY_NAMES_MODE, "displayNamesMode"); + + colorCorrector = ColorCorrector.get(settings.getString("nickColorCorrection")); } private void addBooleanSetting(Setting key, String name) { @@ -260,5 +266,10 @@ public SimpleDateFormat getTimestampFormat() { } return null; } + + @Override + public ColorCorrector getColorCorrector() { + return colorCorrector; + } } diff --git a/src/chatty/gui/StyleServer.java b/src/chatty/gui/StyleServer.java index 4ce9e215a..57fdd9f12 100644 --- a/src/chatty/gui/StyleServer.java +++ b/src/chatty/gui/StyleServer.java @@ -1,6 +1,7 @@ package chatty.gui; +import chatty.util.colors.ColorCorrector; import java.awt.Color; import java.awt.Font; import java.text.SimpleDateFormat; @@ -17,4 +18,5 @@ public interface StyleServer { public MutableAttributeSet getStyle(String type); public Font getFont(String type); public SimpleDateFormat getTimestampFormat(); + public ColorCorrector getColorCorrector(); } diff --git a/src/chatty/gui/colors/MsgColorManager.java b/src/chatty/gui/colors/MsgColorManager.java index 286ca69e1..58b16aacc 100644 --- a/src/chatty/gui/colors/MsgColorManager.java +++ b/src/chatty/gui/colors/MsgColorManager.java @@ -4,7 +4,7 @@ import chatty.Addressbook; import chatty.User; import chatty.gui.Highlighter.HighlightItem; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.util.settings.Settings; import java.awt.Color; import java.util.ArrayList; diff --git a/src/chatty/gui/colors/UsercolorItem.java b/src/chatty/gui/colors/UsercolorItem.java index ec9311b11..030743ad9 100644 --- a/src/chatty/gui/colors/UsercolorItem.java +++ b/src/chatty/gui/colors/UsercolorItem.java @@ -2,7 +2,7 @@ package chatty.gui.colors; import chatty.Helper; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import java.awt.Color; import java.util.Arrays; import java.util.HashSet; diff --git a/src/chatty/gui/colors/UsercolorManager.java b/src/chatty/gui/colors/UsercolorManager.java index abdddab8b..b7d8318d8 100644 --- a/src/chatty/gui/colors/UsercolorManager.java +++ b/src/chatty/gui/colors/UsercolorManager.java @@ -3,7 +3,7 @@ import chatty.Helper; import chatty.User; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.util.settings.Settings; import java.awt.Color; import java.util.ArrayList; diff --git a/src/chatty/gui/components/AutoCompletion.java b/src/chatty/gui/components/AutoCompletion.java index 7d3c17fbb..255504f8e 100644 --- a/src/chatty/gui/components/AutoCompletion.java +++ b/src/chatty/gui/components/AutoCompletion.java @@ -2,7 +2,7 @@ package chatty.gui.components; import chatty.Helper; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.components.AutoCompletionServer.CompletionItems; import chatty.util.StringUtil; import java.awt.Color; diff --git a/src/chatty/gui/components/DebugWindow.java b/src/chatty/gui/components/DebugWindow.java index 94cd009e5..138bd94a1 100644 --- a/src/chatty/gui/components/DebugWindow.java +++ b/src/chatty/gui/components/DebugWindow.java @@ -109,7 +109,7 @@ public void printLinePubSub(String line) { private void printLine(JTextArea text, String line) { try { Document doc = text.getDocument(); - doc.insertString(doc.getLength(), "["+DateTime.currentTime()+"] "+line+"\n", null); + doc.insertString(doc.getLength(), "["+DateTime.currentTimeExact()+"] "+line+"\n", null); if (autoscroll.isSelected()) { text.setCaretPosition(doc.getLength()); } diff --git a/src/chatty/gui/components/EmotesDialog.java b/src/chatty/gui/components/EmotesDialog.java index ef2cef484..cc7907136 100644 --- a/src/chatty/gui/components/EmotesDialog.java +++ b/src/chatty/gui/components/EmotesDialog.java @@ -5,7 +5,7 @@ import chatty.Helper; import chatty.util.ForkUtil; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LaF; import chatty.gui.MainGui; import chatty.gui.components.menus.ContextMenuListener; diff --git a/src/chatty/gui/components/LinkLabel.java b/src/chatty/gui/components/LinkLabel.java index 69380c1e6..85461bae5 100644 --- a/src/chatty/gui/components/LinkLabel.java +++ b/src/chatty/gui/components/LinkLabel.java @@ -1,7 +1,7 @@ package chatty.gui.components; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LaF; import java.awt.Color; import java.awt.Font; diff --git a/src/chatty/gui/components/admin/SelectCommunityDialog.java b/src/chatty/gui/components/admin/SelectCommunityDialog.java index 176c8684a..8fafd3863 100644 --- a/src/chatty/gui/components/admin/SelectCommunityDialog.java +++ b/src/chatty/gui/components/admin/SelectCommunityDialog.java @@ -3,7 +3,7 @@ import chatty.Helper; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.MainGui; import chatty.gui.UrlOpener; import chatty.lang.Language; diff --git a/src/chatty/gui/components/help/help.html b/src/chatty/gui/components/help/help.html index 478d27693..f95f3d2cb 100644 --- a/src/chatty/gui/components/help/help.html +++ b/src/chatty/gui/components/help/help.html @@ -5,7 +5,7 @@ -

Chatty (Version: 0.9.3-b4)

+

Chatty (Version: 0.9.3-b5)

diff --git a/src/chatty/gui/components/settings/ColorChooser.java b/src/chatty/gui/components/settings/ColorChooser.java index ec76e898e..57d8126d7 100644 --- a/src/chatty/gui/components/settings/ColorChooser.java +++ b/src/chatty/gui/components/settings/ColorChooser.java @@ -1,7 +1,7 @@ package chatty.gui.components.settings; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.lang.Language; import java.awt.*; import java.awt.event.ActionEvent; diff --git a/src/chatty/gui/components/settings/ColorSetting.java b/src/chatty/gui/components/settings/ColorSetting.java index ea3eea9e1..79eb19479 100644 --- a/src/chatty/gui/components/settings/ColorSetting.java +++ b/src/chatty/gui/components/settings/ColorSetting.java @@ -2,7 +2,7 @@ package chatty.gui.components.settings; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.lang.Language; import java.awt.Color; import java.awt.Dimension; diff --git a/src/chatty/gui/components/settings/ColorSettings.java b/src/chatty/gui/components/settings/ColorSettings.java index bd5613b57..7a966620c 100644 --- a/src/chatty/gui/components/settings/ColorSettings.java +++ b/src/chatty/gui/components/settings/ColorSettings.java @@ -272,6 +272,26 @@ public ColorSettings(SettingsDialog d, Settings settings) { false // highlightBackground }); + presets.addPreset("Dark Smooth", + new String[]{ + "#323232", // backgroundColor + "LightGrey", // foregroundColor + "Aquamarine", // infoColor + "#A0A0A0", // compactColor + "#FFFFFF", // highlightColor + "#222222", // inputBackgroundColor + "#FFFFFF", // inputForegroundColor + "DarkSlateBlue", // searchResultColor + "SlateBlue", // searchResultColor2 + "#3B3B3B", // backgroundColor2 + "#5C0000", // highlightBackgroundColor + "#DFDFDF"}, // separatorColor + new Boolean[]{ + true, // alternateBackground + false, // messageSeparator + true // highlightBackground + }); + presets.init(); //======== diff --git a/src/chatty/gui/components/settings/CompletionSettings.java b/src/chatty/gui/components/settings/CompletionSettings.java index c4e8c8ecb..b42f4e4b1 100644 --- a/src/chatty/gui/components/settings/CompletionSettings.java +++ b/src/chatty/gui/components/settings/CompletionSettings.java @@ -71,12 +71,16 @@ public CompletionSettings(SettingsDialog d) { localized.add(d.addSimpleBooleanSetting("completionPreferUsernames"), d.makeGbc(0, 2, 4, 1, GridBagConstraints.WEST)); - localized.add(d.addSimpleBooleanSetting("completionAllNameTypes"), + JCheckBox completionAllNameTypes = d.addSimpleBooleanSetting("completionAllNameTypes"); + localized.add(completionAllNameTypes, d.makeGbcCloser(0, 3, 4, 1, GridBagConstraints.WEST)); - localized.add(d.addSimpleBooleanSetting("completionAllNameTypesRestriction"), + JCheckBox completionAllNameTypesRestriction = d.addSimpleBooleanSetting("completionAllNameTypesRestriction"); + localized.add(completionAllNameTypesRestriction, d.makeGbcSub(0, 4, 4, 1, GridBagConstraints.WEST)); + SettingsUtil.addSubsettings(completionAllNameTypes, completionAllNameTypesRestriction); + //=========== // Appearance //=========== @@ -98,14 +102,7 @@ public CompletionSettings(SettingsDialog d) { popupSettings.add(common, d.makeGbcCloser(0, 1, 2, 1, GridBagConstraints.WEST)); - // Popup checkbox state - common.setEnabled(false); - max.setEnabled(false); - popup.addItemListener(e -> { - common.setEnabled(popup.isSelected()); - max.setEnabled(popup.isSelected()); - } - ); + SettingsUtil.addSubsettings(popup, max, common); appearance.add(popupSettings, d.makeGbcSub(0, 1, 2, 1, GridBagConstraints.WEST)); @@ -129,7 +126,7 @@ public CompletionSettings(SettingsDialog d) { d.makeGbc(0, 3, 1, 1)); appearance.add( - d.addComboStringSetting("completionSearch", 4, false, new String[]{"start", "words", "anywhere"}), + d.addComboStringSetting("completionSearch", false, new String[]{"start", "words", "anywhere"}), d.makeGbc(1, 3, 1, 1, GridBagConstraints.WEST)); //================== diff --git a/src/chatty/gui/components/settings/EmoteSettings.java b/src/chatty/gui/components/settings/EmoteSettings.java index 44045d264..c3061279a 100644 --- a/src/chatty/gui/components/settings/EmoteSettings.java +++ b/src/chatty/gui/components/settings/EmoteSettings.java @@ -123,14 +123,7 @@ protected EmoteSettings(SettingsDialog d) { other.add(ffzEvent, d.makeGbcCloser(1, 2, 1, 1, GridBagConstraints.WEST)); - // FFZ checkbox status - ffzMod.setEnabled(false); - ffzEvent.setEnabled(false); - ffz.addItemListener(e -> { - ffzMod.setEnabled(ffz.isSelected()); - ffzEvent.setEnabled(ffz.isSelected()); - } - ); + SettingsUtil.addSubsettings(ffz, ffzMod, ffzEvent); //======= // Emoji diff --git a/src/chatty/gui/components/settings/FilterSettings.java b/src/chatty/gui/components/settings/FilterSettings.java index ea1ef2b1a..7ca46192b 100644 --- a/src/chatty/gui/components/settings/FilterSettings.java +++ b/src/chatty/gui/components/settings/FilterSettings.java @@ -1,21 +1,11 @@ package chatty.gui.components.settings; -import chatty.gui.GuiUtil; import chatty.lang.Language; -import chatty.util.StringUtil; import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.List; -import javax.swing.JButton; -import javax.swing.JDialog; -import javax.swing.JLabel; +import javax.swing.JCheckBox; import javax.swing.JPanel; -import static javax.swing.WindowConstants.HIDE_ON_CLOSE; -import javax.swing.text.Highlighter; /** * @@ -47,7 +37,8 @@ public FilterSettings(SettingsDialog d) { gbc = d.makeGbc(0,0,1,1); gbc.insets.bottom -= 3; gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("filterEnabled"), gbc); + JCheckBox filterEnabled = d.addSimpleBooleanSetting("filterEnabled"); + base.add(filterEnabled, gbc); gbc = d.makeGbc(0,1,1,1); gbc.insets = new Insets(5,10,5,5); @@ -62,6 +53,7 @@ public FilterSettings(SettingsDialog d) { gbc.weighty = 1; base.add(items, gbc); + SettingsUtil.addSubsettings(filterEnabled, items); } } diff --git a/src/chatty/gui/components/settings/HighlightSettings.java b/src/chatty/gui/components/settings/HighlightSettings.java index d608272e2..0edf4dc46 100644 --- a/src/chatty/gui/components/settings/HighlightSettings.java +++ b/src/chatty/gui/components/settings/HighlightSettings.java @@ -11,6 +11,7 @@ import java.awt.event.ActionListener; import java.util.List; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; @@ -66,33 +67,39 @@ public HighlightSettings(SettingsDialog d) { gbc = d.makeGbc(0,0,1,1); gbc.insets.bottom -= 3; gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("highlightEnabled"), gbc); + JCheckBox highlightEnabled = d.addSimpleBooleanSetting("highlightEnabled"); + base.add(highlightEnabled, gbc); Insets settingInsets = new Insets(1,14,1,4); gbc = d.makeGbc(0,1,1,1); gbc.anchor = GridBagConstraints.WEST; gbc.insets = settingInsets; - base.add(d.addSimpleBooleanSetting("highlightUsername"), gbc); + JCheckBox highlightUsername = d.addSimpleBooleanSetting("highlightUsername"); + base.add(highlightUsername, gbc); gbc = d.makeGbc(1,1,1,1); gbc.insets = settingInsets; gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("highlightNextMessages"), gbc); + JCheckBox highlightNextMessages = d.addSimpleBooleanSetting("highlightNextMessages"); + base.add(highlightNextMessages, gbc); gbc = d.makeGbc(0,2,1,1); gbc.insets = settingInsets; gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("highlightOwnText"), gbc); + JCheckBox highlightOwnText = d.addSimpleBooleanSetting("highlightOwnText"); + base.add(highlightOwnText, gbc); gbc = d.makeGbc(1,2,1,1); gbc.insets = settingInsets; gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("highlightIgnored"), gbc); + JCheckBox highlightIgnored = d.addSimpleBooleanSetting("highlightIgnored"); + base.add(highlightIgnored, gbc); gbc = d.makeGbc(0, 3, 2, 1, GridBagConstraints.WEST); gbc.insets = settingInsets; - base.add(d.addSimpleBooleanSetting("highlightMatches"), gbc); + JCheckBox highlightMatches = d.addSimpleBooleanSetting("highlightMatches"); + base.add(highlightMatches, gbc); gbc = d.makeGbc(0,5,2,1); gbc.insets = new Insets(5,10,5,5); @@ -131,6 +138,11 @@ public HighlightSettings(SettingsDialog d) { gbc.insets = new Insets(1,5,5,30); gbc.fill = GridBagConstraints.HORIZONTAL; base.add(highlightBlacklistButton, gbc); + + SettingsUtil.addSubsettings(highlightEnabled, highlightUsername, + highlightNextMessages, highlightOwnText, highlightIgnored, + highlightMatches, items, noHighlightUsersButton, + highlightBlacklistButton); } private static class NoHighlightUsers extends JDialog { diff --git a/src/chatty/gui/components/settings/HotkeySettings.java b/src/chatty/gui/components/settings/HotkeySettings.java index e20b5c183..29485fdba 100644 --- a/src/chatty/gui/components/settings/HotkeySettings.java +++ b/src/chatty/gui/components/settings/HotkeySettings.java @@ -26,7 +26,7 @@ public HotkeySettings(SettingsDialog d) { GridBagConstraints gbc; - gbc = d.makeGbc(0, 0, 1, 1); + gbc = d.makeGbc(0, 1, 1, 1); gbc.anchor = GridBagConstraints.WEST; main.add(d.addSimpleBooleanSetting("globalHotkeysEnabled", "Enable global hotkeys", @@ -34,7 +34,7 @@ public HotkeySettings(SettingsDialog d) { data = new HotkeyEditor(d); data.setPreferredSize(new Dimension(1,270)); - gbc = d.makeGbc(0, 1, 1, 1); + gbc = d.makeGbc(0, 0, 1, 1); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; diff --git a/src/chatty/gui/components/settings/IgnoreSettings.java b/src/chatty/gui/components/settings/IgnoreSettings.java index bdafcef39..e387d5f3f 100644 --- a/src/chatty/gui/components/settings/IgnoreSettings.java +++ b/src/chatty/gui/components/settings/IgnoreSettings.java @@ -42,9 +42,8 @@ public IgnoreSettings(SettingsDialog d) { gbc = d.makeGbc(0,0,1,1); gbc.anchor = GridBagConstraints.WEST; - base.add(d.addSimpleBooleanSetting("ignoreEnabled", "Enable Ignore", - "If enabled, shows messages that match the highlight criteria " - + "in another color"), gbc); + JCheckBox ignoredEnabled = d.addSimpleBooleanSetting("ignoreEnabled"); + base.add(ignoredEnabled, gbc); //--------- // Settings @@ -90,11 +89,11 @@ public void actionPerformed(ActionEvent e) { gbc = d.makeGbc(0, 1, 2, 1, GridBagConstraints.EAST); gbc.insets = new Insets(0,12,2,5); - base.add(d.addSimpleBooleanSetting( + JCheckBox ignoreOwnText = d.addSimpleBooleanSetting( "ignoreOwnText", "Check own text for ignoring", - "If enabled, allows messages you wrote yourself to be ignored as well. Good for testing."), - gbc); + "If enabled, allows messages you wrote yourself to be ignored as well. Good for testing."); + base.add(ignoreOwnText, gbc); //---------- // Main List @@ -113,6 +112,8 @@ public void actionPerformed(ActionEvent e) { items.setDataFormatter(input -> input.trim()); base.add(items, gbc); + SettingsUtil.addSubsettings(ignoredEnabled, ignoreOwnText, items); + //------- // Footer //------- diff --git a/src/chatty/gui/components/settings/ItemColorEditor.java b/src/chatty/gui/components/settings/ItemColorEditor.java index c287a4741..ccae256d7 100644 --- a/src/chatty/gui/components/settings/ItemColorEditor.java +++ b/src/chatty/gui/components/settings/ItemColorEditor.java @@ -2,7 +2,7 @@ package chatty.gui.components.settings; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.colors.ColorItem; import java.awt.Color; import java.awt.Component; diff --git a/src/chatty/gui/components/settings/ListSelector.java b/src/chatty/gui/components/settings/ListSelector.java index 2a35fcd57..13d70ba7b 100644 --- a/src/chatty/gui/components/settings/ListSelector.java +++ b/src/chatty/gui/components/settings/ListSelector.java @@ -330,12 +330,15 @@ private void sort() { * edit buttons accordingly. */ private void updateEditButtons() { - boolean somethingIsSelected = list.getSelectedIndex() != -1; - boolean exactlyOneIsSelected = list.getSelectedIndices().length == 1; + boolean somethingIsSelected = list.getSelectedIndex() != -1 && isEnabled(); + boolean exactlyOneIsSelected = list.getSelectedIndices().length == 1 && isEnabled(); remove.setEnabled(somethingIsSelected); change.setEnabled(exactlyOneIsSelected); moveUp.setEnabled(exactlyOneIsSelected); moveDown.setEnabled(exactlyOneIsSelected); + add.setEnabled(isEnabled()); + sort.setEnabled(isEnabled()); + editAll.setEnabled(isEnabled()); } /** @@ -376,8 +379,10 @@ public void setSettingValue(List value) { @Override public void setEnabled(boolean enabled) { + super.setEnabled(enabled); input.setEnabled(enabled); list.setEnabled(enabled); + updateEditButtons(); } public void setDataFormatter(DataFormatter formatter) { diff --git a/src/chatty/gui/components/settings/MessageSettings.java b/src/chatty/gui/components/settings/MessageSettings.java index cfa8603c4..67c85706f 100644 --- a/src/chatty/gui/components/settings/MessageSettings.java +++ b/src/chatty/gui/components/settings/MessageSettings.java @@ -25,8 +25,6 @@ public class MessageSettings extends SettingsPanel { - private final Set timeoutMessageSettings = new HashSet<>(); - public MessageSettings(final SettingsDialog d) { JPanel timeoutSettingsPanel = addTitledPanel(Language.getString("settings.section.deletedMessages"), 0); @@ -46,33 +44,21 @@ public MessageSettings(final SettingsDialog d) { d.makeGbcSub(1, 1, 1, 1, GridBagConstraints.WEST)); final JCheckBox timeoutMessages = d.addSimpleBooleanSetting("showBanMessages"); - timeoutMessages.addItemListener(new ItemListener() { - - @Override - public void itemStateChanged(ItemEvent e) { - for (JCheckBox cb : timeoutMessageSettings) { - cb.setEnabled(timeoutMessages.isSelected()); - } - } - }); timeoutSettingsPanel.add(timeoutMessages, d.makeGbc(0, 3, 2, 1, GridBagConstraints.WEST)); JCheckBox banDuration = d.addSimpleBooleanSetting( "banDurationMessage"); - timeoutMessageSettings.add(banDuration); timeoutSettingsPanel.add(banDuration, d.makeGbcSub(0, 4, 1, 1, GridBagConstraints.WEST)); JCheckBox banReason = d.addSimpleBooleanSetting( "banReasonMessage"); - timeoutMessageSettings.add(banReason); timeoutSettingsPanel.add(banReason, d.makeGbcSub(1, 4, 1, 1, GridBagConstraints.WEST)); JCheckBox timeoutsCombine = d.addSimpleBooleanSetting( "combineBanMessages"); - timeoutMessageSettings.add(timeoutsCombine); timeoutSettingsPanel.add(timeoutsCombine, d.makeGbcSub(0, 5, 1, 1, GridBagConstraints.WEST)); @@ -80,10 +66,7 @@ public void itemStateChanged(ItemEvent e) { "clearChatOnChannelCleared"), d.makeGbc(0, 6, 2, 1, GridBagConstraints.WEST)); - - for (JCheckBox cb : timeoutMessageSettings) { - cb.setEnabled(false); - } + SettingsUtil.addSubsettings(timeoutMessages, banDuration, banReason, timeoutsCombine); //======================== // Other Settings (Panel) diff --git a/src/chatty/gui/components/settings/ModerationSettings.java b/src/chatty/gui/components/settings/ModerationSettings.java index 62f8e8bfc..94ba4e6c4 100644 --- a/src/chatty/gui/components/settings/ModerationSettings.java +++ b/src/chatty/gui/components/settings/ModerationSettings.java @@ -20,8 +20,7 @@ public ModerationSettings(final SettingsDialog d) { JCheckBox showModActions = d.addSimpleBooleanSetting("showModActions"); JCheckBox showModActionsRestrict = d.addSimpleBooleanSetting("showModActionsRestrict"); - showModActions.addItemListener(e -> showModActionsRestrict.setEnabled(showModActions.isSelected())); - showModActionsRestrict.setEnabled(false); + SettingsUtil.addSubsettings(showModActions, showModActionsRestrict); blah.add(showModActions, d.makeGbc(0, 0, 3, 1, GridBagConstraints.WEST)); diff --git a/src/chatty/gui/components/settings/MsgColorSettings.java b/src/chatty/gui/components/settings/MsgColorSettings.java index 903506ce5..308305140 100644 --- a/src/chatty/gui/components/settings/MsgColorSettings.java +++ b/src/chatty/gui/components/settings/MsgColorSettings.java @@ -8,6 +8,7 @@ import java.awt.Dimension; import java.awt.GridBagConstraints; import java.util.List; +import javax.swing.JCheckBox; import javax.swing.JPanel; /** @@ -44,9 +45,10 @@ public MsgColorSettings(SettingsDialog d) { GridBagConstraints gbc; + JCheckBox msgColorsEnabled = d.addSimpleBooleanSetting("msgColorsEnabled"); gbc = d.makeGbc(0, 0, 1, 1); gbc.anchor = GridBagConstraints.WEST; - main.add(d.addSimpleBooleanSetting("msgColorsEnabled"), gbc); + main.add(msgColorsEnabled, gbc); data = new ItemColorEditor<>(d, (id, @@ -63,6 +65,8 @@ public MsgColorSettings(SettingsDialog d) { gbc.weighty = 1; main.add(data, gbc); + SettingsUtil.addSubsettings(msgColorsEnabled, data); + LinkLabel info = new LinkLabel(INFO_TEXT, d.getSettingsHelpLinkLabelListener()); main.add(info, d.makeGbc(0, 2, 1, 1)); diff --git a/src/chatty/gui/components/settings/NamedColorsPanel.java b/src/chatty/gui/components/settings/NamedColorsPanel.java index 730ba7cb1..eeb23392b 100644 --- a/src/chatty/gui/components/settings/NamedColorsPanel.java +++ b/src/chatty/gui/components/settings/NamedColorsPanel.java @@ -1,6 +1,6 @@ package chatty.gui.components.settings; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.NamedColor; import java.awt.*; import java.awt.event.MouseEvent; diff --git a/src/chatty/gui/components/settings/NotificationEditor.java b/src/chatty/gui/components/settings/NotificationEditor.java index c9cf6a6a3..7380cd616 100644 --- a/src/chatty/gui/components/settings/NotificationEditor.java +++ b/src/chatty/gui/components/settings/NotificationEditor.java @@ -2,7 +2,7 @@ package chatty.gui.components.settings; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.components.LinkLabelListener; import chatty.gui.notifications.Notification; import chatty.gui.notifications.Notification.State; diff --git a/src/chatty/gui/components/settings/SettingsDialog.java b/src/chatty/gui/components/settings/SettingsDialog.java index 6e1fe9f24..8410aa8f3 100644 --- a/src/chatty/gui/components/settings/SettingsDialog.java +++ b/src/chatty/gui/components/settings/SettingsDialog.java @@ -2,7 +2,7 @@ package chatty.gui.components.settings; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LaF; import chatty.gui.MainGui; import chatty.gui.components.LinkLabel; @@ -633,7 +633,7 @@ protected Boolean getBooleanSetting(String name) { return null; } - protected ComboStringSetting addComboStringSetting(String name, int size, boolean editable, String[] choices) { + protected ComboStringSetting addComboStringSetting(String name, boolean editable, String[] choices) { Map localizedChoices = new LinkedHashMap<>(); for (String choice : choices) { String label = Language.getString("settings.string."+name+".option."+choice, false); @@ -721,6 +721,17 @@ protected JTextField addSimpleLongSetting(String name, int size, boolean editabl return result; } + protected ComboLongSetting addComboLongSetting(String name, int[] choices) { + Map localizedChoices = new LinkedHashMap<>(); + for (Integer choice : choices) { + String label = Language.getString("settings.long."+name+".option."+choice); + localizedChoices.put((long)choice, label); + } + ComboLongSetting result = new ComboLongSetting(localizedChoices); + longSettings.put(name, result); + return result; + } + protected void addLongSetting(String settingName, LongSetting setting) { longSettings.put(settingName, setting); } diff --git a/src/chatty/gui/components/settings/SettingsUtil.java b/src/chatty/gui/components/settings/SettingsUtil.java new file mode 100644 index 000000000..bc635fa9a --- /dev/null +++ b/src/chatty/gui/components/settings/SettingsUtil.java @@ -0,0 +1,24 @@ + +package chatty.gui.components.settings; + +import java.awt.Component; +import javax.swing.JCheckBox; + +/** + * + * @author tduva + */ +public class SettingsUtil { + + public static void addSubsettings(JCheckBox control, Component... subs) { + control.addItemListener(e -> { + for (Component sub : subs) { + sub.setEnabled(control.isSelected()); + } + }); + for (Component sub : subs) { + sub.setEnabled(false); + } + } + +} diff --git a/src/chatty/gui/components/settings/TabSettings.java b/src/chatty/gui/components/settings/TabSettings.java index 085042696..531fcc380 100644 --- a/src/chatty/gui/components/settings/TabSettings.java +++ b/src/chatty/gui/components/settings/TabSettings.java @@ -69,11 +69,7 @@ public TabSettings(final SettingsDialog d) { other.add(scroll2, d.makeGbcSub(0, 6, 4, 1, GridBagConstraints.WEST)); - // Tab scrolling checkbox status - scroll2.setEnabled(false); - scroll.addItemListener(e -> { - scroll2.setEnabled(scroll.isSelected()); - }); + SettingsUtil.addSubsettings(scroll, scroll2); } } diff --git a/src/chatty/gui/components/settings/TableEditor.java b/src/chatty/gui/components/settings/TableEditor.java index 502a1cc0d..5f1a3d5d8 100644 --- a/src/chatty/gui/components/settings/TableEditor.java +++ b/src/chatty/gui/components/settings/TableEditor.java @@ -114,20 +114,26 @@ public void valueChanged(ListSelectionEvent e) { table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - editSelectedItem(); + if (isEnabled()) { + if (e.getClickCount() == 2) { + editSelectedItem(); + } } } @Override public void mousePressed(MouseEvent e) { - selectRowAt(e.getPoint()); - popupMenu(e); + if (isEnabled()) { + selectRowAt(e.getPoint()); + popupMenu(e); + } } @Override public void mouseReleased(MouseEvent e) { - popupMenu(e); + if (isEnabled()) { + popupMenu(e); + } } }); @@ -317,6 +323,17 @@ public final void setTableEditorListener(TableEditorListener listener) { this.listener = listener; } + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + updateButtons(); + // Make table visibily disabled + table.setEnabled(enabled); + table.setFocusable(enabled); + table.setOpaque(enabled); + table.setShowGrid(enabled); + } + /** * Opens the context menu if this MouseEvent was a popup trigger and a menu * is set. @@ -402,8 +419,8 @@ private void configureButton(JButton button, String icon, String tooltip) { * Update the enabled-state of the buttons. */ private void updateButtons() { - boolean enabled = table.getSelectedRowCount() == 1; - add.setEnabled(true); + boolean enabled = table.getSelectedRowCount() == 1 && isEnabled(); + add.setEnabled(isEnabled()); remove.setEnabled(enabled); edit.setEnabled(enabled); moveUp.setEnabled(enabled); diff --git a/src/chatty/gui/components/settings/UsercolorCorrectionPreview.java b/src/chatty/gui/components/settings/UsercolorCorrectionPreview.java new file mode 100644 index 000000000..d3f90ce86 --- /dev/null +++ b/src/chatty/gui/components/settings/UsercolorCorrectionPreview.java @@ -0,0 +1,114 @@ + +package chatty.gui.components.settings; + +import chatty.gui.GuiUtil; +import chatty.gui.NamedColor; +import chatty.lang.Language; +import chatty.util.colors.ColorCorrection; +import chatty.util.colors.ColorCorrector; +import chatty.util.colors.HtmlColors; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GridBagLayout; +import java.awt.Window; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; + +/** + * Show a preview of the different Nickcolor Correction settings. + * + * @author tduva + */ +public class UsercolorCorrectionPreview extends JDialog { + + public UsercolorCorrectionPreview(Window parent, Color background) { + super(parent); + + setTitle("Usercolor Correction Preview"); + + boolean darkBg = ColorCorrection.isDarkColor(background); + + JPanel main = new JPanel(new GridBagLayout()); + main.setBackground(background); + + //=============== + // Setting Names + //=============== + int column = 1; + for (String type : ColorCorrector.ACTIVE_TYPES) { + String label = Language.getString("settings.string.nickColorCorrection.option."+type); + main.add(createLabel(label, darkBg ? Color.WHITE : Color.BLACK), + GuiUtil.makeGbc(column, 0, 1, 1)); + column++; + } + + //========= + // Preview + //========= + int row = 1; + for (NamedColor color : HtmlColors.getNamedColors()) { + int diff = ColorCorrection.getBrightnessDifference(color, background); + if (Math.abs(diff) > 100) { + continue; + } + + //---------------- + // Original Color + //---------------- + main.add(createLabel(color.getName(), color), + GuiUtil.makeGbc(0, row, 1, 1)); + + //------------------ + // Corrected Colors + //------------------ + column = 1; + for (String type : ColorCorrector.ACTIVE_TYPES) { + Color correctedColor = ColorCorrector.get(type).correctColor(color, background); + String label = HtmlColors.getColorString(correctedColor); + if (correctedColor.equals(color)) { + label = "Unchanged"; + } + main.add(createLabel(label, correctedColor), + GuiUtil.makeGbc(column, row, 1, 1)); + column++; + } + + row++; + } + + add(new JScrollPane(main), BorderLayout.CENTER); + + setPreferredSize(new Dimension(getPreferredSize().width + 100, 600)); + pack(); + setLocationRelativeTo(parent); + setVisible(true); + } + + private static JLabel createLabel(String text, Color foreground) { + JLabel label = new JLabel(text); + label.setForeground(foreground); + return label; + } + + //========= + // Testing + //========= + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + new UsercolorCorrectionPreview(null, new Color(250, 250, 250)).addComponentListener(new ComponentAdapter() { + + @Override + public void componentHidden(ComponentEvent e) { + System.exit(0); + } + }); + }); + } + +} diff --git a/src/chatty/gui/components/settings/UsercolorSettings.java b/src/chatty/gui/components/settings/UsercolorSettings.java index bb3adbff7..49d213f93 100644 --- a/src/chatty/gui/components/settings/UsercolorSettings.java +++ b/src/chatty/gui/components/settings/UsercolorSettings.java @@ -1,15 +1,17 @@ package chatty.gui.components.settings; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.colors.UsercolorItem; import chatty.gui.components.LinkLabel; import chatty.lang.Language; +import chatty.util.colors.ColorCorrector; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.util.List; +import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; @@ -37,12 +39,13 @@ public class UsercolorSettings extends SettingsPanel { + "[help:Usercolors And more..]"; private final ItemColorEditor data; + private Color defaultBackgroundColor; public UsercolorSettings(SettingsDialog d) { super(true); JPanel customPanel = addTitledPanel("Custom Usercolors", 0, true); - JPanel mainPanel = addTitledPanel(Language.getString("settings.section.usercolorsOther"), 1); + JPanel otherPanel = addTitledPanel(Language.getString("settings.section.usercolorsOther"), 1); GridBagConstraints gbc; @@ -51,8 +54,9 @@ public UsercolorSettings(SettingsDialog d) { //=================== gbc = d.makeGbc(0, 0, 1, 1); gbc.anchor = GridBagConstraints.WEST; - customPanel.add(d.addSimpleBooleanSetting("customUsercolors", - "Enable custom usercolors", ""), gbc); + JCheckBox usercolorsEnabled = d.addSimpleBooleanSetting("customUsercolors", + "Enable custom usercolors", ""); + customPanel.add(usercolorsEnabled, gbc); data = new ItemColorEditor<>(d, (id, color, enabled, bg, bgEnabled) -> { @@ -66,14 +70,28 @@ public UsercolorSettings(SettingsDialog d) { gbc.weighty = 1; customPanel.add(data, gbc); + SettingsUtil.addSubsettings(usercolorsEnabled, data); + LinkLabel info = new LinkLabel(INFO_TEXT, d.getSettingsHelpLinkLabelListener()); customPanel.add(info, d.makeGbc(1, 1, 1, 1)); //================ // Other Settings //================ - mainPanel.add(d.addSimpleBooleanSetting("colorCorrection"), - d.makeGbcCloser(0, 0, 1, 1, GridBagConstraints.WEST)); + otherPanel.add(new JLabel(Language.getString("settings.string.nickColorCorrection")), + d.makeGbc(0, 0, 1, 1)); + + String[] colorCorrectionTypes = new String[ColorCorrector.TYPES.keySet().size()]; + ColorCorrector.TYPES.keySet().toArray(colorCorrectionTypes); + otherPanel.add(d.addComboStringSetting("nickColorCorrection", false, colorCorrectionTypes), + d.makeGbc(1, 0, 1, 1)); + + JButton colorCorrectionPreview = new JButton("Preview"); + colorCorrectionPreview.addActionListener(e -> { + new UsercolorCorrectionPreview(d, defaultBackgroundColor); + }); + otherPanel.add(colorCorrectionPreview, + d.makeGbc(2, 0, 1, 1)); } public void setData(List data) { @@ -86,6 +104,7 @@ public List getData() { public void setDefaultBackground(Color color) { data.setDefaultBackground(color); + this.defaultBackgroundColor = color; } public void editItem(String item) { diff --git a/src/chatty/gui/components/srl/RacesTable.java b/src/chatty/gui/components/srl/RacesTable.java index 199d0ea58..a7c14fd62 100644 --- a/src/chatty/gui/components/srl/RacesTable.java +++ b/src/chatty/gui/components/srl/RacesTable.java @@ -1,7 +1,7 @@ package chatty.gui.components.srl; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.TwitchUrl; import chatty.gui.UrlOpener; import chatty.gui.components.menus.ContextMenu; diff --git a/src/chatty/gui/components/srl/SRLRace.java b/src/chatty/gui/components/srl/SRLRace.java index f2bf1e997..fd8588d33 100644 --- a/src/chatty/gui/components/srl/SRLRace.java +++ b/src/chatty/gui/components/srl/SRLRace.java @@ -2,7 +2,7 @@ package chatty.gui.components.srl; import chatty.gui.GuiUtil; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LinkListener; import chatty.gui.TwitchUrl; import chatty.gui.UrlOpener; diff --git a/src/chatty/gui/components/textpane/ChannelTextPane.java b/src/chatty/gui/components/textpane/ChannelTextPane.java index e219c1c55..eedadf89a 100644 --- a/src/chatty/gui/components/textpane/ChannelTextPane.java +++ b/src/chatty/gui/components/textpane/ChannelTextPane.java @@ -7,7 +7,7 @@ import chatty.SettingsManager; import chatty.gui.MouseClickedListener; import chatty.gui.UserListener; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LinkListener; import chatty.gui.StyleServer; import chatty.gui.UrlOpener; @@ -27,6 +27,7 @@ import chatty.util.api.Emoticon.EmoticonUser; import chatty.util.api.Emoticons; import chatty.util.api.Emoticons.TagEmotes; +import chatty.util.colors.ColorCorrector; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -654,8 +655,12 @@ private boolean printModLogInfo(ModLogInfo info) { return false; } changeInfo(line, attributes -> { - attributes.addAttribute(Attribute.ACTION_BY, info.data.created_by); - attributes.addAttribute(Attribute.ACTION_REASON, info.getReason()); + addBy(attributes, info.data.created_by); + if (info.getReason() != null) { + // Shouldn't add null value since it sometimes seems + // to cause error when printing with these attrs + attributes.addAttribute(Attribute.ACTION_REASON, info.getReason()); + } }); return true; } @@ -669,7 +674,7 @@ private boolean printModLogInfo(ModLogInfo info) { } if (line.getAttributes().containsAttribute(Attribute.COMMAND, command)) { changeInfo(line, attributes -> { - attributes.addAttribute(Attribute.ACTION_BY, info.data.created_by); + addBy(attributes, info.data.created_by); }); return true; } @@ -679,6 +684,20 @@ private boolean printModLogInfo(ModLogInfo info) { return false; } + private void addBy(MutableAttributeSet attributes, String byName) { + java.util.List old = (java.util.List)attributes.getAttribute(Attribute.ACTION_BY); + java.util.List changed; + if (old != null) { + changed = new ArrayList<>(old); + } else { + changed = new ArrayList<>(); + } + // If already present, append to end + changed.remove(byName); + changed.add(byName); + attributes.addAttribute(Attribute.ACTION_BY, changed); + } + private long getTimeAgo(Element element) { Long timestamp = (Long)element.getAttributes().getAttribute(Attribute.TIMESTAMP); if (timestamp != null) { @@ -780,13 +799,13 @@ private void changeInfo(Element line, InfoChanger changer) { String actionReason = (String)attributes.getAttribute(Attribute.ACTION_REASON); if (!StringUtil.isNullOrEmpty(actionReason) - && styles.isEnabled(Setting.BAN_REASON_MESSAGE)) { + && styles.isEnabled(Setting.BAN_REASON_APPENDED)) { text = StringUtil.append(text, " ", "["+actionReason+"]"); } - String actionBy = (String)attributes.getAttribute(Attribute.ACTION_BY); - if (!StringUtil.isNullOrEmpty(actionBy)) { - text = StringUtil.append(text, " ", "(@"+actionBy+")"); + java.util.List actionBy = (java.util.List)attributes.getAttribute(Attribute.ACTION_BY); + if (actionBy != null) { + text = StringUtil.append(text, " ", "(@"+StringUtil.join(actionBy, ", ")+")"); } /** @@ -944,7 +963,7 @@ public void userBanned(User user, long duration, String reason, String id) { // Set info on newest deleted line if (i == lines.size() - 1) { setBanInfo(line, banInfo); - setLineCommand(line.getStartOffset(), Helper.makeBanCommand(user, duration, reason, id)); + setLineCommand(line.getStartOffset(), Helper.makeBanCommand(user, duration, id)); replayModLogInfo(); } i++; @@ -2061,7 +2080,7 @@ private void printSpecialsInfo(String text, AttributeSet style, java.util.List highlightMatches) { TreeMap ranges = new TreeMap<>(); HashMap rangesStyle = new HashMap<>(); - findLinks(text, ranges, rangesStyle); + findLinks(text, ranges, rangesStyle, style); printSpecials(null, text, style, ranges, rangesStyle, highlightMatches); } @@ -2094,7 +2113,7 @@ protected void printSpecialsNormal(String text, User user, MutableAttributeSet s applyReplacements(text, replacements, replacement, ranges, rangesStyle); if (!ignoreLinks) { - findLinks(text, ranges, rangesStyle); + findLinks(text, ranges, rangesStyle, styles.standard()); } if (styles.showEmoticons()) { @@ -2229,7 +2248,7 @@ private void applyReplacements(String text, java.util.List matches, } private void findLinks(String text, Map ranges, - Map rangesStyle) { + Map rangesStyle, AttributeSet baseStyle) { // Find links urlMatcher.reset(text); while (urlMatcher.find()) { @@ -2250,7 +2269,7 @@ private void findLinks(String text, Map ranges, if (!foundUrl.startsWith("http")) { foundUrl = "http://"+foundUrl; } - rangesStyle.put(start, styles.url(foundUrl)); + rangesStyle.put(start, styles.url(foundUrl, baseStyle)); } } } @@ -3047,6 +3066,8 @@ public class Styles { private SimpleDateFormat timestampFormat; private int bufferSize = -1; + + private ColorCorrector colorCorrector; /** * Icons that have been modified for use and saved into a style. Should @@ -3207,6 +3228,8 @@ public boolean setStyles() { styles.put("clearSearchResult", clearSearchResult); setBackground(styleServer.getColor("background")); + + colorCorrector = styleServer.getColorCorrector(); return somethingChanged; } @@ -3231,7 +3254,6 @@ private void setSettings() { addSetting(Setting.PAUSE_ON_MOUSEMOVE, true); addSetting(Setting.PAUSE_ON_MOUSEMOVE_CTRL_REQUIRED, false); addSetting(Setting.EMOTICONS_SHOW_ANIMATED, false); - addSetting(Setting.COLOR_CORRECTION, true); addSetting(Setting.SHOW_TOOLTIPS, true); addNumericSetting(Setting.FILTER_COMBINING_CHARACTERS, 1, 0, 2); addNumericSetting(Setting.DELETED_MESSAGES_MODE, 30, -1, 9999999); @@ -3472,8 +3494,9 @@ public MutableAttributeSet nick(User user, AttributeSet style) { userStyle.addAttribute(Attribute.IS_USER_MESSAGE, true); Color userColor = user.getColor(); // Only correct color if no custom color is defined - if (!user.hasCustomColor() && isEnabled(Setting.COLOR_CORRECTION)) { - userColor = HtmlColors.correctReadability(userColor, getBackground()); + if (!user.hasCustomColor()) { + // If turned off, it will just return the same color + userColor = colorCorrector.correctColor(userColor, getBackground()); user.setCorrectedColor(userColor); } StyleConstants.setForeground(userStyle, userColor); @@ -3572,10 +3595,11 @@ public boolean isEnabled(Setting setting) { * Make a link style for the given URL. * * @param url + * @param baseStyle * @return */ - public MutableAttributeSet url(String url) { - SimpleAttributeSet urlStyle = new SimpleAttributeSet(standard()); + public MutableAttributeSet url(String url, AttributeSet baseStyle) { + SimpleAttributeSet urlStyle = new SimpleAttributeSet(baseStyle); StyleConstants.setUnderline(urlStyle, true); urlStyle.addAttribute(HTML.Attribute.HREF, url); return urlStyle; diff --git a/src/chatty/gui/components/textpane/ModLogInfo.java b/src/chatty/gui/components/textpane/ModLogInfo.java index 1af60ff9e..953ea7fe1 100644 --- a/src/chatty/gui/components/textpane/ModLogInfo.java +++ b/src/chatty/gui/components/textpane/ModLogInfo.java @@ -1,6 +1,7 @@ package chatty.gui.components.textpane; +import chatty.Helper; import chatty.gui.components.Channel; import chatty.util.StringUtil; import chatty.util.api.pubsub.ModeratorActionData; @@ -13,7 +14,7 @@ * @author tduva */ public class ModLogInfo extends InfoMessage { - + private static final Set BAN_COMMANDS = new HashSet<>(Arrays.asList(new String[]{"timeout", "ban", "delete"})); @@ -40,37 +41,45 @@ private static String makeText(ModeratorActionData data) { @Override public String makeCommand() { + return makeCommand(data); + } + + public static String makeCommand(ModeratorActionData data) { switch (data.moderation_action) { - case "timeout": return makeTimeoutCommand(); - case "ban": return makeBanCommand(); - case "delete": return makeDeleteCommand(); + case "timeout": return makeTimeoutCommand(data); + case "ban": return makeBanCommand(data); + case "delete": return makeDeleteCommand(data); default: return data.moderation_action; } } public boolean isBanCommand() { + return isBanCommand(data); + } + + public static boolean isBanCommand(ModeratorActionData data) { return BAN_COMMANDS.contains(data.moderation_action); } public static boolean isBanOrInfoAssociated(ModeratorActionData data) { - return BAN_COMMANDS.contains(data.moderation_action) || InfoMessage.msgIdHasCommand(data.moderation_action); + return isBanCommand(data) || InfoMessage.msgIdHasCommand(data.moderation_action); } - private String makeDeleteCommand() { + public static String makeDeleteCommand(ModeratorActionData data) { if (data.args.size() > 2) { return data.moderation_action+" "+data.args.get(2); } return ""; } - private String makeBanCommand() { + public static String makeBanCommand(ModeratorActionData data) { if (data.args.size() > 0) { return data.moderation_action+" "+data.args.get(0); } return ""; } - private String makeTimeoutCommand() { + public static String makeTimeoutCommand(ModeratorActionData data) { if (data.args.size() > 1) { return data.moderation_action+" "+data.args.get(0)+" "+data.args.get(1); } @@ -78,20 +87,32 @@ private String makeTimeoutCommand() { } public String getReason() { + return getReason(data); + } + + public static String getReason(ModeratorActionData data) { switch (data.moderation_action) { - case "timeout": return getReason(2); - case "ban": return getReason(1); + case "timeout": return getReason(data, 2); + case "ban": return getReason(data, 1); default: return null; } } - private String getReason(int index) { + private static String getReason(ModeratorActionData data, int index) { if (data.args.size() > index && !data.args.get(index).isEmpty()) { return data.args.get(index); } return null; } + public static String getBannedUsername(ModeratorActionData data) { + if (isBanCommand(data) && data.args.size() > 0 + && Helper.isValidStream(data.args.get(0))) { + return data.args.get(0); + } + return null; + } + @Override public String toString() { return text; diff --git a/src/chatty/gui/components/textpane/WrapLabelView.java b/src/chatty/gui/components/textpane/WrapLabelView.java index 7eb53b9dc..195ccf65a 100644 --- a/src/chatty/gui/components/textpane/WrapLabelView.java +++ b/src/chatty/gui/components/textpane/WrapLabelView.java @@ -1,9 +1,10 @@ package chatty.gui.components.textpane; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.components.textpane.ChannelTextPane.Attribute; import chatty.util.Debugging; +import chatty.util.colors.ColorCorrection; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; @@ -85,7 +86,7 @@ && getAttributes().containsAttribute(Attribute.HIGHLIGHT_WORD, true)) { Color c2; Color c3; - boolean darkText = HtmlColors.getBrightness(c) < 128; + boolean darkText = ColorCorrection.isDarkColor(c); if (darkText) { c2 = new Color(c.getRed(), c.getGreen(), c.getBlue(), 200); c3 = new Color(c.getRed(), c.getGreen(), c.getBlue(), 60); diff --git a/src/chatty/gui/components/updating/Changes.java b/src/chatty/gui/components/updating/Changes.java index 650829ff2..ce3146de9 100644 --- a/src/chatty/gui/components/updating/Changes.java +++ b/src/chatty/gui/components/updating/Changes.java @@ -1,7 +1,7 @@ package chatty.gui.components.updating; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.LaF; import chatty.gui.UrlOpener; import chatty.lang.Language; diff --git a/src/chatty/gui/components/userinfo/InfoPanel.java b/src/chatty/gui/components/userinfo/InfoPanel.java index 5e4db4947..b0e57c1be 100644 --- a/src/chatty/gui/components/userinfo/InfoPanel.java +++ b/src/chatty/gui/components/userinfo/InfoPanel.java @@ -3,7 +3,7 @@ import chatty.Helper; import chatty.User; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.gui.components.LinkLabel; import chatty.gui.components.LinkLabelListener; import static chatty.gui.components.userinfo.Util.makeGbc; diff --git a/src/chatty/gui/components/userinfo/PastMessages.java b/src/chatty/gui/components/userinfo/PastMessages.java index 9b01d346f..7d997a687 100644 --- a/src/chatty/gui/components/userinfo/PastMessages.java +++ b/src/chatty/gui/components/userinfo/PastMessages.java @@ -73,13 +73,18 @@ else if (m.getType() == User.Message.BAN) { if (bm.reason != null && !bm.reason.isEmpty()) { b.append(" [").append(bm.reason).append("]"); } - + if (bm.by != null) { + b.append(" (@").append(bm.by).append(")"); + } b.append("\n"); } else if (m.getType() == User.Message.MSG_DELETED) { User.MsgDeleted md = (User.MsgDeleted)m; b.append(DateTime.format(m.getTime(), TIMESTAMP)).append(">"); b.append("Message deleted: ").append(md.msg); + if (md.by != null) { + b.append(" (@").append(md.by).append(")"); + } b.append("\n"); } else if (m.getType() == User.Message.SUB) { diff --git a/src/chatty/gui/notifications/Notification.java b/src/chatty/gui/notifications/Notification.java index d0f8a53d7..845f71152 100644 --- a/src/chatty/gui/notifications/Notification.java +++ b/src/chatty/gui/notifications/Notification.java @@ -5,7 +5,7 @@ import chatty.Helper; import chatty.User; import chatty.gui.Highlighter; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.util.StringUtil; import java.awt.Color; import java.util.ArrayList; diff --git a/src/chatty/lang/Strings.properties b/src/chatty/lang/Strings.properties index e9f13d4c7..b61e5b129 100644 --- a/src/chatty/lang/Strings.properties +++ b/src/chatty/lang/Strings.properties @@ -618,7 +618,12 @@ settings.boolean.actionColored = Color action messages (/me) with Usercolor !-- Usercolors --! settings.section.usercolorsOther = Other Settings -settings.boolean.colorCorrection = Adjust usercolors to improve readability on chat background +settings.string.nickColorCorrection = Usercolor Readability Correction: +settings.string.nickColorCorrection.option.off = Off +settings.string.nickColorCorrection.option.normal = Normal +settings.string.nickColorCorrection.option.strong = Strong +settings.string.nickColorCorrection.option.old = Old +settings.string.nickColorCorrection.option.gray = Grayscale !-- Usericons --! settings.section.usericons = Usericon Settings (Badges) @@ -718,6 +723,10 @@ settings.boolean.highlightIgnored.tip = Allows ignored messages to be highlighte settings.boolean.highlightMatches = Emphasize Highlight/Ignore matches settings.boolean.highlightMatches.tip = Surrounds sections of text that caused the Highlight with a rectangle (and in the Highlighted/Ignored Messages windows). +!-- Ignore --! +settings.section.ignoreMessages = Ignore Messages +settings.boolean.ignoreEnabled = Enable Ignore + !-- Filter --! settings.section.filterMessages = Filter out parts of messages settings.boolean.filterEnabled = Enable Filter diff --git a/src/chatty/util/DateTime.java b/src/chatty/util/DateTime.java index c8eed7c6d..f9be50e19 100644 --- a/src/chatty/util/DateTime.java +++ b/src/chatty/util/DateTime.java @@ -20,6 +20,7 @@ public class DateTime { private static final SimpleDateFormat FULL_DATETIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZ"); private static final SimpleDateFormat SDF = new SimpleDateFormat("HH:mm:ss"); private static final SimpleDateFormat SDF2 = new SimpleDateFormat("HH:mm"); + private static final SimpleDateFormat SDF3 = new SimpleDateFormat("HH:mm:ss/SSS"); public static final long MINUTE = 60; public static final long HOUR = MINUTE * 60; public static final long DAY = HOUR * 24; @@ -45,6 +46,10 @@ public static String currentTime() { return currentTime(SDF); } + public static String currentTimeExact() { + return currentTime(SDF3); + } + public static String currentTime(String format) { return currentTime(new SimpleDateFormat(format)); } diff --git a/src/chatty/util/api/CheerEmoticonManager.java b/src/chatty/util/api/CheerEmoticonManager.java index 25c8a3112..ea2dafed2 100644 --- a/src/chatty/util/api/CheerEmoticonManager.java +++ b/src/chatty/util/api/CheerEmoticonManager.java @@ -2,7 +2,7 @@ package chatty.util.api; import chatty.Chatty; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.util.api.CheerEmoticon.CheerEmoticonUrl; import java.awt.Color; import java.util.HashSet; diff --git a/src/chatty/util/api/FollowerInfo.java b/src/chatty/util/api/FollowerInfo.java index 35af1b11e..e496306c6 100644 --- a/src/chatty/util/api/FollowerInfo.java +++ b/src/chatty/util/api/FollowerInfo.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.List; /** @@ -57,7 +58,7 @@ public class FollowerInfo { */ public FollowerInfo(Follower.Type type, String stream, List followers, int total) { this.type = type; - this.followers = followers; + this.followers = Collections.unmodifiableList(followers); this.total = total; this.time = System.currentTimeMillis(); this.stream = stream; diff --git a/src/chatty/util/api/pubsub/ModeratorActionData.java b/src/chatty/util/api/pubsub/ModeratorActionData.java index 0e2de51bc..3803affae 100644 --- a/src/chatty/util/api/pubsub/ModeratorActionData.java +++ b/src/chatty/util/api/pubsub/ModeratorActionData.java @@ -166,4 +166,9 @@ public int hashCode() { return hash; } + @Override + public String toString() { + return String.format("'%s'@%s", getCommandAndParameters(), created_by); + } + } diff --git a/src/chatty/util/api/usericons/Usericon.java b/src/chatty/util/api/usericons/Usericon.java index be7d88954..cc6bf872d 100644 --- a/src/chatty/util/api/usericons/Usericon.java +++ b/src/chatty/util/api/usericons/Usericon.java @@ -2,7 +2,7 @@ package chatty.util.api.usericons; import chatty.Helper; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import chatty.util.ImageCache; import chatty.util.StringUtil; import java.awt.Color; diff --git a/src/chatty/util/api/usericons/UsericonFactory.java b/src/chatty/util/api/usericons/UsericonFactory.java index 46c252f86..e5bd0ceba 100644 --- a/src/chatty/util/api/usericons/UsericonFactory.java +++ b/src/chatty/util/api/usericons/UsericonFactory.java @@ -3,7 +3,7 @@ import chatty.Chatty; import chatty.Helper; -import chatty.gui.HtmlColors; +import chatty.util.colors.HtmlColors; import static chatty.util.api.usericons.Usericon.SOURCE_CUSTOM; import static chatty.util.api.usericons.Usericon.SOURCE_FALLBACK; import static chatty.util.api.usericons.Usericon.SOURCE_OTHER; diff --git a/src/chatty/util/colors/ColorCorrection.java b/src/chatty/util/colors/ColorCorrection.java new file mode 100644 index 000000000..2d44feb2f --- /dev/null +++ b/src/chatty/util/colors/ColorCorrection.java @@ -0,0 +1,107 @@ + +package chatty.util.colors; + +import chatty.util.Debugging; +import java.awt.Color; + +/** + * + * @author tduva + */ +public class ColorCorrection { + + /** + * Gets the perceived brightness of the given Color. + * + * @param color + * @return + */ + public static int getBrightness(Color color) { + return (color.getRed() * 299 + + color.getGreen() * 587 + + color.getBlue() * 114) / 1000; + } + + public static boolean isDarkColor(Color color) { + return getBrightness(color) < 128; + } + + public static boolean isLightColor(Color color) { + return getBrightness(color) >= 128; + } + + /** + * Gets the difference between the perceived brightness between colors. + * + * @param c1 + * @param c2 + * @return + */ + public static int getBrightnessDifference(Color c1, Color c2) { + int b1 = getBrightness(c1); + int b2 = getBrightness(c2); + return b1 - b2; + } + + /** + * Tries to change the color (if necessary) so it it better readable on + * the given background color. + * + * This works for a few colors, but is far from perfect. For example + * some colors have a high enough brightness difference, but they are + * still not very well readable, e.g. springgreen on light grey. + * + * @param foreground + * @param background + * @return + */ + public static Color correctReadability(Color foreground, Color background) { + int bd = getBrightnessDifference(foreground, background); + if (Math.abs(bd) < 50) { + if (getBrightness(background) > 180) { + foreground = makeDarker(foreground,0.5f); + } + else { + foreground = makeBrighter(foreground,0.5f); + } + } + return foreground; + } + + /** + * Tries to make the given color brighter. Might not work very well with + * colors like 0000FF because hsb[2] is already 1.0. + * + * @param color + * @param factor + * @return + */ + public static Color makeBrighter(Color color, float factor) { + int red = color.getRed(); + int green = color.getGreen(); + int blue = color.getBlue(); + float[] hsb = Color.RGBtoHSB(red, green, blue, null); + if (hsb[2] == 1) { + red += 150; + green += 150; + blue += 150; + if (blue > 255) { + blue = 255; + } + if (red > 255) { + red = 255; + } + if (green > 255) { + green = 255; + } + hsb = Color.RGBtoHSB(red, green, blue, null); + } + return Color.getHSBColor(hsb[0], hsb[1], factor * (1f + hsb[2])); + } + + public static Color makeDarker(Color color, float factor) { + float hsb[] = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return Color.getHSBColor(hsb[0], hsb[1], factor * hsb[2]); + } + +} diff --git a/src/chatty/util/colors/ColorCorrectionNew.java b/src/chatty/util/colors/ColorCorrectionNew.java new file mode 100644 index 000000000..2ef5479c6 --- /dev/null +++ b/src/chatty/util/colors/ColorCorrectionNew.java @@ -0,0 +1,88 @@ + +package chatty.util.colors; + +import java.awt.Color; + +/** + * + * @author tduva + */ +public class ColorCorrectionNew { + + /** + * sRGB Luma + * + * @param c + * @return + */ + public static int getLightness(Color c) { + return (int)(c.getRed() * 0.2126 + c.getGreen() * 0.7152 + c.getBlue() * 0.0722); + } + + /** + * Gets the difference between the perceived brightness between colors. + * + * @param c1 + * @param c2 + * @return + */ + public static int getLightnessDifference(Color c1, Color c2) { + int b1 = getLightness(c1); + int b2 = getLightness(c2); + return b1 - b2; + } + + /** + * Tries to change the color (if necessary) so it it better readable on the + * given background color. + * + * @param foreground + * @param background + * @param threshold + * @return + */ + public static Color correctReadability(Color foreground, Color background, int threshold) { + boolean darkBg = getLightness(background) < 180; + int diff = getLightnessDifference(foreground, background); + if (!darkBg) { + diff *= -1; + // Light colors seem to be a bit worse readable, so adjust some more + threshold += 10; + } + diff = Math.max(0, diff); + if (diff < threshold) { + // Find adjustment factor to roughly get to threshold diff + float factor = (1 - diff / (float)threshold) / 2; + if (!darkBg) { + foreground = makeDarker(foreground, 1 - factor); + } + else { + foreground = makeBrighter(foreground, factor); + } + } + return foreground; + } + + public static Color makeBrighter(Color c, float factor) { + int r = c.getRed(); + int g = c.getGreen(); + int b = c.getBlue(); + + // Remaining to max value + int rr = 255 - r; + int rg = 255 - g; + int rb = 255 - b; + + // Add a factor of remaining + int cr = r + (int)(rr * factor); + int cg = g + (int)(rg * factor); + int cb = b + (int)(rb * factor); + + return new Color(cr, cg, cb); + } + + public static Color makeDarker(Color c, float factor) { + return new Color((int)(c.getRed() * factor), (int)(c.getGreen() * factor), (int)(c.getBlue() * factor)); + } + +} diff --git a/src/chatty/util/colors/ColorCorrector.java b/src/chatty/util/colors/ColorCorrector.java new file mode 100644 index 000000000..216c7367f --- /dev/null +++ b/src/chatty/util/colors/ColorCorrector.java @@ -0,0 +1,79 @@ + +package chatty.util.colors; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * + * @author tduva + */ +public abstract class ColorCorrector { + + public abstract Color correctColor(Color foreground, Color background); + + public static final Map TYPES = new LinkedHashMap<>(); + public static final List ACTIVE_TYPES = new ArrayList<>(); + + static { + TYPES.put("normal", new ColorCorrector() { + + @Override + public Color correctColor(Color foreground, Color background) { + return ColorCorrectionNew.correctReadability(foreground, background, 60); + } + }); + + TYPES.put("strong", new ColorCorrector() { + + @Override + public Color correctColor(Color foreground, Color background) { + return ColorCorrectionNew.correctReadability(foreground, background, 140); + } + }); + + TYPES.put("old", new ColorCorrector() { + + @Override + public Color correctColor(Color foreground, Color background) { + return ColorCorrection.correctReadability(foreground, background); + } + }); + + TYPES.put("gray", new ColorCorrector() { + + @Override + public Color correctColor(Color foreground, Color background) { + foreground = ColorCorrectionNew.correctReadability(foreground, background, 80); + int brightness = ColorCorrection.getBrightness(foreground); + return new Color(brightness, brightness, brightness); + } + }); + + TYPES.put("off", new ColorCorrector() { + + @Override + public Color correctColor(Color foreground, Color background) { + return foreground; + } + }); + + TYPES.keySet().forEach(type -> { + if (!type.equals("off")) { + ACTIVE_TYPES.add(type); + } + }); + } + + public static ColorCorrector get(String type) { + if (!TYPES.containsKey(type)) { + type = "normal"; + } + return TYPES.get(type); + } + +} diff --git a/src/chatty/gui/HtmlColors.java b/src/chatty/util/colors/HtmlColors.java similarity index 75% rename from src/chatty/gui/HtmlColors.java rename to src/chatty/util/colors/HtmlColors.java index 3e9e0f58c..910b85843 100644 --- a/src/chatty/gui/HtmlColors.java +++ b/src/chatty/util/colors/HtmlColors.java @@ -1,6 +1,8 @@ -package chatty.gui; +package chatty.util.colors; +import chatty.gui.NamedColor; +import chatty.util.Debugging; import java.awt.Color; import java.util.ArrayList; import java.util.List; @@ -267,103 +269,6 @@ public static void setDefaultColor(Color color) { defaultColor = color; } - /** - * Gets the perceived brightness of the given Color. - * - * @param color - * @return - */ - public static int getBrightness(Color color) { - return (color.getRed() * 299 - + color.getGreen() * 587 - + color.getBlue() * 114) / 1000; - } - - /** - * Gets the difference between the perceived brightness between colors. - * - * @param c1 - * @param c2 - * @return - */ - public static int getBrightnessDifference(Color c1, Color c2) { - int b1 = getBrightness(c1); - int b2 = getBrightness(c2); - return b1 - b2; - } - - /** - * Tries to change the color (if necessary) so it it better readable on - * the given background color. - * - * This works for a few colors, but is far from perfect. For example - * some colors have a high enough brightness difference, but they are - * still not very well readable, e.g. springgreen on light grey. - * - * @param foreground - * @param background - * @return - */ - public static Color correctReadability(Color foreground, Color background) { - int bd = getBrightnessDifference(foreground, background); - if (Math.abs(bd) < 50) { - if (getBrightness(background) > 180) { - foreground = makeDarker(foreground,0.5f); - } - else { - foreground = makeBrighter(foreground,0.5f); - } - } -// if (bd > 0 && bd < 50) { -// System.out.println("Making brighter"); -// foreground = makeBrighter(foreground, 0.5f); -// } -// else if (bd < 0 && bd > -50) { -// System.out.println("Making darker"); -// foreground = foreground.darker(); -// } - //System.out.println(bd+" "+foreground); - return foreground; - } - - /** - * Tries to make the given color brighter. Might not work very well with - * colors like 0000FF because hsb[2] is already 1.0. - * - * @param color - * @param factor - * @return - */ - public static Color makeBrighter(Color color, float factor) { - int red = color.getRed(); - int green = color.getGreen(); - int blue = color.getBlue(); - float[] hsb = Color.RGBtoHSB(red, green, blue, null); - //System.out.println(hsb[2]); - if (hsb[2] == 1) { - red += 150; - green += 150; - blue += 150; - if (blue > 255) { - blue = 255; - } - if (red > 255) { - red = 255; - } - if (green > 255) { - green = 255; - } - hsb = Color.RGBtoHSB(red, green, blue, null); - } - return Color.getHSBColor(hsb[0], hsb[1], factor * (1f + hsb[2])); - } - - public static Color makeDarker(Color color, float factor) { - float hsb[] = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); - return Color.getHSBColor(hsb[0], hsb[1], factor * hsb[2]); - } - - public static String getColorString(Color color) { if (color == null) { return null; diff --git a/src/chatty/util/commands/CustomCommands.java b/src/chatty/util/commands/CustomCommands.java index 6fcae49f6..f1124e3b7 100644 --- a/src/chatty/util/commands/CustomCommands.java +++ b/src/chatty/util/commands/CustomCommands.java @@ -3,6 +3,7 @@ import chatty.Helper; import chatty.Room; +import chatty.TwitchClient; import chatty.util.DateTime; import chatty.util.StringUtil; import chatty.util.api.StreamInfo; @@ -32,10 +33,12 @@ public class CustomCommands { private final Settings settings; private final TwitchApi api; + private final TwitchClient client; - public CustomCommands(Settings settings, TwitchApi api) { + public CustomCommands(Settings settings, TwitchApi api, TwitchClient client) { this.settings = settings; this.api = api; + this.client = client; } /** @@ -60,6 +63,9 @@ public synchronized String command(CustomCommand command, Parameters parameters, // Add some more parameters parameters.put("chan", Helper.toStream(room.getChannel())); parameters.put("stream", room.getStream()); + Set chans = new HashSet<>(); + client.getOpenChannels().forEach(chan -> { if (Helper.isRegularChannelStrict(chan)) chans.add(Helper.toStream(chan));}); + parameters.put("chans", StringUtil.join(chans, " ")); if (!command.getIdentifiersWithPrefix("stream").isEmpty()) { System.out.println("request"); String stream = Helper.toValidStream(room.getStream());