Skip to content

Commit

Permalink
Improve contact view
Browse files Browse the repository at this point in the history
Add contacts list and searching.
  • Loading branch information
zapek committed Sep 29, 2024
1 parent c9f188f commit df87d53
Show file tree
Hide file tree
Showing 11 changed files with 436 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.api.controller.contact;

import io.swagger.v3.oas.annotations.ExternalDocumentation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.xeres.app.service.ContactService;
import io.xeres.common.rest.contact.Contact;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static io.xeres.common.rest.PathConfig.CONTACT_PATH;

@Tag(name = "Contact", description = "Contact service", externalDocs = @ExternalDocumentation(url = "https://xeres.io/docs/api/contact", description = "Contact documentation"))
@RestController
@RequestMapping(value = CONTACT_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
public class ContactController
{
private final ContactService contactService;

public ContactController(ContactService contactService)
{
this.contactService = contactService;
}

@GetMapping("")
@Operation(summary = "Get all the contacts")
@ApiResponse(responseCode = "200", description = "Request successful")
public List<Contact> getContacts()
{
return contactService.getContacts();
}
}
56 changes: 56 additions & 0 deletions app/src/main/java/io/xeres/app/service/ContactService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.service;

import io.xeres.app.xrs.service.identity.IdentityRsService;
import io.xeres.common.rest.contact.Contact;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class ContactService
{
private final ProfileService profileService;
private final LocationService locationService;
private final IdentityRsService identityRsService;

public ContactService(ProfileService profileService, LocationService locationService, IdentityRsService identityRsService)
{
this.profileService = profileService;
this.locationService = locationService;
this.identityRsService = identityRsService;
}

@Transactional(readOnly = true)
public List<Contact> getContacts()
{
var profiles = profileService.getAllProfiles();
var identities = identityRsService.getAll();

// XXX: for now return all of them, in the future it would be possible to merge the identity to the profile (if the name is the same)
List<Contact> contacts = new ArrayList<>(profiles.size() + identities.size());
profiles.forEach(profile -> contacts.add(new Contact(profile.getName(), profile.getId(), 0L)));
identities.forEach(identity -> contacts.add(new Contact(identity.getName(), 0L, identity.getId()))); // XXX: put the profile too
return contacts;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
import static io.xeres.app.xrs.serialization.Serializer.*;

@Entity(name = "identity_group")
public class IdentityGroupItem extends GxsGroupItem // XXX: beware because we need to be able to serialize just the group data (here) and the group metadata (superclass)
public class IdentityGroupItem extends GxsGroupItem
{
@Transient
public static final IdentityGroupItem EMPTY = new IdentityGroupItem();

@Embedded
@AttributeOverride(name = "identifier", column = @Column(name = "profile_hash"))
private Sha1Sum profileHash; // hash of the gxsId + public key
private byte[] profileSignature; // XXX: warning, RS puts this in a string! we might have to do some serialization trickery... see p3idservice.cc in service_createGroup(), but I think my system's flexibility makes up for it
private byte[] profileSignature;

@Transient
private List<String> recognitionTags = new ArrayList<>(); // not used (but serialized)
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/resources/application-dev.properties
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ springdoc.swagger-ui.tags-sorter=alpha
## Actuator
info.java.vm.vendor=${java.vm.vendor}
info.java.version=${java.version}
management.endpoints.jmx.exposure.exclude=*
management.endpoint.shutdown.enabled=true
management.endpoints.web.exposure.include=info,health,env,logfile,shutdown
management.endpoints.web.exposure.include=*
management.endpoints.web.base-path=/api/v1/actuator
management.info.java.enabled=true
management.info.os.enabled=true
Expand Down
1 change: 1 addition & 0 deletions common/src/main/java/io/xeres/common/rest/PathConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ private PathConfig()
public static final String SHARES_PATH = "/api/v1/shares";
public static final String FILES_PATH = "/api/v1/files";
public static final String STATISTICS_PATH = "/api/v1/statistics";
public static final String CONTACT_PATH = "/api/v1/contacts";
}
24 changes: 24 additions & 0 deletions common/src/main/java/io/xeres/common/rest/contact/Contact.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.common.rest.contact;

public record Contact(String name, long profileId, long identityId)
{
}
59 changes: 59 additions & 0 deletions ui/src/main/java/io/xeres/ui/client/ContactClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.ui.client;

import io.xeres.common.events.StartupEvent;
import io.xeres.common.rest.contact.Contact;
import io.xeres.common.util.RemoteUtils;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;

import static io.xeres.common.rest.PathConfig.CONTACT_PATH;

@Component
public class ContactClient
{
private final WebClient.Builder webClientBuilder;

private WebClient webClient;

public ContactClient(WebClient.Builder webClientBuilder)
{
this.webClientBuilder = webClientBuilder;
}

@EventListener
public void init(@SuppressWarnings("unused") StartupEvent event)
{
webClient = webClientBuilder
.baseUrl(RemoteUtils.getControlUrl() + CONTACT_PATH)
.build();
}

public Flux<Contact> getContacts()
{
return webClient.get()
.uri("")
.retrieve()
.bodyToFlux(Contact.class);
}
}
59 changes: 59 additions & 0 deletions ui/src/main/java/io/xeres/ui/controller/contact/ContactCell.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.ui.controller.contact;

import io.xeres.common.rest.contact.Contact;
import io.xeres.ui.client.GeneralClient;
import io.xeres.ui.custom.AsyncImageView;
import javafx.scene.control.TableCell;
import javafx.scene.image.ImageView;

import static io.xeres.common.rest.PathConfig.IDENTITIES_PATH;

public class ContactCell extends TableCell<Contact, Contact>
{
private final GeneralClient generalClient;

public ContactCell(GeneralClient generalClient)
{
super();
this.generalClient = generalClient;
}

@Override
protected void updateItem(Contact item, boolean empty)
{
super.updateItem(item, empty);
setText(empty ? null : item.name());
setGraphic(empty ? null : updateContactImage((AsyncImageView) getGraphic(), item));
}

private ImageView updateContactImage(AsyncImageView imageView, Contact contact)
{
if (imageView == null)
{
imageView = new AsyncImageView();
imageView.setFitWidth(32);
imageView.setFitHeight(32);
}
imageView.setUrl(contact.identityId() != 0 ? (IDENTITIES_PATH + "/" + contact.identityId() + "/image") : null, url -> generalClient.getImage(url).block());
return imageView;
}
}
Loading

0 comments on commit df87d53

Please sign in to comment.