render Mu links in chat

dbus-notify
Zlatin Balevsky 2022-08-04 21:26:16 +01:00
parent 5628c39d57
commit 08d9bf881a
No known key found for this signature in database
GPG Key ID: A72832072D525E41
5 changed files with 142 additions and 49 deletions

View File

@ -231,7 +231,7 @@ class MainFrameController {
originator : core.me, sig : sig.data, queryTime : timestamp, sig2 : sig2))
}
private void downloadLink(FileMuLink link) {
void downloadLink(FileMuLink link) {
view.showDownloadsWindow.call()
def event = new UIDownloadLinkEvent(host: link.host,
infoHash: link.infoHash,
@ -241,7 +241,7 @@ class MainFrameController {
core.eventBus.publish event
}
private void fetchCollectionLink(CollectionMuLink link) {
void fetchCollectionLink(CollectionMuLink link) {
UUID uuid = UUID.randomUUID()

View File

@ -1,16 +1,20 @@
package com.muwire.gui
import com.muwire.core.download.UIDownloadLinkEvent
import com.muwire.core.trust.TrustLevel
import com.muwire.gui.chat.ChatEntry
import com.muwire.gui.chat.ChatEntryPane
import com.muwire.gui.contacts.POPLabel
import com.muwire.gui.mulinks.FileMuLink
import com.muwire.gui.mulinks.MuLink
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.PersonaOrProfileCellRenderer
import com.muwire.gui.profile.PersonaOrProfileComparator
import com.muwire.gui.profile.ProfileConstants
import griffon.core.GriffonApplication
import griffon.core.artifact.GriffonView
import griffon.core.mvc.MVCGroup
import javax.inject.Inject
import javax.swing.BorderFactory
@ -20,6 +24,7 @@ import javax.swing.border.Border
import javax.swing.text.SimpleAttributeSet
import java.awt.Dimension
import java.text.SimpleDateFormat
import java.util.function.Consumer
import static com.muwire.gui.Translator.trans
import griffon.inject.MVCMember
@ -67,6 +72,8 @@ class ChatRoomView {
def lastMembersTableSortEvent
UISettings settings
private final Consumer<MuLink> muLinkConsumer = new MuLinkConsumer()
void initUI() {
settings = application.context.get("ui-settings")
int rowHeight = application.context.get("row-height")
@ -252,7 +259,7 @@ class ChatRoomView {
StyledDocument doc = roomTextArea.getStyledDocument()
def textField = new ChatEntry(text, settings, model::getByPersona, timestamp, sender)
def textField = new ChatEntry(text, settings, model::getByPersona, muLinkConsumer, timestamp, sender)
def style = doc.addStyle("newStyle", null)
StyleConstants.setComponent(style, textField)
doc.insertString(doc.getEndPosition().getOffset() - 1, " ", style)
@ -270,4 +277,17 @@ class ChatRoomView {
Element element = doc.getParagraphElement(0)
doc.remove(0, element.getEndOffset())
}
private class MuLinkConsumer implements Consumer<MuLink> {
@Override
void accept(MuLink muLink) {
MVCGroup mainFrame = application.mvcGroupManager.findGroup("MainFrame")
if (muLink.getLinkType() == MuLink.LinkType.FILE) {
mainFrame.controller.downloadLink(muLink)
} else if (muLink.getLinkType() == MuLink.LinkType.COLLECTION) {
mainFrame.controller.fetchCollectionLink(muLink)
}
}
}
}

View File

@ -1,25 +1,25 @@
package com.muwire.gui.chat
import com.muwire.core.Constants
import com.muwire.core.Persona
import com.muwire.core.util.DataUtil
import com.muwire.gui.UISettings
import com.muwire.gui.contacts.POPLabel
import com.muwire.gui.mulinks.FileMuLink
import com.muwire.gui.mulinks.InvalidMuLinkException
import com.muwire.gui.mulinks.MuLink
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.ProfileConstants
import net.i2p.data.Base64
import javax.swing.BorderFactory
import javax.swing.JLabel
import javax.swing.JTextPane
import javax.swing.*
import javax.swing.border.Border
import javax.swing.text.Document
import javax.swing.text.SimpleAttributeSet
import javax.swing.text.StyleConstants
import javax.swing.text.StyledDocument
import java.awt.Dimension
import java.text.SimpleDateFormat
import java.util.function.Function
import java.util.function.Consumer
import java.util.function.Function
class ChatEntry extends JTextPane {
@ -27,17 +27,22 @@ class ChatEntry extends JTextPane {
private static final char AT = "@".toCharacter()
private static final char EQUALS = "=".toCharacter()
private static final char LT = "<".toCharacter()
private static final char GT = ">".toCharacter()
private final UISettings settings
private final Function<Persona, PersonaOrProfile> function
private final Consumer<MuLink> linkConsumer
private final List<ChatToken> tokens = []
ChatEntry(String text, UISettings settings, Function<Persona, PersonaOrProfile> function,
Consumer<MuLink> linkConsumer,
long timestamp, PersonaOrProfile sender) {
super()
this.settings = settings
this.function = function
this.linkConsumer = linkConsumer
setEditable(false)
setAlignmentY(0f)
@ -94,6 +99,12 @@ class ChatEntry extends JTextPane {
tokens << new TextChatToken(stringBuilder.toString())
return new PersonaParsingState()
}
if (c == LT) {
consumed = true
stringBuilder.setLength(stringBuilder.length() - 1)
tokens << new TextChatToken(stringBuilder.toString())
return new MuLinkParsingState()
}
this
}
}
@ -129,6 +140,25 @@ class ChatEntry extends JTextPane {
}
}
private class MuLinkParsingState extends ParsingState {
@Override
ParsingState consume(char c) {
if (c == GT) {
stringBuilder.setLength(stringBuilder.length() - 1)
String payload = stringBuilder.toString()
try {
MuLink link = MuLink.parse(payload)
tokens << new LinkChatToken(link)
} catch (InvalidMuLinkException e) {
tokens << new TextChatToken(payload + ">")
}
return new TextParsingState()
}
return this
}
}
private interface ChatToken {
void render()
}
@ -163,4 +193,21 @@ class ChatEntry extends JTextPane {
style)
}
}
private class LinkChatToken implements ChatToken {
private final MuLink link
LinkChatToken(MuLink link){
this.link = link
}
void render() {
StyledDocument document = getStyledDocument()
JPanel panel = new MuLinkPanel(link, settings, linkConsumer)
def style = document.addStyle("newStyle", null)
StyleConstants.setComponent(style, panel)
document.insertString(document.getEndPosition().getOffset() - 1,
" ",
style)
}
}
}

View File

@ -1,39 +0,0 @@
package com.muwire.gui.chat
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.FileMuLink
import javax.swing.Icon
import javax.swing.ImageIcon
import javax.swing.JButton
import javax.swing.JPanel
import java.awt.BorderLayout
import java.awt.Image
import java.util.function.Consumer
class FileLinkPanel extends JPanel {
private static final Icon DOWN_ICON
static {
DOWN_ICON = new ImageIcon(FileLinkPanel.class.getClassLoader().getResource("down_arrow.png"))
}
private final FileMuLink link
private final UISettings settings
private final Consumer<FileMuLink> linkConsumer
FileLinkPanel(FileMuLink link, UISettings settings, Consumer<FileMuLink> linkConsumer) {
super()
this.linkConsumer = linkConsumer
setLayout(new BorderLayout())
def label = new FileLinkLabel(link, settings, false)
add(label, BorderLayout.CENTER)
JButton button = new JButton()
button.setIcon(DOWN_ICON)
button.addActionListener({linkConsumer.accept(link)})
add(button, BorderLayout.EAST)
}
}

View File

@ -0,0 +1,65 @@
package com.muwire.gui.chat
import com.muwire.gui.UISettings
import com.muwire.gui.mulinks.CollectionMuLink
import com.muwire.gui.mulinks.FileMuLink
import com.muwire.gui.mulinks.MuLink
import javax.swing.BorderFactory
import javax.swing.Icon
import javax.swing.ImageIcon
import javax.swing.JButton
import javax.swing.JPanel
import javax.swing.border.Border
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.Insets
import java.util.function.Consumer
class MuLinkPanel extends JPanel {
private static final Icon DOWN_ICON
static {
DOWN_ICON = new ImageIcon(MuLinkPanel.class.getClassLoader().getResource("down_arrow.png"))
}
private final UISettings settings
private final Consumer<MuLink> linkConsumer
MuLinkPanel(MuLink link, UISettings settings, Consumer<MuLink> linkConsumer) {
super()
this.settings = settings
this.linkConsumer = linkConsumer
setLayout(new BorderLayout())
def label = null
if (link.getLinkType() == MuLink.LinkType.FILE)
label = new FileLinkLabel((FileMuLink)link, settings, false)
else if (link.getLinkType() == MuLink.LinkType.COLLECTION)
label = new CollectionLinkLabel((CollectionMuLink)link, settings, false)
add(label, BorderLayout.CENTER)
JButton button = new JButton()
button.setIcon(DOWN_ICON)
button.addActionListener({linkConsumer.accept(link)})
add(button, BorderLayout.EAST)
def labelDim = label.getMaximumSize()
double preferredY = labelDim.getHeight()
double preferredX = labelDim.getWidth() + DOWN_ICON.getIconWidth()
Border border = BorderFactory.createEtchedBorder()
setBorder(border)
Insets insets = border.getBorderInsets(this)
preferredX += insets.left
preferredX += insets.right
preferredY += insets.top
preferredY += insets.bottom
preferredX += 20
setMaximumSize([(int)preferredX, (int)preferredY] as Dimension)
float alignmentY = 0.5f + (settings.fontSize * 1f / preferredY) / 2
setAlignmentY(alignmentY)
}
}