diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java index 19e2e94c30..9b6d1e2229 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/feed/FeedPanel.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2018, Lotto + * Copyright (c) 2018, Psikoi * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +29,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; +import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; @@ -43,13 +45,16 @@ import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; +import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import lombok.extern.slf4j.Slf4j; +import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.LinkBrowser; +import net.runelite.client.util.SwingUtil; import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.feed.FeedItem; import net.runelite.http.api.feed.FeedItemType; @@ -63,8 +68,10 @@ import okhttp3.ResponseBody; @Slf4j class FeedPanel extends PluginPanel { - private static BufferedImage RUNELITE_ICON; - private static BufferedImage OSRS_ICON; + private static final ImageIcon RUNELITE_ICON; + private static final ImageIcon OSRS_ICON; + private static final ImageIcon RESET_ICON; + private static final ImageIcon RESET_ICON_CLICK; //used as a click effect (darker version of the reset icon) private static final Color TWEET_BACKGROUND = new Color(15, 15, 15); private static final Color OSRS_NEWS_BACKGROUND = new Color(36, 30, 19); @@ -74,6 +81,11 @@ class FeedPanel extends PluginPanel private static final int CONTENT_WIDTH = 148; private static final int TIME_WIDTH = 20; + /** + * Holds all feed items. + */ + private final JPanel feedContainer = new JPanel(); + private static final Comparator FEED_ITEM_COMPARATOR = (o1, o2) -> { if (o1.getType() != o2.getType()) @@ -97,24 +109,16 @@ class FeedPanel extends PluginPanel { synchronized (ImageIO.class) { - RUNELITE_ICON = ImageIO.read(FeedPanel.class.getResourceAsStream("runelite.png")); + BufferedImage reset = ImageIO.read(FeedPanel.class.getResourceAsStream("reset.png")); + RUNELITE_ICON = new ImageIcon(ImageIO.read(FeedPanel.class.getResourceAsStream("runelite.png"))); + OSRS_ICON = new ImageIcon(ImageIO.read(FeedPanel.class.getResourceAsStream("osrs.png"))); + RESET_ICON = new ImageIcon(reset); + RESET_ICON_CLICK = new ImageIcon(SwingUtil.grayscaleOffset(reset, -100)); } } catch (IOException e) { - log.warn("Client icon failed to load", e); - } - - try - { - synchronized (ImageIO.class) - { - OSRS_ICON = ImageIO.read(FeedPanel.class.getResourceAsStream("osrs.png")); - } - } - catch (IOException e) - { - log.warn("OSRS icon failed to load", e); + throw new RuntimeException(e); } } @@ -125,6 +129,56 @@ class FeedPanel extends PluginPanel { this.config = config; this.feedSupplier = feedSupplier; + + setBorder(new EmptyBorder(10, 10, 10, 10)); + setBackground(ColorScheme.DARK_GRAY_COLOR); + setLayout(new BorderLayout()); + + feedContainer.setLayout(new GridLayout(0, 1, 0, 4)); + feedContainer.setOpaque(false); + + /** + * This header contains the "News Feed" title and a refresh icon button. + */ + JPanel header = new JPanel(); + header.setOpaque(false); + header.setLayout(new BorderLayout()); + header.setBorder(new EmptyBorder(0, 0, 9, 0)); + + /** + * A refresh icon button, when clicked, it will swap icons for feedback effect and then call + * the rebuildFeed method. + */ + JLabel reset = new JLabel(); + reset.setIcon(RESET_ICON); + reset.setVerticalAlignment(SwingConstants.CENTER); + reset.setHorizontalAlignment(SwingConstants.CENTER); + reset.setToolTipText("Refresh"); + + reset.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent mouseEvent) + { + reset.setIcon(RESET_ICON_CLICK); + rebuildFeed(); + } + + @Override + public void mouseReleased(MouseEvent mouseEvent) + { + reset.setIcon(RESET_ICON); + } + }); + + JLabel title = new JLabel("News feed"); + title.setForeground(Color.WHITE); + + header.add(title, BorderLayout.WEST); + header.add(reset, BorderLayout.EAST); + + add(header, BorderLayout.NORTH); + add(feedContainer, BorderLayout.CENTER); } void rebuildFeed() @@ -138,7 +192,7 @@ class FeedPanel extends PluginPanel SwingUtilities.invokeLater(() -> { - removeAll(); + feedContainer.removeAll(); feed.getItems() .stream() @@ -207,14 +261,14 @@ class FeedPanel extends PluginPanel case OSRS_NEWS: if (OSRS_ICON != null) { - avatar.setIcon(new ImageIcon(OSRS_ICON)); + avatar.setIcon(OSRS_ICON); } avatarAndRight.setBackground(OSRS_NEWS_BACKGROUND); break; default: if (RUNELITE_ICON != null) { - avatar.setIcon(new ImageIcon(RUNELITE_ICON)); + avatar.setIcon(RUNELITE_ICON); } avatarAndRight.setBackground(BLOG_POST_BACKGROUND); break; @@ -296,7 +350,7 @@ class FeedPanel extends PluginPanel } }); - add(avatarAndRight); + feedContainer.add(avatarAndRight); } private String durationToString(Duration duration) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/feed/reset.png b/runelite-client/src/main/resources/net/runelite/client/plugins/feed/reset.png new file mode 100644 index 0000000000..e94f6102a5 Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/feed/reset.png differ