Skip to content

Commit

Permalink
Updated to v0.13.1.
Browse files Browse the repository at this point in the history
  • Loading branch information
23rd committed Nov 17, 2020
2 parents 8f0c52d + b4cc8da commit 31e31cd
Showing 17 changed files with 142 additions and 53 deletions.
9 changes: 9 additions & 0 deletions src/chatty/Helper.java
Original file line number Diff line number Diff line change
@@ -755,6 +755,15 @@ public static Map<String, String> parseBadges(String data) {
return Collections.unmodifiableMap(result);
}

public static short parseShort(String input, short defaultValue) {
try {
return Short.parseShort(input);
}
catch (NumberFormatException ex) {
return defaultValue;
}
}

public static String makeDisplayNick(User user, long displayNamesMode) {
if (user.hasCustomNickSet()) {
return user.getFullNick();
6 changes: 6 additions & 0 deletions src/chatty/TwitchConnection.java
Original file line number Diff line number Diff line change
@@ -918,6 +918,12 @@ private void updateUserFromTags(User user, MsgTags tags) {
changed = true;
}

Map<String, String> badgeInfo = Helper.parseBadges(tags.get("badge-info"));
String subMonths = badgeInfo.get("subscriber");
if (subMonths != null) {
user.setSubMonths(Helper.parseShort(subMonths, (short)0));
}

if (settings.getBoolean("ircv3CapitalizedNames")) {
if (user.setDisplayNick(StringUtil.trim(tags.get("display-name")))) {
changed = true;
9 changes: 9 additions & 0 deletions src/chatty/User.java
Original file line number Diff line number Diff line change
@@ -90,6 +90,7 @@ public class User implements Comparable<User> {
* Current badges id/version. Map gets replaced, not modified.
*/
private Map<String, String> twitchBadges;
private short subMonths;
private volatile UsericonManager iconManager;

//===========
@@ -205,6 +206,14 @@ public List<Usericon> getBadges(boolean botBadgeEnabled, boolean pointsHl, boole
return null;
}

public synchronized void setSubMonths(short months) {
this.subMonths = months;
}

public synchronized short getSubMonths() {
return subMonths;
}

/**
* Should probably not be set back to null, which might not be safe in
* regards to synchronization.
3 changes: 3 additions & 0 deletions src/chatty/gui/colors/UsercolorItem.java
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ public class UsercolorItem extends ColorItem {
public static final int TYPE_STATUS = 2;
public static final int TYPE_ALL = 3;
public static final int TYPE_CATEGORY = 4;
public static final int TYPE_DEFAULT_COLOR = 5;
public static final int TYPE_UNDEFINED = -1;

public final Color color;
@@ -67,6 +68,8 @@ public UsercolorItem(String id, Color color) {
type = TYPE_NAME;
} else if (id.equals("$all")) {
type = TYPE_ALL;
} else if (id.toLowerCase().equals("$defaultcolor")) {
type = TYPE_DEFAULT_COLOR;
} else {
type = TYPE_UNDEFINED;
}
17 changes: 13 additions & 4 deletions src/chatty/gui/colors/UsercolorManager.java
Original file line number Diff line number Diff line change
@@ -109,19 +109,28 @@ public synchronized Color getColor(User user) {
if (item.idColor.equals(user.getPlainColor())) {
return item.color;
}
} else if (item.type == UsercolorItem.TYPE_NAME) {
}
else if (item.type == UsercolorItem.TYPE_NAME) {
if (item.id.equalsIgnoreCase(user.getName())) {
return item.color;
}
} else if (item.type == UsercolorItem.TYPE_STATUS) {
}
else if (item.type == UsercolorItem.TYPE_STATUS) {
if (Helper.matchUserStatus(item.id, user)) {
return item.color;
}
} else if (item.type == UsercolorItem.TYPE_CATEGORY) {
}
else if (item.type == UsercolorItem.TYPE_CATEGORY) {
if (user.hasCategory(item.category)) {
return item.color;
}
} else if (item.type == UsercolorItem.TYPE_ALL) {
}
else if (item.type == UsercolorItem.TYPE_DEFAULT_COLOR) {
if (user.hasDefaultColor()) {
return item.color;
}
}
else if (item.type == UsercolorItem.TYPE_ALL) {
return item.color;
}
}
15 changes: 14 additions & 1 deletion src/chatty/gui/components/help/help-releases.html
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
<h1><a name="top">Release Information</a></h1>

<p>
<a href="#0.13.1">0.13.1</a> |
<a href="#0.13">0.13</a> |
<a href="#0.12">0.12</a> |
<a href="#0.11">0.11</a> |
@@ -61,7 +62,19 @@ <h1><a name="top">Release Information</a></h1>
full list of changes.</p>

<h2>
<a name="0.13">Version 0.13</a> <a name="latest">(This one!)</a> (2020-10-17)
<a name="0.13.1">Version 0.13.1</a> <a name="latest">(This one!)</a> (2020-11-17)
<a href="#top" class="top">[back to top]</a>
</h2>
<pre>
- Added number of subbed months to subscriber badge tooltip
- Added "$defaultColor" type for Custom Usercolors
- Improved color info in User Dialog when a default color is being replaced
- Added "All Types" option for Custom Badges
- Fixed FFZ emotes not loading
</pre>

<h2>
<a name="0.13">Version 0.13</a> (2020-10-17)
<a href="#top" class="top">[back to top]</a>
</h2>
<p>Chatty now supports the Twitch reply feature, both marking replies with
1 change: 1 addition & 0 deletions src/chatty/gui/components/help/help-settings.html
Original file line number Diff line number Diff line change
@@ -152,6 +152,7 @@ <h2>
<li><code>$color:&lt;color code or name&gt;</code> - A Html color code or name (names
as hardcoded into Chatty, may be different from other programs), e.g. <code>$color:Blue</code> for blue,
which can be used to replace colors</li>
<li><code>$defaultColor</code> - Users that don't have a color set and have the default assigned color (somewhat random)</li>
</ul>

<p>The order of the
2 changes: 1 addition & 1 deletion src/chatty/gui/components/help/help.html
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<h1><a name="top">Chatty (Version: 0.13)</a></h1>
<h1><a name="top">Chatty (Version: 0.13.1)</a></h1>
<table>
<tr>
<td valign="top">
1 change: 1 addition & 0 deletions src/chatty/gui/components/settings/UsericonEditor.java
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@ public UsericonEditor(JDialog owner, LinkLabelListener linkLabelListener) {
typeNames.put(Usericon.Type.TWITCH, "Other (Twitch)");
typeNames.put(Usericon.Type.OTHER, "Other (Third-Party)");
typeNames.put(Usericon.Type.HL, "Highlighted (by points)");
typeNames.put(Usericon.Type.ALL, "All Types");
typeNames.put(Usericon.Type.TURBO, "Turbo");
typeNames.put(Usericon.Type.PRIME, "Prime");
typeNames.put(Usericon.Type.BITS, "Bits");
13 changes: 10 additions & 3 deletions src/chatty/gui/components/textpane/ChannelTextPane.java
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ public enum Attribute {
IS_BAN_MESSAGE, BAN_MESSAGE_COUNT, TIMESTAMP, USER, IS_USER_MESSAGE,
URL_DELETED, DELETED_LINE, EMOTICON, IS_APPENDED_INFO, INFO_TEXT, BANS,
BAN_MESSAGE, ID, ID_AUTOMOD, AUTOMOD_ACTION, USERICON, IMAGE_ID, ANIMATED,
APPENDED_INFO_UPDATED, MENTION,
APPENDED_INFO_UPDATED, MENTION, USERICON_INFO,

HIGHLIGHT_WORD, HIGHLIGHT_LINE, EVEN, PARAGRAPH_SPACING,
CUSTOM_BACKGROUND, CUSTOM_FOREGROUND,
@@ -1996,7 +1996,7 @@ private void printUserIcons(User user, boolean pointsHl) {
if (badges != null) {
for (Usericon badge : badges) {
if (badge.image != null && !badge.removeBadge) {
print(badge.getSymbol(), styles.makeIconStyle(badge));
print(badge.getSymbol(), styles.makeIconStyle(badge, user));
}
}
}
@@ -3965,16 +3965,23 @@ public MutableAttributeSet mention(User user, AttributeSet style,
* once.
*
* @param icon
* @param user
* @return The created style (or read from the cache)
*/
public MutableAttributeSet makeIconStyle(Usericon icon) {
public MutableAttributeSet makeIconStyle(Usericon icon, User user) {
MutableAttributeSet style = savedIcons.get(icon);
if (style == null) {
//System.out.println("Creating icon style: "+icon);
style = new SimpleAttributeSet(nick());
if (icon != null && icon.image != null) {
StyleConstants.setIcon(style, addSpaceToIcon(icon.image));
style.addAttribute(Attribute.USERICON, icon);
if (icon.type == Usericon.Type.TWITCH
&& Usericon.typeFromBadgeId(icon.badgeType.id) == Usericon.Type.SUB
&& user != null
&& user.getSubMonths() > 0) {
style.addAttribute(Attribute.USERICON_INFO, DateTime.formatMonthsVerbose(user.getSubMonths()));
}
}
savedIcons.put(icon, style);
}
11 changes: 9 additions & 2 deletions src/chatty/gui/components/textpane/LinkController.java
Original file line number Diff line number Diff line change
@@ -277,7 +277,7 @@ public void mouseMoved(MouseEvent e) {
if (emoteImage != null) {
popup.show(textPane, element, p -> makeEmoticonPopupText(emoteImage, popupImagesEnabled, p, element), emoteImage.getImageIcon().getIconWidth());
} else if (usericon != null) {
popup.show(textPane, element, p -> makeUsericonPopupText(usericon, p), usericon.image.getIconWidth());
popup.show(textPane, element, p -> makeUsericonPopupText(usericon, getUsericonInfo(element), p), usericon.image.getIconWidth());
} else if (replacedText != null) {
popup.show(textPane, element, p -> makeReplacementPopupText(replacedText, p), 1);
} else if (replyMsgId != null) {
@@ -359,6 +359,10 @@ private Usericon getUsericon(Element e) {
return (Usericon)(e.getAttributes().getAttribute(ChannelTextPane.Attribute.USERICON));
}

private String getUsericonInfo(Element e) {
return (String)(e.getAttributes().getAttribute(ChannelTextPane.Attribute.USERICON_INFO));
}

private String getReplacedText(Element e) {
return (String)(e.getAttributes().getAttribute(ChannelTextPane.Attribute.REPLACEMENT_FOR));
}
@@ -783,7 +787,7 @@ private static String makeEmoticonPopupText2(EmoticonImage emoticonImage, boolea
// Usericon Popup
//----------------

private static void makeUsericonPopupText(Usericon usericon, MyPopup p) {
private static void makeUsericonPopupText(Usericon usericon, String moreInfo, MyPopup p) {
String info;
if (!usericon.metaTitle.isEmpty()) {
info = POPUP_HTML_PREFIX+"Badge: "+usericon.metaTitle;
@@ -804,6 +808,9 @@ private static void makeUsericonPopupText(Usericon usericon, MyPopup p) {
if (Debugging.isEnabled("tt")) {
info += " ["+usericon.image.getDescription()+"]";
}
if (!StringUtil.isNullOrEmpty(moreInfo)) {
info += "<br />("+moreInfo+")";
}
p.setText(info);
}

10 changes: 6 additions & 4 deletions src/chatty/gui/components/userinfo/InfoPanel.java
Original file line number Diff line number Diff line change
@@ -152,10 +152,12 @@ private void updateColor() {

if (currentUser.hasCustomColor()) {
Color plainColor = currentUser.getPlainColor();
colorText = "Color: "+colorNamed+"**";
colorTooltipText = "Custom Color: "+colorCode
+" (Original: "+HtmlColors.getNamedColorString(plainColor)+"/"
+ HtmlColors.getColorString(plainColor)+")";
colorText = "Color: "+colorNamed+"**"+(currentUser.hasDefaultColor() ? "*" : "");
colorTooltipText = String.format("Custom Color: %s (Original: %s/%s%s)",
colorCode,
HtmlColors.getNamedColorString(plainColor),
HtmlColors.getColorString(plainColor),
currentUser.hasDefaultColor() ? " (default)" : "");
} else if (currentUser.hasDefaultColor()) {
colorText = "Color: "+colorNamed+"*";
colorTooltipText = "Color: "+colorCode+" (default)";
25 changes: 25 additions & 0 deletions src/chatty/util/DateTime.java
Original file line number Diff line number Diff line change
@@ -363,6 +363,31 @@ public static SimpleDateFormat createSdfAmPm(String format) {
return new SimpleDateFormat(format);
}

public static String formatMonthsVerbose(int months) {
if (months < 12) {
return months+" months";
}
return months+" months, "+formatMonths(months);
}

public static String formatMonths(int months) {
if (months < 12) {
return months+" months";
}
int y = months / 12;
int m = months % 12;
if (m == 0) {
return String.format("%d %s",
y,
y == 1 ? "year" : "years");
}
return String.format("%d %s %d %s",
y,
y == 1 ? "year" : "years",
m,
m == 1 ? "month" : "months");
}

public static final void main(String[] args) {
// System.out.println("'"+dur(HOUR*2+1, Formatting.COMPACT, 0, -2, 2, 2, 2)+"'");
// System.out.println("'"+duration(1000*MINUTE*1+1000, Formatting.COMPACT, N, 0, 0, 0, 2)+"'");
10 changes: 3 additions & 7 deletions src/chatty/util/ImageCache.java
Original file line number Diff line number Diff line change
@@ -436,13 +436,9 @@ private static boolean saveFile(URL url, Path file) {
try {
URLConnection c = url.openConnection();
try (InputStream is = c.getInputStream()) {
if (c.getContentLengthLong() <= 0) {
LOGGER.warning("Error saving " + url + " (empty): " + c.getHeaderField(null));
} else {
long written = Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
if (written > 0) {
return true;
}
long written = Files.copy(is, file, StandardCopyOption.REPLACE_EXISTING);
if (written > 0) {
return true;
}
}
} catch (IOException ex) {
1 change: 1 addition & 0 deletions src/chatty/util/api/usericons/Usericon.java
Original file line number Diff line number Diff line change
@@ -67,6 +67,7 @@ public enum Type {
HL(14, "Highlighted by channel points", "HL", "'", null, null),
CHANNEL_LOGO(15, "Channel Logo", "CHL", null, null, null),
FOUNDER(16, "Founder", "FND", "%", "founder", null),
ALL(17, "All Types", "ALL", "", null, null),
UNDEFINED(-1, "Undefined", "UDF", null, null, null);

public Color color;
5 changes: 4 additions & 1 deletion src/chatty/util/api/usericons/UsericonManager.java
Original file line number Diff line number Diff line change
@@ -444,7 +444,10 @@ else if (!usernameR || !useridR) {

private boolean iconsMatchesAdvancedType(Usericon icon,
Usericon.Type requestedType, String id, String version) {
if (icon.type == requestedType) {
if (icon.type == Type.ALL) {
return true;
}
else if (icon.type == requestedType) {
if (icon.badgeType.matchesLenient(id, version)) {
return true;
}
57 changes: 27 additions & 30 deletions src/chatty/util/gif/GifUtil.java
Original file line number Diff line number Diff line change
@@ -36,39 +36,36 @@ public static ImageIcon getGifFromUrl(URL url) throws Exception {
ImageIcon image = null;
URLConnection c = url.openConnection();
try (InputStream input = c.getInputStream()) {
if (c.getContentLengthLong() <= 0) {
LOGGER.warning("Error saving " + url + " (empty): " + c.getHeaderField(null));
} else {
// Use readAllBytes() because GifDecoder doesn't handle streams well
byte[] imageData = readAllBytes(input);

try {
//System.out.println(hash(imageData)+" "+url);
image = fixGifFps(imageData);
} catch (Exception ex) {
/**
* If not a GIF, or another error occured, just create the
* image normally.
*/
image = new ImageIcon(imageData);
if (image.getIconWidth() == -1) {
// new ImageIcon() breaks with some images (rare)
// Checking for MediaTracker.ERRORED seems to sometimes
// not work.
LOGGER.info("Using ImageIO for "+url);
Image loadedImage = ImageIO.read(new ByteArrayInputStream(imageData));
if (loadedImage != null) {
image.setImage(loadedImage);
image.setDescription("ImageIO");
}
// Use readAllBytes() because GifDecoder doesn't handle streams well
byte[] imageData = readAllBytes(input);

try {
//System.out.println(hash(imageData)+" "+url);
image = fixGifFps(imageData);
}
catch (Exception ex) {
/**
* If not a GIF, or another error occured, just create the image
* normally.
*/
image = new ImageIcon(imageData);
if (image.getIconWidth() == -1) {
// new ImageIcon() breaks with some images (rare)
// Checking for MediaTracker.ERRORED seems to sometimes
// not work.
LOGGER.info("Using ImageIO for " + url);
Image loadedImage = ImageIO.read(new ByteArrayInputStream(imageData));
if (loadedImage != null) {
image.setImage(loadedImage);
image.setDescription("ImageIO");
}
}
}

//System.out.println(url+" "+image.getImageLoadStatus()+" "+image.getIconHeight());
if (image.getImageLoadStatus() == MediaTracker.ERRORED
|| image.getIconWidth() == -1) {
return null;
}
//System.out.println(url+" "+image.getImageLoadStatus()+" "+image.getIconHeight());
if (image.getImageLoadStatus() == MediaTracker.ERRORED
|| image.getIconWidth() == -1) {
return null;
}
}
return image;

0 comments on commit 31e31cd

Please sign in to comment.