Remember profile headers of contacts and transmit them over the network. Update UI relevant components to show avatars

dbus-notify
Zlatin Balevsky 2022-06-03 13:13:32 +01:00
parent 2613e7c7fe
commit ad85a984c2
No known key found for this signature in database
GPG Key ID: A72832072D525E41
13 changed files with 193 additions and 78 deletions

View File

@ -10,6 +10,7 @@ import com.muwire.core.messenger.UIFolderCreateEvent
import com.muwire.core.messenger.UIFolderDeleteEvent
import com.muwire.core.messenger.UIMessageMovedEvent
import com.muwire.core.profile.MWProfile
import com.muwire.core.profile.MWProfileFetchEvent
import com.muwire.core.profile.MWProfileFetcher
import com.muwire.core.profile.MWProfileHeader
import com.muwire.core.profile.UIProfileFetchEvent
@ -316,6 +317,7 @@ public class Core {
File badTrust = new File(home, "distrusted")
trustService = new TrustService(eventBus, goodTrust, badTrust)
eventBus.register(TrustEvent.class, trustService)
eventBus.register(MWProfileFetchEvent.class, trustService)
log.info("initializing content manager")
contentManager = new ContentManager(eventBus, home, props)

View File

@ -530,6 +530,8 @@ class ConnectionAcceptor {
def obj = [:]
obj.persona = it.persona.toBase64()
obj.reason = it.reason
if (it.profileHeader != null)
obj.profileHeader = it.profileHeader.toBase64()
String toJson = JsonOutput.toJson(obj)
byte [] payload = toJson.getBytes(StandardCharsets.US_ASCII)
dos.writeShort(payload.length)
@ -539,6 +541,8 @@ class ConnectionAcceptor {
def obj = [:]
obj.persona = it.persona.toBase64()
obj.reason = it.reason
if (it.profileHeader != null)
obj.profileHeader = it.profileHeader.toBase64()
String toJson = JsonOutput.toJson(obj)
byte [] payload = toJson.getBytes(StandardCharsets.US_ASCII)
dos.writeShort(payload.length)

View File

@ -2,10 +2,12 @@ package com.muwire.core.trust
import com.muwire.core.Event
import com.muwire.core.Persona
import com.muwire.core.profile.MWProfileHeader
class TrustEvent extends Event {
Persona persona
TrustLevel level
String reason
MWProfileHeader profileHeader
}

View File

@ -1,6 +1,8 @@
package com.muwire.core.trust
import com.muwire.core.EventBus
import com.muwire.core.profile.MWProfileFetchEvent
import com.muwire.core.profile.MWProfileHeader
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executor
@ -50,9 +52,8 @@ class TrustService extends Service {
persistGood.eachLine("UTF-8", {
try {
def json = slurper.parseText(it)
byte [] decoded = Base64.decode(json.persona)
Persona persona = new Persona(new ByteArrayInputStream(decoded))
good.put(persona.destination, new TrustEntry(persona, json.reason))
def te = fromJson(json)
good.put(te.persona.destination, te)
} catch (Exception bad) {
log.log(Level.WARNING,"couldn't parse trust entry $it",bad)
}
@ -62,9 +63,8 @@ class TrustService extends Service {
persistBad.eachLine("UTF-8", {
try {
def json = slurper.parseText(it)
byte [] decoded = Base64.decode(json.persona)
Persona persona = new Persona(new ByteArrayInputStream(decoded))
bad.put(persona.destination, new TrustEntry(persona, json.reason))
def te = fromJson(json)
bad.put(te.persona.destination, te)
} catch (Exception bad) {
log.log(Level.WARNING,"couldn't parse trust entry $it",bad)
}
@ -73,6 +73,17 @@ class TrustService extends Service {
loaded = true
eventBus.publish(new TrustServiceLoadedEvent())
}
private static TrustEntry fromJson(def json) {
byte [] decoded = Base64.decode(json.persona)
Persona persona = new Persona(new ByteArrayInputStream(decoded))
MWProfileHeader profileHeader = null
if (json.profileHeader != null) {
decoded = Base64.decode(json.profileHeader)
profileHeader = new MWProfileHeader(new ByteArrayInputStream(decoded))
}
new TrustEntry(persona, (String)json.reason, profileHeader)
}
private void persist() {
persistGood.delete()
@ -81,6 +92,8 @@ class TrustService extends Service {
def json = [:]
json.persona = v.persona.toBase64()
json.reason = v.reason
if (v.profileHeader != null)
json.profileHeader = v.profileHeader.toBase64()
writer.println JsonOutput.toJson(json)
}
})
@ -90,6 +103,8 @@ class TrustService extends Service {
def json = [:]
json.persona = v.persona.toBase64()
json.reason = v.reason
if (v.profileHeader != null)
json.profileHeader = v.profileHeader.toBase64()
writer.println JsonOutput.toJson(json)
}
})
@ -102,16 +117,23 @@ class TrustService extends Service {
return TrustLevel.DISTRUSTED
TrustLevel.NEUTRAL
}
MWProfileHeader getProfileHeader(Persona persona) {
def rv = good[persona.destination]?.getProfileHeader()
if (rv == null)
rv = bad[persona.destination]?.getProfileHeader()
rv
}
void onTrustEvent(TrustEvent e) {
switch(e.level) {
case TrustLevel.TRUSTED:
bad.remove(e.persona.destination)
good.put(e.persona.destination, new TrustEntry(e.persona, e.reason))
good.put(e.persona.destination, new TrustEntry(e.persona, e.reason, e.profileHeader))
break
case TrustLevel.DISTRUSTED:
good.remove(e.persona.destination)
bad.put(e.persona.destination, new TrustEntry(e.persona, e.reason))
bad.put(e.persona.destination, new TrustEntry(e.persona, e.reason, e.profileHeader))
break
case TrustLevel.NEUTRAL:
good.remove(e.persona.destination)
@ -121,12 +143,25 @@ class TrustService extends Service {
diskIO.submit({persist()} as Runnable)
}
void onMWProfileFetchEvent(MWProfileFetchEvent event) {
def dest = event.profile.getHeader().getPersona().getDestination()
TrustEntry te = good[dest]
if (te == null)
te = bad[dest]
if (te == null)
return
te.profileHeader = event.profile.getHeader()
diskIO.submit({persist()} as Runnable)
}
public static class TrustEntry {
final Persona persona
final String reason
TrustEntry(Persona persona, String reason) {
volatile MWProfileHeader profileHeader
TrustEntry(Persona persona, String reason, MWProfileHeader profileHeader) {
this.persona = persona
this.reason = reason
this.profileHeader = profileHeader
}
public int hashCode() {

View File

@ -1,5 +1,7 @@
package com.muwire.core.trust
import com.muwire.core.profile.MWProfileHeader
import java.nio.charset.StandardCharsets
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ExecutorService
@ -144,34 +146,24 @@ class TrustSubscriber {
JsonSlurper slurper = new JsonSlurper()
for (int i = 0; i < countGood; i++) {
int length = dis.readUnsignedShort()
byte []payload = new byte[length]
dis.readFully(payload)
def json = slurper.parse(payload)
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(json.persona)))
good.add(new TrustEntry(persona, json.reason))
good.add(fromDIS(slurper, dis))
}
for (int i = 0; i < countBad; i++) {
int length = dis.readUnsignedShort()
byte []payload = new byte[length]
dis.readFully(payload)
def json = slurper.parse(payload)
Persona persona = new Persona(new ByteArrayInputStream(Base64.decode(json.persona)))
bad.add(new TrustEntry(persona, json.reason))
bad.add(fromDIS(slurper, dis))
}
} else {
int nGood = dis.readUnsignedShort()
for (int i = 0; i < nGood; i++) {
Persona p = new Persona(dis)
good.add(new TrustEntry(p,null))
good.add(new TrustEntry(p,null,null))
}
int nBad = dis.readUnsignedShort()
for (int i = 0; i < nBad; i++) {
Persona p = new Persona(dis)
bad.add(new TrustEntry(p, null))
bad.add(new TrustEntry(p, null, null))
}
}
@ -190,4 +182,21 @@ class TrustSubscriber {
}
}
private static TrustEntry fromDIS(JsonSlurper slurper, DataInputStream dis) {
int length = dis.readUnsignedShort()
byte [] payload = new byte[length]
dis.readFully(payload)
def json = slurper.parse(payload)
byte [] decoded = Base64.decode(json.persona)
Persona persona = new Persona(new ByteArrayInputStream(decoded))
MWProfileHeader profileHeader = null
if (json.profileHeader != null) {
decoded = Base64.decode(json.profileHeader)
profileHeader = new MWProfileHeader(new ByteArrayInputStream(decoded))
if (persona != profileHeader.getPersona())
throw new IOException("persona and profile mismatch")
}
new TrustEntry(persona, (String)json.reason, profileHeader)
}
}

View File

@ -425,7 +425,7 @@ class MainFrameController {
return
core.muOptions.trustSubscriptions.remove(list.persona)
saveMuWireSettings()
model.subscriptions.remove(list)
model.subscriptions.remove(model.buildSubPOP(list))
JTable table = builder.getVariable("subscription-table")
table.model.fireTableDataChanged()
core.eventBus.publish(new TrustSubscriptionEvent(persona : list.persona, subscribe : false))
@ -435,7 +435,7 @@ class MainFrameController {
int row = view.getSelectedContactSubscriptionTableRow()
if (row < 0)
return null
model.subscriptions[row]
model.subscriptions[row].getTrustList()
}
@ControllerAction
@ -931,7 +931,7 @@ class MainFrameController {
int row = view.getSelectedContactsTableRow()
if (row < 0)
return
TrustEntry te = model.contacts[row]
Persona persona = model.contacts[row].getPersona()
def params = [:]
params.recipients = new HashSet<>(Collections.singletonList(te.persona))
@ -949,8 +949,8 @@ class MainFrameController {
int row = view.getSelectedContactsTableRow()
if (row < 0)
return
TrustEntry te = model.contacts.get(row)
CopyPasteSupport.copyToClipboard(te.persona.toBase64())
Persona persona = model.contacts.get(row).getPersona()
CopyPasteSupport.copyToClipboard(persona.toBase64())
}
@ControllerAction

View File

@ -1,5 +1,6 @@
package com.muwire.gui
import com.muwire.gui.profile.TrustPOP
import griffon.core.artifact.GriffonController
import griffon.core.controller.ControllerAction
import griffon.inject.MVCMember
@ -27,8 +28,9 @@ class TrustListController {
if (selectedRow < 0)
return
String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.trusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason))
TrustPOP tp = model.trusted[selectedRow]
eventBus.publish(new TrustEvent(persona : tp.getPersona(), level : TrustLevel.TRUSTED,
reason : reason, profileHeader: tp.getHeader()))
view.fireUpdate("trusted-table")
}
@ -38,8 +40,9 @@ class TrustListController {
if (selectedRow < 0)
return
String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.distrusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.TRUSTED, reason : reason))
TrustPOP tp = model.distrusted[selectedRow]
eventBus.publish(new TrustEvent(persona : tp.getPersona(), level : TrustLevel.TRUSTED,
reason : reason, profileHeader: tp.getHeader()))
view.fireUpdate("distrusted-table")
}
@ -49,8 +52,9 @@ class TrustListController {
if (selectedRow < 0)
return
String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.trusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason))
TrustPOP tp = model.trusted[selectedRow]
eventBus.publish(new TrustEvent(persona : tp.getPersona(), level : TrustLevel.DISTRUSTED,
reason : reason, profileHeader: tp.getHeader()))
view.fireUpdate("trusted-table")
}
@ -60,8 +64,9 @@ class TrustListController {
if (selectedRow < 0)
return
String reason = JOptionPane.showInputDialog("Enter reason (optional)")
Persona p = model.distrusted[selectedRow].persona
eventBus.publish(new TrustEvent(persona : p, level : TrustLevel.DISTRUSTED, reason : reason))
TrustPOP tp = model.distrusted[selectedRow]
eventBus.publish(new TrustEvent(persona : tp.getPersona(), level : TrustLevel.DISTRUSTED,
reason : reason, profileHeader: tp.getHeader()))
view.fireUpdate("distrusted-table")
}
}

View File

@ -28,13 +28,15 @@ class ViewProfileController {
@ControllerAction
void addContact() {
String reason = JOptionPane.showInputDialog(trans("ENTER_REASON_OPTIONAL"))
model.core.eventBus.publish(new TrustEvent(persona: model.persona, level: TrustLevel.TRUSTED, reason: reason))
model.core.eventBus.publish(new TrustEvent(persona: model.persona, level: TrustLevel.TRUSTED,
reason: reason, profileHeader: model.profile?.getHeader()))
}
@ControllerAction
void block() {
String reason = JOptionPane.showInputDialog(trans("ENTER_REASON_OPTIONAL"))
model.core.eventBus.publish(new TrustEvent(persona: model.persona, level: TrustLevel.DISTRUSTED, reason: reason))
model.core.eventBus.publish(new TrustEvent(persona: model.persona, level: TrustLevel.DISTRUSTED,
reason: reason, profileHeader: model.profile?.getHeader()))
}
@ControllerAction

View File

@ -5,9 +5,11 @@ import com.muwire.core.download.DownloadHopelessEvent
import com.muwire.core.messenger.MessageFolderLoadingEvent
import com.muwire.core.profile.MWProfileHeader
import com.muwire.core.search.ResultsEvent
import com.muwire.core.trust.RemoteTrustList
import com.muwire.core.trust.TrustServiceLoadedEvent
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.ThumbnailIcon
import com.muwire.gui.profile.TrustPOP
import javax.swing.DefaultListModel
import javax.swing.Icon
@ -134,8 +136,8 @@ class MainFrameModel {
def connectionList = []
def searches = new LinkedList()
def contacts = []
def subscriptions = []
List<TrustPOP> contacts = []
List<SubscriptionPOP> subscriptions = []
def feeds = []
def feedItems = []
@ -366,8 +368,8 @@ class MainFrameModel {
}, 1000, 1000)
runInsideUIAsync {
contacts.addAll(core.trustService.good.values())
contacts.addAll(core.trustService.bad.values())
contacts.addAll(core.trustService.good.values().collect {new TrustPOP(it)})
contacts.addAll(core.trustService.bad.values().collect {new TrustPOP(it)})
resumeButtonText = "RETRY"
@ -706,16 +708,17 @@ class MainFrameModel {
private void refreshContacts() {
contacts.clear()
contacts.addAll(core.trustService.good.values())
contacts.addAll(core.trustService.bad.values())
contacts.addAll(core.trustService.good.values().collect{new TrustPOP(it)})
contacts.addAll(core.trustService.bad.values().collect{new TrustPOP(it)})
updateTablePreservingSelection("contacts-table")
}
void onTrustSubscriptionUpdatedEvent(TrustSubscriptionUpdatedEvent e) {
runInsideUIAsync {
if (!subscriptions.contains(e.trustList))
subscriptions << e.trustList
def subPOP = new SubscriptionPOP(e.trustList)
if (!subscriptions.contains(subPOP))
subscriptions << subPOP
updateTablePreservingSelection("subscription-table")
}
}
@ -1128,4 +1131,44 @@ class MainFrameModel {
view.refreshSharedFiles()
}
}
SubscriptionPOP buildSubPOP(RemoteTrustList list) {
new SubscriptionPOP(list)
}
class SubscriptionPOP implements PersonaOrProfile {
final RemoteTrustList trustList
Icon icon
SubscriptionPOP(RemoteTrustList trustList) {
this.trustList = trustList
}
@Override
Persona getPersona() {
trustList.getPersona()
}
@Override
Icon getThumbnail() {
MWProfileHeader header = core.trustService.getProfileHeader(getPersona())
if (header == null)
return null
if (icon == null)
icon = new ThumbnailIcon(header.getThumbNail())
return icon
}
@Override
String getTitle() {
String title = core.trustService.getProfileHeader(getPersona())?.getTitle()
return HTMLSanitizer.sanitize(title)
}
public boolean equals(Object o) {
if (!(o instanceof SubscriptionPOP))
return false
SubscriptionPOP other = (SubscriptionPOP)o
return trustList == other.trustList
}
}
}

View File

@ -2,7 +2,7 @@ package com.muwire.gui
import com.muwire.core.trust.RemoteTrustList
import com.muwire.core.trust.TrustService
import com.muwire.gui.profile.TrustPOP
import griffon.core.artifact.GriffonModel
import griffon.transform.Observable
import griffon.metadata.ArtifactProviderFor
@ -12,11 +12,11 @@ class TrustListModel {
RemoteTrustList trustList
TrustService trustService
def trusted
def distrusted
List<TrustPOP> trusted
List<TrustPOP> distrusted
void mvcGroupInit(Map<String,String> args) {
trusted = new ArrayList<>(trustList.good)
distrusted = new ArrayList<>(trustList.bad)
trusted = trustList.good.collect {new TrustPOP(it)}
distrusted = trustList.bad.collect {new TrustPOP(it)}
}
}

View File

@ -2,6 +2,7 @@ package com.muwire.gui.profile
import com.muwire.core.Core
import com.muwire.core.Persona
import com.muwire.core.profile.MWProfile
import com.muwire.core.profile.MWProfileFetchEvent
import com.muwire.core.profile.MWProfileFetchStatus
import com.muwire.core.profile.MWProfileHeader
@ -24,6 +25,7 @@ class ViewProfileModel {
String profileTitle
@Observable MWProfileFetchStatus status
MWProfile profile
private boolean registered
@ -48,8 +50,10 @@ class ViewProfileModel {
return
runInsideUIAsync {
status = event.status
if (status == MWProfileFetchStatus.FINISHED)
if (status == MWProfileFetchStatus.FINISHED) {
view.profileFetched(event.profile)
profile = event.profile
}
}
}
}

View File

@ -652,10 +652,10 @@ class MainFrameView {
table(id: "contacts-table", autoCreateRowSorter: true, rowHeight: rowHeight,
dragEnabled: true, transferHandler: new PersonaTransferHandler()) {
tableModel(list: model.contacts) {
closureColumn(header: trans("CONTACTS"), preferredWidth: 250, type: Persona, read: { it.persona })
closureColumn(header: trans("REASON"), preferredWidth: 450, type: String, read: { it.reason })
closureColumn(header: trans("TRUST_STATUS"), preferredWidth: 60, type: String, read: { row ->
trans(model.core.trustService.getLevel(row.persona.destination).name())
closureColumn(header: trans("CONTACTS"), preferredWidth: 250, type: PersonaOrProfile, read: { it })
closureColumn(header: trans("REASON"), preferredWidth: 450, type: String, read: { it.getReason() })
closureColumn(header: trans("TRUST_STATUS"), preferredWidth: 60, type: String, read: { PersonaOrProfile row ->
trans(model.core.trustService.getLevel(row.getPersona().destination).name())
})
}
}
@ -692,11 +692,11 @@ class MainFrameView {
scrollPane(constraints : BorderLayout.CENTER) {
table(id : "subscription-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.subscriptions) {
closureColumn(header : trans("NAME"), preferredWidth: 200, type: Persona, read : {it.persona})
closureColumn(header : trans("TRUSTED"), preferredWidth : 20, type: Integer, read : {it.good.size()})
closureColumn(header : trans("DISTRUSTED"), preferredWidth: 20, type: Integer, read : {it.bad.size()})
closureColumn(header : trans("STATUS"), preferredWidth: 30, type: String, read : {trans(it.status.name())})
closureColumn(header : trans("LAST_UPDATED"), preferredWidth: 200, type : Long, read : { it.timestamp })
closureColumn(header : trans("NAME"), preferredWidth: 200, type: PersonaOrProfile, read : {it})
closureColumn(header : trans("TRUSTED"), preferredWidth : 20, type: Integer, read : {it.trustList.good.size()})
closureColumn(header : trans("DISTRUSTED"), preferredWidth: 20, type: Integer, read : {it.trustList.bad.size()})
closureColumn(header : trans("STATUS"), preferredWidth: 30, type: String, read : {trans(it.trustList.status.name())})
closureColumn(header : trans("LAST_UPDATED"), preferredWidth: 200, type : Long, read : { it.trustList.timestamp })
}
}
}
@ -1287,10 +1287,10 @@ class MainFrameView {
// subscription table
JTable subscriptionTable = builder.getVariable("subscription-table")
subscriptionTable.setDefaultRenderer(Integer.class, centerRenderer)
subscriptionTable.setDefaultRenderer(Persona.class, personaRenderer)
subscriptionTable.setDefaultRenderer(PersonaOrProfile.class, popRenderer)
subscriptionTable.rowSorter.addRowSorterListener({ evt -> lastContactsSubscriptionSortEvent = evt })
subscriptionTable.rowSorter.setSortsOnUpdates(true)
subscriptionTable.rowSorter.setComparator(0, personaComparator)
subscriptionTable.rowSorter.setComparator(0, popComparator)
selectionModel = subscriptionTable.getSelectionModel()
selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
selectionModel.addListSelectionListener({
@ -1301,7 +1301,7 @@ class MainFrameView {
model.unsubscribeButtonEnabled = false
return
}
def trustList = model.subscriptions[selectedRow]
def trustList = model.subscriptions[selectedRow]?.getTrustList()
if (trustList == null)
return
switch (trustList.status) {
@ -1324,8 +1324,8 @@ class MainFrameView {
// contacts table
JTable contactsTable = builder.getVariable("contacts-table")
contactsTable.setDefaultRenderer(Persona.class, personaRenderer)
contactsTable.rowSorter.setComparator(0, personaComparator)
contactsTable.setDefaultRenderer(PersonaOrProfile.class, popRenderer)
contactsTable.rowSorter.setComparator(0, popComparator)
contactsTable.rowSorter.addRowSorterListener({ evt -> lastContactsSortEvent = evt })
contactsTable.rowSorter.setSortsOnUpdates(true)
selectionModel = contactsTable.getSelectionModel()

View File

@ -1,6 +1,9 @@
package com.muwire.gui
import com.muwire.core.Persona
import com.muwire.gui.profile.PersonaOrProfile
import com.muwire.gui.profile.PersonaOrProfileCellRenderer
import com.muwire.gui.profile.PersonaOrProfileComparator
import griffon.core.artifact.GriffonView
import griffon.inject.MVCMember
import griffon.metadata.ArtifactProviderFor
@ -53,9 +56,12 @@ class TrustListView {
scrollPane (constraints : BorderLayout.CENTER){
table(id : "trusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.trusted) {
closureColumn(header: trans("TRUSTED_USERS"), type : Persona, read : {it.persona})
closureColumn(header: trans("REASON"), type : String, read : {HTMLSanitizer.sanitize(it.reason)})
closureColumn(header: trans("YOUR_TRUST"), type : String, read : {trans(model.trustService.getLevel(it.persona.destination).name())})
closureColumn(header: trans("TRUSTED_USERS"), type : PersonaOrProfile, read : {it})
closureColumn(header: trans("REASON"), type : String, read : {it.reason})
closureColumn(header: trans("YOUR_TRUST"), type : String, read : {
Persona p = it.persona
trans(model.trustService.getLevel(p.destination).name())
})
}
}
}
@ -70,9 +76,12 @@ class TrustListView {
scrollPane (constraints : BorderLayout.CENTER ){
table(id : "distrusted-table", autoCreateRowSorter : true, rowHeight : rowHeight) {
tableModel(list : model.distrusted) {
closureColumn(header: trans("DISTRUSTED_USERS"), type : Persona, read : {it.persona})
closureColumn(header: trans("REASON"), type:String, read : {HTMLSanitizer.sanitize(it.reason)})
closureColumn(header: trans("YOUR_TRUST"), type : String, read : {trans(model.trustService.getLevel(it.persona.destination).name())})
closureColumn(header: trans("DISTRUSTED_USERS"), type : PersonaOrProfile, read : {it})
closureColumn(header: trans("REASON"), type:String, read : {it.reason})
closureColumn(header: trans("YOUR_TRUST"), type : String, read : {
Persona p = it.persona
trans(model.trustService.getLevel(p.destination).name())
})
}
}
}
@ -88,19 +97,19 @@ class TrustListView {
void mvcGroupInit(Map<String,String> args) {
def personaRenderer = new PersonaCellRenderer()
def personaComparator = new PersonaComparator()
def popRenderer = new PersonaOrProfileCellRenderer()
def popComparator = new PersonaOrProfileComparator()
JTable trustedTable = builder.getVariable("trusted-table")
trustedTable.setDefaultRenderer(Persona.class, personaRenderer)
trustedTable.rowSorter.setComparator(0, personaComparator)
trustedTable.setDefaultRenderer(PersonaOrProfile.class, popRenderer)
trustedTable.rowSorter.setComparator(0, popComparator)
trustedTable.rowSorter.addRowSorterListener({evt -> sortEvents["trusted-table"] = evt})
trustedTable.rowSorter.setSortsOnUpdates(true)
trustedTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
JTable distrustedTable = builder.getVariable("distrusted-table")
distrustedTable.setDefaultRenderer(Persona.class, personaRenderer)
distrustedTable.rowSorter.setComparator(0, personaComparator)
distrustedTable.setDefaultRenderer(Persona.class, popRenderer)
distrustedTable.rowSorter.setComparator(0, popComparator)
distrustedTable.rowSorter.addRowSorterListener({evt -> sortEvents["distrusted-table"] = evt})
distrustedTable.rowSorter.setSortsOnUpdates(true)
distrustedTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION)