Skip to content

Commit

Permalink
Guild users table (#32)
Browse files Browse the repository at this point in the history
Frontend pagination models
Paginate guild users endpoint
Cache discord guild members
  • Loading branch information
Alf-Melmac committed Mar 5, 2023
1 parent 8434388 commit f139d7c
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.StreamSupport;

/**
* @author Alf
* @since 18.01.2023
Expand All @@ -22,18 +19,12 @@
public class UserInGuildAssembler {
private final DiscordBotService discordBotService;

private UserInGuildDto toDto(@NonNull User user, @NonNull Guild guild) {
public UserInGuildDto toDto(@NonNull User user, @NonNull Guild guild) {
final DiscordGuildMember member = discordBotService.getGuildMember(user.getId(), guild.getId());
if (member == null) return null;

return UserInGuildDto.builder()
.user(DiscordUserAssembler.toDto(member))
.build();
}

public List<UserInGuildDto> toDtoList(@NonNull Iterable<? extends User> users, @NonNull Guild guild) {
return StreamSupport.stream(users.spliterator(), false)
.map(user -> this.toDto(user, guild))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import de.webalf.slotbot.model.dtos.website.GuildDetailsDto;
import de.webalf.slotbot.model.dtos.website.UserInGuildDto;
import de.webalf.slotbot.model.dtos.website.guild.GuildConfigDto;
import de.webalf.slotbot.model.dtos.website.pagination.FrontendPageable;
import de.webalf.slotbot.service.GuildService;
import de.webalf.slotbot.service.GuildUsersService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -55,9 +57,10 @@ public GuildConfigDto putGuildConfig(@PathVariable(value = "id") long guildId, @
}

@GetMapping("/{id}/users")
public List<UserInGuildDto> getGuildUsers(@PathVariable(value = "id") long guildId) {
public FrontendPageable<UserInGuildDto> getGuildUsers(@PathVariable(value = "id") long guildId, Pageable pageRequest) {
final Guild guild = guildService.findByDiscordGuild(guildId);
return userInGuildAssembler.toDtoList(guildUsersService.getUsers(guild), guild);
return FrontendPageable.of(guildUsersService.getUsers(guild, pageRequest)
.map(user -> userInGuildAssembler.toDto(user, guild)));
}

@DeleteMapping("/{id}/users/{userId}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package de.webalf.slotbot.model.dtos.website.pagination;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import org.springframework.data.domain.Page;

/**
* Page metadata used by the frontend. Replacement for {@link org.springframework.hateoas.PagedModel.PageMetadata}
*
* @author Alf
* @since 28.02.2023
*/
@Value
@Builder(access = AccessLevel.PRIVATE)
public class FrontendPage {
/**
* Size of the payload
*/
int size;

/**
* Total count of elements
*/
long totalElements;

/**
* Count of available pages
*/
int totalPages;

/**
* Current page number
*/
int number;

/**
* Creates a {@link FrontendPage} object by the given page
*/
static FrontendPage of(@NonNull Page<?> page) {
return FrontendPage.builder()
.size(page.getSize())
.totalElements(page.getTotalElements())
.totalPages(page.getTotalPages())
.number(page.getNumber())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package de.webalf.slotbot.model.dtos.website.pagination;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.NonNull;
import lombok.Value;
import org.springframework.data.domain.Page;

import java.util.List;

/**
* This model provides the expected paginated format for the frontend and is a replacement for {@link org.springframework.hateoas.PagedModel}
*
* @param <T> type of the content, usually DTOs
* @author Alf
* @since 28.02.2023
*/
@Builder(access = AccessLevel.PRIVATE)
@Value
public class FrontendPageable<T> {
/**
* Info about this page
*/
FrontendPage page;
/**
* Actual page content
*/
List<T> content;

/**
* Creates a {@link FrontendPageable} object by the given page
*/
public static <T> FrontendPageable<T> of(@NonNull Page<T> page) {
final List<T> content = page.getContent();
return FrontendPageable.<T>builder()
.content(content)
.page(FrontendPage.of(page))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import de.webalf.slotbot.model.Guild;
import de.webalf.slotbot.model.GuildUsers;
import de.webalf.slotbot.model.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

/**
Expand All @@ -14,7 +15,7 @@
*/
@Repository
public interface GuildUsersRepository extends SuperIdEntityJpaRepository<GuildUsers> {
List<GuildUsers> findByGuild(Guild guild);
Page<GuildUsers> findByGuild(Guild guild, Pageable pageable);

Optional<GuildUsers> findByGuildAndUser(Guild guild, User user);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import de.webalf.slotbot.repository.GuildUsersRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* @author Alf
* @since 18.01.2023
Expand All @@ -23,8 +23,8 @@ public class GuildUsersService {
private final UserService userService;
private final GuildService guildService;

public List<User> getUsers(Guild guild) {
return guildUsersRepository.findByGuild(guild).stream().map(GuildUsers::getUser).toList();
public Page<User> getUsers(Guild guild, Pageable pageable) {
return guildUsersRepository.findByGuild(guild, pageable).map(GuildUsers::getUser);
}

public GuildUsers add(long guildId, long userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.requests.ErrorResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
Expand All @@ -35,6 +36,7 @@ public class DiscordBotService {
* @return the member or null if not resolvable
* @see DiscordApiService#getGuildMemberWithUser(String, long)
*/
@Cacheable("botGuildMember")
public DiscordGuildMember getGuildMember(long userId, long guildId) {
final JDA jda = botService.getJda();
if (jda == null) {
Expand Down

0 comments on commit f139d7c

Please sign in to comment.