From fec578efa4b85c90bfadd01efec8e2577ddbd848 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Tue, 31 May 2022 11:06:41 +0100 Subject: [PATCH] show profile thumbnails in group-by-file view --- .../resultdetails/CertificateListModel.groovy | 12 +++-- .../resultdetails/CollectionListModel.groovy | 12 +++-- .../ResultDetailsTabsModel.groovy | 31 +++++++------ .../views/com/muwire/gui/SearchTabView.groovy | 3 +- .../resultdetails/CertificateListView.groovy | 7 +-- .../resultdetails/CollectionListView.groovy | 7 +-- .../ResultDetailsTabsView.groovy | 46 ++++++++++++------- .../com/muwire/gui/profile/ResultPOP.groovy | 35 ++++++++++++++ .../ResultListCellRenderer.groovy | 22 +++++++-- 9 files changed, 123 insertions(+), 52 deletions(-) create mode 100644 gui/src/main/groovy/com/muwire/gui/profile/ResultPOP.groovy diff --git a/gui/griffon-app/models/com/muwire/gui/resultdetails/CertificateListModel.groovy b/gui/griffon-app/models/com/muwire/gui/resultdetails/CertificateListModel.groovy index d9b7c7e3..6ae018b5 100644 --- a/gui/griffon-app/models/com/muwire/gui/resultdetails/CertificateListModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/resultdetails/CertificateListModel.groovy @@ -3,6 +3,7 @@ package com.muwire.gui.resultdetails import com.muwire.core.Core import com.muwire.core.Persona import com.muwire.core.search.UIResultEvent +import com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonModel import griffon.core.mvc.MVCGroup import griffon.inject.MVCMember @@ -18,14 +19,14 @@ class CertificateListModel { CertificateListView view Core core - List results + List results String uuid Map tabGroups = new HashMap<>() void mvcGroupInit(Map args) { - for(UIResultEvent event : results) { - tabGroups.put(event.sender, createTabGroup(event)) + for(ResultPOP resultPOP : results) { + tabGroups.put(resultPOP.getEvent().sender, createTabGroup(resultPOP.getEvent())) } } @@ -33,13 +34,14 @@ class CertificateListModel { tabGroups.values().each {it.destroy()} } - void addResult(UIResultEvent event) { + void addResult(ResultPOP resultPOP) { + UIResultEvent event = resultPOP.getEvent() if (event.certificates == 0) return if (tabGroups.containsKey(event.sender)) return tabGroups.put(event.sender, createTabGroup(event)) - results << event + results << resultPOP view.refresh() } diff --git a/gui/griffon-app/models/com/muwire/gui/resultdetails/CollectionListModel.groovy b/gui/griffon-app/models/com/muwire/gui/resultdetails/CollectionListModel.groovy index 0b30d4ac..b306f247 100644 --- a/gui/griffon-app/models/com/muwire/gui/resultdetails/CollectionListModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/resultdetails/CollectionListModel.groovy @@ -3,6 +3,7 @@ package com.muwire.gui.resultdetails import com.muwire.core.Core import com.muwire.core.Persona import com.muwire.core.search.UIResultEvent +import com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonModel import griffon.core.mvc.MVCGroup import griffon.inject.MVCMember @@ -18,14 +19,14 @@ class CollectionListModel { CollectionListView view Core core - List results + List results String uuid Map tabGroups = new HashMap<>() void mvcGroupInit(Map args) { - for(UIResultEvent event : results) { - tabGroups.put(event.sender, createTabGroup(event)) + for(ResultPOP resultPOP : results) { + tabGroups.put(resultPOP.getPersona(), createTabGroup(resultPOP.getEvent())) } } @@ -33,13 +34,14 @@ class CollectionListModel { tabGroups.values().each {it.destroy()} } - void addResult(UIResultEvent event) { + void addResult(ResultPOP resultPOP) { + UIResultEvent event = resultPOP.getEvent() if (event.collections.isEmpty()) return if (tabGroups.containsKey(event.sender)) return tabGroups.put(event.sender, createTabGroup(event)) - results << event + results << resultPOP view.refresh() } diff --git a/gui/griffon-app/models/com/muwire/gui/resultdetails/ResultDetailsTabsModel.groovy b/gui/griffon-app/models/com/muwire/gui/resultdetails/ResultDetailsTabsModel.groovy index affa38a8..49739000 100644 --- a/gui/griffon-app/models/com/muwire/gui/resultdetails/ResultDetailsTabsModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/resultdetails/ResultDetailsTabsModel.groovy @@ -4,6 +4,7 @@ import com.muwire.core.Core import com.muwire.core.InfoHash import com.muwire.core.SharedFile import com.muwire.core.search.UIResultEvent +import com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonModel import griffon.inject.MVCMember import griffon.metadata.ArtifactProviderFor @@ -24,27 +25,28 @@ class ResultDetailsTabsModel { Core core String fileName InfoHash infoHash - List results + List results String uuid String key private final Set uniqueResults = new HashSet<>() - List resultsWithComments = [] - List resultsWithCertificates = [] - List resultsWithCollections = [] + List resultsWithComments = [] + List resultsWithCertificates = [] + List resultsWithCollections = [] void mvcGroupInit(Map args) { key = fileName + Base64.encode(infoHash.getRoot()) - uniqueResults.addAll(results) - for (UIResultEvent event : results) { + uniqueResults.addAll(results.collect {it.getEvent()}) + for (ResultPOP resultPOP : results) { + def event = resultPOP.getEvent() if (event.comment != null) - resultsWithComments << event + resultsWithComments << resultPOP if (event.certificates > 0) - resultsWithCertificates << event + resultsWithCertificates << resultPOP if (event.collections.size() > 0) - resultsWithCollections << event + resultsWithCollections << resultPOP } } @@ -58,14 +60,15 @@ class ResultDetailsTabsModel { void addResult(UIResultEvent event) { if (!uniqueResults.add(event)) return - results << event + def resultPOP = new ResultPOP(event) + results << resultPOP if (event.comment != null) - resultsWithComments << event + resultsWithComments << resultPOP if (event.certificates > 0) - resultsWithCertificates << event + resultsWithCertificates << resultPOP if (event.collections.size() > 0) - resultsWithCollections << event - view.addResultToListGroups(event) + resultsWithCollections << resultPOP + view.addResultToListGroups(resultPOP) view.refreshAll() } } diff --git a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy index 72f74734..3e4e7777 100644 --- a/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/SearchTabView.groovy @@ -5,6 +5,7 @@ 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 com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonView import net.i2p.data.Destination @@ -498,7 +499,7 @@ class SearchTabView { if (group == null) { String mvcId = model.uuid + Base64.encode(infoHash.getRoot()) - List allResults = new ArrayList<>(model.hashBucket[infoHash].getResults()) + List allResults = model.hashBucket[infoHash].getResults().collect{new ResultPOP(it)} def params = [:] params.core = model.core diff --git a/gui/griffon-app/views/com/muwire/gui/resultdetails/CertificateListView.groovy b/gui/griffon-app/views/com/muwire/gui/resultdetails/CertificateListView.groovy index e2d0d02d..ef59534e 100644 --- a/gui/griffon-app/views/com/muwire/gui/resultdetails/CertificateListView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/resultdetails/CertificateListView.groovy @@ -1,6 +1,7 @@ package com.muwire.gui.resultdetails import com.muwire.core.search.UIResultEvent +import com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonView import griffon.inject.MVCMember import griffon.metadata.ArtifactProviderFor @@ -24,7 +25,7 @@ class CertificateListView { CertificateListModel model JPanel p - JList senders + JList senders JPanel detailsPanel void initUI() { @@ -52,7 +53,7 @@ class CertificateListView { selectionModel.addListSelectionListener({ detailsPanel.removeAll() detailsPanel.updateUI() - UIResultEvent event = senders.getSelectedValue() + UIResultEvent event = senders.getSelectedValue()?.getEvent() if (event == null) return def mvc = model.tabGroups.get(event.sender) @@ -62,6 +63,6 @@ class CertificateListView { } void refresh() { - senders.setListData(model.results.toArray(new UIResultEvent[0])) + senders.setListData(model.results.toArray(new ResultPOP[0])) } } diff --git a/gui/griffon-app/views/com/muwire/gui/resultdetails/CollectionListView.groovy b/gui/griffon-app/views/com/muwire/gui/resultdetails/CollectionListView.groovy index 1388fd54..aaee0fb6 100644 --- a/gui/griffon-app/views/com/muwire/gui/resultdetails/CollectionListView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/resultdetails/CollectionListView.groovy @@ -1,6 +1,7 @@ package com.muwire.gui.resultdetails import com.muwire.core.search.UIResultEvent +import com.muwire.gui.profile.ResultPOP import griffon.core.artifact.GriffonView import griffon.inject.MVCMember import griffon.metadata.ArtifactProviderFor @@ -22,7 +23,7 @@ class CollectionListView { CollectionListModel model JPanel p - JList senders + JList senders JPanel detailsPanel void initUI() { @@ -50,7 +51,7 @@ class CollectionListView { selectionModel.addListSelectionListener({ detailsPanel.removeAll() detailsPanel.updateUI() - UIResultEvent event = senders.getSelectedValue() + UIResultEvent event = senders.getSelectedValue()?.getEvent() if (event == null) return def mvc = model.tabGroups.get(event.sender) @@ -60,6 +61,6 @@ class CollectionListView { } void refresh() { - senders.setListData(model.results.toArray(new UIResultEvent[0])) + senders.setListData(model.results.toArray(new ResultPOP[0])) } } diff --git a/gui/griffon-app/views/com/muwire/gui/resultdetails/ResultDetailsTabsView.groovy b/gui/griffon-app/views/com/muwire/gui/resultdetails/ResultDetailsTabsView.groovy index 201fe7b9..8381aa57 100644 --- a/gui/griffon-app/views/com/muwire/gui/resultdetails/ResultDetailsTabsView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/resultdetails/ResultDetailsTabsView.groovy @@ -5,6 +5,11 @@ import com.muwire.core.search.UIResultEvent import com.muwire.gui.HTMLSanitizer import com.muwire.gui.PersonaCellRenderer import com.muwire.gui.PersonaComparator +import com.muwire.gui.profile.PersonaOrProfile +import com.muwire.gui.profile.PersonaOrProfileCellRenderer +import com.muwire.gui.profile.PersonaOrProfileComparator +import com.muwire.gui.profile.ResultPOP +import com.muwire.gui.profile.ThumbnailIcon import com.muwire.gui.resultdetails.ResultListCellRenderer import griffon.core.artifact.GriffonView import griffon.core.mvc.MVCGroup @@ -13,6 +18,7 @@ import griffon.metadata.ArtifactProviderFor import net.i2p.data.Base64 import javax.annotation.Nonnull +import javax.swing.Icon import javax.swing.JList import javax.swing.JPanel import javax.swing.JTabbedPane @@ -41,7 +47,7 @@ class ResultDetailsTabsView { JTable sendersTable JPanel commentsPanel - JList commentsList + JList commentsList JTextArea commentTextArea private MVCGroup certificateListGroup @@ -63,14 +69,22 @@ class ResultDetailsTabsView { scrollPane(constraints: BorderLayout.CENTER) { sendersTable = table(autoCreateRowSorter : true, rowHeight : rowHeight) { tableModel(list: model.results) { - closureColumn(header: trans("SENDER"), preferredWidth: 150, type: Persona, read : {it.sender}) - closureColumn(header: trans("TRUST_STATUS"), preferredWidth: 30, type:String, read : { - trans(model.core.trustService.getLevel(it.sender.destination).name()) + closureColumn(header: trans("SENDER"), preferredWidth: 150, type: PersonaOrProfile, read : {it}) + closureColumn(header: trans("TRUST_STATUS"), preferredWidth: 30, type:String, read : { ResultPOP row -> + trans(model.core.trustService.getLevel(row.getPersona().destination).name()) + }) + closureColumn(header: trans("NAME"), preferredWidth: 650, type: String, read : { ResultPOP row -> + HTMLSanitizer.sanitize(row.getEvent().getFullPath()) + }) + closureColumn(header: trans("COMMENTS"), preferredWidth: 20, type: Boolean, read : { ResultPOP row -> + row.getEvent().comment != null + }) + closureColumn(header: trans("CERTIFICATES"), preferredWidth: 20, type: Integer, read : { ResultPOP row -> + row.getEvent().certificates + }) + closureColumn(header: trans("COLLECTIONS"), preferredWidth: 20, type: Integer, read: { ResultPOP row -> + row.getEvent().collections.size() }) - closureColumn(header: trans("NAME"), preferredWidth: 650, type: String, read : { HTMLSanitizer.sanitize(it.getFullPath())}) - closureColumn(header: trans("COMMENTS"), preferredWidth: 20, type: Boolean, read : {it.comment != null}) - closureColumn(header: trans("CERTIFICATES"), preferredWidth: 20, type: Integer, read : {it.certificates}) - closureColumn(header: trans("COLLECTIONS"), preferredWidth: 20, type: Integer, read: {it.collections.size()}) } } } @@ -168,8 +182,8 @@ class ResultDetailsTabsView { void mvcGroupInit(Map args) { // all senders table - sendersTable.setDefaultRenderer(Persona.class, new PersonaCellRenderer()) - sendersTable.rowSorter.setComparator(0, new PersonaComparator()) + sendersTable.setDefaultRenderer(PersonaOrProfile.class, new PersonaOrProfileCellRenderer()) + sendersTable.rowSorter.setComparator(0, new PersonaOrProfileComparator()) def selectionModel = sendersTable.getSelectionModel() selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) selectionModel.addListSelectionListener({ @@ -180,7 +194,7 @@ class ResultDetailsTabsView { return } row = sendersTable.rowSorter.convertRowIndexToModel(row) - UIResultEvent event = model.results[row] + UIResultEvent event = model.results[row].getEvent() model.copyIdActionEnabled = true model.browseActionEnabled = event.browse @@ -194,7 +208,7 @@ class ResultDetailsTabsView { selectionModel = commentsList.getSelectionModel() selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) selectionModel.addListSelectionListener({ - UIResultEvent event = commentsList.getSelectedValue() + UIResultEvent event = commentsList.getSelectedValue()?.getEvent() if (event != null) commentTextArea.setText(event.comment) }) @@ -213,16 +227,16 @@ class ResultDetailsTabsView { model.results[row].sender } - void addResultToListGroups(UIResultEvent event) { - certificateListGroup?.model?.addResult(event) - collectionListGroup?.model?.addResult(event) + void addResultToListGroups(ResultPOP resultPOP) { + certificateListGroup?.model?.addResult(resultPOP) + collectionListGroup?.model?.addResult(resultPOP) } void refreshAll() { sendersTable.model.fireTableDataChanged() if (!model.resultsWithComments.isEmpty()) { commentsPanel.getLayout().show(commentsPanel,"yes-comments") - commentsList.setListData(model.resultsWithComments.toArray(new UIResultEvent[0])) + commentsList.setListData(model.resultsWithComments.toArray(new ResultPOP[0])) } buildTabs() diff --git a/gui/src/main/groovy/com/muwire/gui/profile/ResultPOP.groovy b/gui/src/main/groovy/com/muwire/gui/profile/ResultPOP.groovy new file mode 100644 index 00000000..6feb613a --- /dev/null +++ b/gui/src/main/groovy/com/muwire/gui/profile/ResultPOP.groovy @@ -0,0 +1,35 @@ +package com.muwire.gui.profile + +import com.muwire.core.Persona +import com.muwire.core.search.UIResultEvent +import com.muwire.gui.HTMLSanitizer + +import javax.swing.Icon + +class ResultPOP implements PersonaOrProfile { + final UIResultEvent event + private Icon thumbNail + ResultPOP(UIResultEvent event) { + this.event = event + } + + @Override + Persona getPersona() { + return event.sender + } + + @Override + Icon getThumbnail() { + if (event.profileHeader == null) + return null + if (thumbNail == null) { + thumbNail = new ThumbnailIcon(event.profileHeader.getThumbNail()) + } + thumbNail + } + + @Override + String getTitle() { + return HTMLSanitizer.sanitize(event.profileHeader?.getTitle()) + } +} diff --git a/gui/src/main/groovy/com/muwire/gui/resultdetails/ResultListCellRenderer.groovy b/gui/src/main/groovy/com/muwire/gui/resultdetails/ResultListCellRenderer.groovy index e70c9e45..57de8624 100644 --- a/gui/src/main/groovy/com/muwire/gui/resultdetails/ResultListCellRenderer.groovy +++ b/gui/src/main/groovy/com/muwire/gui/resultdetails/ResultListCellRenderer.groovy @@ -1,21 +1,33 @@ package com.muwire.gui.resultdetails -import com.muwire.core.search.UIResultEvent import com.muwire.gui.PersonaCellRenderer +import com.muwire.gui.profile.ResultPOP +import static com.muwire.gui.Translator.trans import javax.swing.JLabel import javax.swing.JList import javax.swing.ListCellRenderer import java.awt.Component -class ResultListCellRenderer implements ListCellRenderer{ +class ResultListCellRenderer implements ListCellRenderer{ @Override - Component getListCellRendererComponent(JList list, - UIResultEvent value, int index, + Component getListCellRendererComponent(JList list, + ResultPOP value, int index, boolean isSelected, boolean cellHasFocus) { JLabel rv = new JLabel() - String text = "" + PersonaCellRenderer.htmlize(value.sender) + "" + String text = "" + PersonaCellRenderer.htmlize(value.getEvent().sender) + "" rv.setText(text) + + if (value.getThumbnail() != null) + rv.setIcon(value.getThumbnail()) + else + rv.setIcon(null) + + if (value.getTitle() != null) + rv.setToolTipText(value.getTitle()) + else + rv.setToolTipText(trans("NO_PROFILE")) + if (!isSelected) { rv.setForeground(list.getForeground()) rv.setBackground(list.getSelectionBackground())