mirror of https://github.com/zlatinb/muwire
hook up profiles with search results, sending and rendering side
parent
3e3e0d5b68
commit
216d0db303
|
@ -430,7 +430,8 @@ public class Core {
|
|||
eventBus.register(UIFeedUpdateEvent.class, feedClient)
|
||||
|
||||
log.info "initializing results sender"
|
||||
ResultsSender resultsSender = new ResultsSender(eventBus, i2pConnector, me, props, certificateManager, chatServer, collectionManager)
|
||||
ResultsSender resultsSender = new ResultsSender(eventBus, i2pConnector, me, { getMyProfile()?.getHeader() } as Supplier,
|
||||
props, certificateManager, chatServer, collectionManager)
|
||||
|
||||
log.info "initializing search manager"
|
||||
SearchManager searchManager = new SearchManager(eventBus, me, resultsSender, props)
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.muwire.core.connection.Endpoint
|
|||
import com.muwire.core.connection.I2PConnector
|
||||
import com.muwire.core.filecert.CertificateManager
|
||||
import com.muwire.core.files.FileHasher
|
||||
import com.muwire.core.profile.MWProfileHeader
|
||||
import com.muwire.core.util.DataUtil
|
||||
import com.muwire.core.Persona
|
||||
|
||||
|
@ -16,6 +17,7 @@ import java.util.concurrent.Executor
|
|||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.ThreadFactory
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.function.Supplier
|
||||
import java.util.logging.Level
|
||||
import java.util.stream.Collectors
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
@ -48,17 +50,20 @@ class ResultsSender {
|
|||
|
||||
private final I2PConnector connector
|
||||
private final Persona me
|
||||
private final Supplier<MWProfileHeader> myProfileHeader
|
||||
private final EventBus eventBus
|
||||
private final MuWireSettings settings
|
||||
private final CertificateManager certificateManager
|
||||
private final ChatServer chatServer
|
||||
private final CollectionManager collectionManager
|
||||
|
||||
ResultsSender(EventBus eventBus, I2PConnector connector, Persona me, MuWireSettings settings,
|
||||
CertificateManager certificateManager, ChatServer chatServer, CollectionManager collectionManager) {
|
||||
ResultsSender(EventBus eventBus, I2PConnector connector, Persona me, Supplier<MWProfileHeader> myProfileHeader,
|
||||
MuWireSettings settings, CertificateManager certificateManager, ChatServer chatServer,
|
||||
CollectionManager collectionManager) {
|
||||
this.connector = connector;
|
||||
this.eventBus = eventBus
|
||||
this.me = me
|
||||
this.myProfileHeader = myProfileHeader
|
||||
this.settings = settings
|
||||
this.certificateManager = certificateManager
|
||||
this.chatServer = chatServer
|
||||
|
@ -109,7 +114,8 @@ class ResultsSender {
|
|||
messages : settings.allowMessages,
|
||||
feed : settings.fileFeed && settings.advertiseFeed,
|
||||
collections : collections,
|
||||
path: path
|
||||
path: path,
|
||||
profileHeader: myProfileHeader.get()
|
||||
)
|
||||
uiResultEvents << uiResultEvent
|
||||
}
|
||||
|
@ -168,6 +174,9 @@ class ResultsSender {
|
|||
os.write("Feed: $feed\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
boolean messages = settings.allowMessages
|
||||
os.write("Messages: $messages\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
MWProfileHeader header = myProfileHeader.get()
|
||||
if (header != null)
|
||||
os.write("ProfileHeader: ${myProfileHeader.toBase64()}\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
os.write("\r\n".getBytes(StandardCharsets.US_ASCII))
|
||||
dos = new DataOutputStream(new GZIPOutputStream(os))
|
||||
results.each {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.muwire.core.search
|
|||
import com.muwire.core.Event
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.Persona
|
||||
|
||||
import com.muwire.core.profile.MWProfileHeader
|
||||
import net.i2p.data.Destination
|
||||
|
||||
class UIResultEvent extends Event {
|
||||
|
@ -23,6 +23,7 @@ class UIResultEvent extends Event {
|
|||
boolean messages
|
||||
Set<InfoHash> collections
|
||||
String[] path
|
||||
MWProfileHeader profileHeader
|
||||
|
||||
|
||||
private String fullPath
|
||||
|
|
|
@ -270,6 +270,8 @@ FEED=Feed
|
|||
NEUTRAL=Neutral
|
||||
DISTRUST=Distrust
|
||||
COPY_FULL_ID=Copy Full ID
|
||||
NO_PROFILE=This user does not have a profile
|
||||
|
||||
|
||||
# results table (group by sender)
|
||||
DIRECT_SOURCES=Direct Sources
|
||||
|
|
|
@ -105,7 +105,7 @@ class Initialize extends AbstractLifecycleHandler {
|
|||
} else {
|
||||
fontSize = uiSettings.fontSize
|
||||
}
|
||||
rowHeight = fontSize + 3
|
||||
rowHeight = Math.max(24, fontSize + 3)
|
||||
FontUIResource font = new FontUIResource(fontName, uiSettings.fontStyle, fontSize)
|
||||
|
||||
def keys = lnf.getDefaults().keys()
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.muwire.gui
|
||||
|
||||
import com.muwire.core.InfoHash
|
||||
import com.muwire.core.profile.MWProfileHeader
|
||||
import com.muwire.gui.profile.ImageScaler
|
||||
import com.muwire.gui.profile.PersonaOrProfile
|
||||
import com.muwire.gui.profile.ThumbnailIcon
|
||||
|
||||
import javax.annotation.Nonnull
|
||||
|
||||
|
@ -13,8 +17,11 @@ import griffon.inject.MVCMember
|
|||
import griffon.transform.Observable
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
|
||||
import javax.imageio.ImageIO
|
||||
import javax.swing.Icon
|
||||
import javax.swing.SwingWorker
|
||||
import javax.swing.tree.DefaultMutableTreeNode
|
||||
import java.awt.image.BufferedImage
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
@ -131,7 +138,7 @@ class SearchTabModel {
|
|||
|
||||
SenderBucket senderBucket = sendersBucket.get(event.sender)
|
||||
if (senderBucket == null) {
|
||||
senderBucket = new SenderBucket(event.sender, senders.size())
|
||||
senderBucket = new SenderBucket(event.sender, event.profileHeader, senders.size())
|
||||
sendersBucket[event.sender] = senderBucket
|
||||
senders << senderBucket
|
||||
}
|
||||
|
@ -245,15 +252,40 @@ class SearchTabModel {
|
|||
}
|
||||
}
|
||||
|
||||
static class SenderBucket {
|
||||
static class SenderBucket implements PersonaOrProfile {
|
||||
final Persona sender
|
||||
private final Icon avatar
|
||||
private final String profileTitle
|
||||
private final int rowIdx
|
||||
final List<UIResultEvent> results = []
|
||||
private int lastUpdatedIdx
|
||||
|
||||
SenderBucket(Persona sender, int rowIdx) {
|
||||
SenderBucket(Persona sender, MWProfileHeader profileHeader,int rowIdx) {
|
||||
this.sender = sender
|
||||
this.rowIdx = rowIdx
|
||||
if (profileHeader != null) {
|
||||
Icon icon = null
|
||||
try {
|
||||
icon = new ThumbnailIcon(profileHeader.getThumbNail())
|
||||
} catch (IOException iox) {}
|
||||
avatar = icon
|
||||
profileTitle = profileHeader.getTitle()
|
||||
} else {
|
||||
avatar = null
|
||||
profileTitle = null
|
||||
}
|
||||
}
|
||||
|
||||
Persona getPersona() {
|
||||
sender
|
||||
}
|
||||
|
||||
Icon getThumbnail() {
|
||||
avatar
|
||||
}
|
||||
|
||||
String getTitle() {
|
||||
profileTitle
|
||||
}
|
||||
|
||||
List<UIResultEvent> getPendingResults() {
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.muwire.gui
|
|||
|
||||
import com.muwire.core.SharedFile
|
||||
import com.muwire.gui.SearchTabModel.SenderBucket
|
||||
import com.muwire.gui.profile.PersonaOrProfile
|
||||
import com.muwire.gui.profile.PersonaOrProfileCellRenderer
|
||||
import com.muwire.gui.profile.PersonaOrProfileComparator
|
||||
import griffon.core.artifact.GriffonView
|
||||
import net.i2p.data.Destination
|
||||
|
||||
|
@ -95,7 +98,7 @@ class SearchTabView {
|
|||
scrollPane (constraints : BorderLayout.CENTER) {
|
||||
sendersTable = table(id : "senders-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
|
||||
tableModel(list : model.senders) {
|
||||
closureColumn(header : trans("SENDER"), preferredWidth : 500, type: Persona, read : { SenderBucket row -> row.sender})
|
||||
closureColumn(header : trans("SENDER"), preferredWidth : 500, type: PersonaOrProfile, read : { SenderBucket row -> row})
|
||||
closureColumn(header : trans("RESULTS"), preferredWidth : 20, type: Integer, read : {SenderBucket row -> row.results.size()})
|
||||
closureColumn(header : trans("BROWSE"), preferredWidth : 20, type: Boolean, read : {SenderBucket row -> row.results[0].browse})
|
||||
closureColumn(header : trans("COLLECTIONS"), preferredWidth : 20, type: Boolean, read : {SenderBucket row -> row.results[0].browseCollections})
|
||||
|
@ -394,12 +397,12 @@ class SearchTabView {
|
|||
})
|
||||
|
||||
// senders table
|
||||
def personaRenderer = new PersonaCellRenderer()
|
||||
def personaComparator = new PersonaComparator()
|
||||
def popRenderer = new PersonaOrProfileCellRenderer()
|
||||
def popComparator = new PersonaOrProfileComparator()
|
||||
sendersTable.addMouseListener(sendersMouseListener)
|
||||
sendersTable.setDefaultRenderer(Integer.class, centerRenderer)
|
||||
sendersTable.setDefaultRenderer(Persona.class, personaRenderer)
|
||||
sendersTable.rowSorter.setComparator(0, personaComparator)
|
||||
sendersTable.setDefaultRenderer(PersonaOrProfile.class, popRenderer)
|
||||
sendersTable.rowSorter.setComparator(0, popComparator)
|
||||
sendersTable.rowSorter.addRowSorterListener({evt -> lastSendersSortEvent = evt})
|
||||
sendersTable.rowSorter.setSortsOnUpdates(true)
|
||||
selectionModel = sendersTable.getSelectionModel()
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.muwire.gui.profile
|
||||
|
||||
import com.muwire.core.Persona
|
||||
|
||||
import javax.swing.JTable
|
||||
import javax.swing.table.DefaultTableCellRenderer
|
||||
import java.awt.Component
|
||||
|
||||
import static com.muwire.gui.Translator.trans
|
||||
|
||||
class PersonaOrProfileCellRenderer extends DefaultTableCellRenderer {
|
||||
@Override
|
||||
Component getTableCellRendererComponent(JTable table, Object value,
|
||||
boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column)
|
||||
|
||||
PersonaOrProfile pop = (PersonaOrProfile) value
|
||||
if (pop.getThumbnail() != null)
|
||||
setIcon(pop.getThumbnail())
|
||||
else
|
||||
setIcon(null)
|
||||
|
||||
if (pop.getTitle() != null)
|
||||
setToolTipText(pop.getTitle())
|
||||
else
|
||||
setToolTipText(trans("NO_PROFILE"))
|
||||
|
||||
Persona persona = pop.getPersona()
|
||||
setText("<html>${htmlize(persona)}</html>")
|
||||
if (isSelected) {
|
||||
setForeground(table.getSelectionForeground())
|
||||
setBackground(table.getSelectionBackground())
|
||||
} else {
|
||||
setForeground(table.getForeground())
|
||||
setBackground(table.getBackground())
|
||||
}
|
||||
this
|
||||
}
|
||||
|
||||
static String htmlize(Persona persona) {
|
||||
int atIdx = persona.getHumanReadableName().indexOf("@")
|
||||
String nickname = persona.getHumanReadableName().substring(0, atIdx)
|
||||
String hashPart = persona.getHumanReadableName().substring(atIdx)
|
||||
"$nickname<font color='gray'>$hashPart</font>"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.muwire.gui.profile
|
||||
|
||||
import java.text.Collator
|
||||
|
||||
class PersonaOrProfileComparator implements Comparator<PersonaOrProfile>{
|
||||
int compare(PersonaOrProfile a, PersonaOrProfile b) {
|
||||
Collator.getInstance().compare(a.getPersona().getHumanReadableName(), b.getPersona().getHumanReadableName())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.muwire.gui.profile;
|
||||
|
||||
import com.muwire.core.Persona;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public interface PersonaOrProfile {
|
||||
Persona getPersona();
|
||||
Icon getThumbnail();
|
||||
String getTitle();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.muwire.gui.profile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ThumbnailIcon implements Icon {
|
||||
|
||||
BufferedImage image;
|
||||
|
||||
public ThumbnailIcon(byte [] rawData) throws IOException {
|
||||
BufferedImage img = ImageIO.read(new ByteArrayInputStream(rawData));
|
||||
image = ImageScaler.scaleToThumbnail(img);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
((Graphics2D)g).drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue