mirror of https://github.com/zlatinb/muwire
render Mu links in chat
parent
5628c39d57
commit
08d9bf881a
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue