Skip to content

Conversation

@Jakubk15
Copy link
Member

No description provided.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Jakubk15, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on significantly improving the user experience within the parcel management system's graphical user interface. By integrating and displaying crucial information such as the contents of a parcel and its delivery status (including estimated arrival times or completion dates), users gain a much clearer and more comprehensive overview of their parcels. This enhancement involves both front-end GUI modifications and back-end service integration, alongside new configuration options for greater customization.

Highlights

  • Enhanced GUI Display: The Collection GUI and Parcel List GUI now display detailed parcel contents and delivery information, including arrival times and item lists.
  • New Configuration Options: Added several new configuration settings in PluginConfig.java to customize the display of parcel arrival lines and item lists within the GUIs.
  • Delivery and Content Integration: Introduced ParcelContentManager and DeliveryManager into the GuiManager to facilitate fetching and displaying parcel-specific data.
  • Parcel Status Refinement: The ParcelStatus enum was updated, renaming IN_PROGRESS to SENT for clearer state representation.
  • Utility Additions: A new DurationUtil class was added for formatting time durations, and InventoryUtil received a private constructor for proper utility class design.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the parcel collection GUI by displaying parcel contents and delivery information. The changes are well-implemented, leveraging asynchronous data fetching to maintain server performance. New configuration options have been added to support these UI enhancements.

My review includes a few suggestions to improve the code's maintainability and correctness. I've pointed out an issue with using the system's default timezone which could lead to inconsistencies, some dead code that should be removed, and a FIXME comment that should be moved to an issue tracker. I've also suggested a small refactoring to improve code clarity.

Comment on lines +122 to +164
private CompletableFuture<GuiItem> createParcelItemAsync(Parcel parcel, ConfigItem item) {
CompletableFuture<List<String>> loreFuture = PlaceholderUtil.replaceParcelPlaceholdersAsync(
parcel, item.lore(), this.guiManager
);
CompletableFuture<Optional<Delivery>> deliveryFuture = this.guiManager.getDelivery(parcel.uuid());

return loreFuture.thenCombine(deliveryFuture, (processedLore, deliveryOptional) -> {
PaperItemBuilder parcelItem = item.toBuilder();

List<String> loreWithArrival = new ArrayList<>(processedLore);

if (deliveryOptional.isPresent()) {
Delivery delivery = deliveryOptional.get();
Instant arrivalTime = delivery.deliveryTimestamp();
Instant now = Instant.now();

if (arrivalTime.isAfter(now)) {
Duration remaining = Duration.between(now, arrivalTime);
String formattedDuration = DurationUtil.format(remaining);
String formattedDate = DATE_FORMATTER.format(arrivalTime.atZone(ZoneId.systemDefault()));

String arrivingLine = this.guiSettings.parcelArrivingLine
.replace("{DURATION}", formattedDuration)
.replace("{DATE}", formattedDate);

loreWithArrival.add(arrivingLine);
} else if (arrivalTime.isBefore(now)) { // not supported rn, because deliveries are deleted on arrival, so the if is always false
String arrivedLine = this.guiSettings.parcelArrivedLine
.replace("{DATE}", DATE_FORMATTER.format(arrivalTime.atZone(ZoneId.systemDefault())));
loreWithArrival.add(arrivedLine);
}
}

List<Component> newLore = loreWithArrival.stream()
.map(line -> resetItalic(this.miniMessage.deserialize(line)))
.toList();

parcelItem.lore(newLore);
parcelItem.name(resetItalic(this.miniMessage.deserialize(item.name().replace("{NAME}", parcel.name()))));

return parcelItem.asGuiItem();
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This method has a couple of issues that should be addressed:

  1. Inconsistent Timezone: The use of ZoneId.systemDefault() on lines 141 and 150 can lead to inconsistent date and time formatting across different server environments. It's better to use a fixed timezone like UTC (ZoneId.of("UTC")) or make it configurable in PluginConfig.java to ensure all players see consistent times.

  2. Dead Code: The else if block on lines 148-152 is commented as unreachable code. This dead code should be removed to avoid confusion for future maintainers. If it's for a future feature, it should be added when that feature is implemented.

Comment on lines +119 to +145
CompletableFuture<List<String>> loreFuture = PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, parcelItem.lore(), this.guiManager);
CompletableFuture<List<ItemStack>> contentFuture = this.guiManager.getParcelContent(parcel.uuid())
.thenApply(optional -> optional.map(content -> content.items()).orElse(List.of()));

return loreFuture.thenCombine(contentFuture, (processedLore, items) -> () -> {
ConfigItem item = parcelItem.clone();
item.name(item.name().replace("{NAME}", parcel.name()));

List<String> loreWithItems = new ArrayList<>(processedLore);
if (!items.isEmpty()) {
loreWithItems.add(this.guiSettings.parcelItemsCollectionGui);
for (ItemStack itemStack : items) {
loreWithItems.add(this.guiSettings.parcelItemCollectionFormat
.replace("{ITEM}", MaterialUtil.format(itemStack.getType()))
.replace("{AMOUNT}", Integer.toString(itemStack.getAmount()))
);
}
}

return PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, parcelItem.lore(), this.guiManager)
.thenApply(processedLore -> () -> {
ConfigItem item = parcelItem.clone();
item.name(item.name().replace("{NAME}", parcel.name()));
item.lore(processedLore);
item.glow(true);
item.lore(loreWithItems);
item.glow(true);

return item.toGuiItem(event -> {
this.guiManager.collectParcel(player, parcel);
refresher.removeItemBySlot(event.getSlot());
});
return item.toGuiItem(event -> {
this.guiManager.collectParcel(player, parcel);
refresher.removeItemBySlot(event.getSlot());
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The createParcelItemAsync method has grown in complexity. To improve readability and maintainability, consider these refactorings:

  1. On line 121, use a method reference for conciseness: optional.map(ParcelContent::items).
  2. Extract the logic for adding item details to the lore (lines 127-136) into a separate private helper method. This will make createParcelItemAsync shorter and more focused.

Here's an example of how you could refactor:

private CompletableFuture<Supplier<GuiItem>> createParcelItemAsync(
    Parcel parcel,
    ConfigItem parcelItem,
    Player player,
    PaginatedGuiRefresher refresher
) {
    CompletableFuture<List<String>> loreFuture = PlaceholderUtil.replaceParcelPlaceholdersAsync(parcel, parcelItem.lore(), this.guiManager);
    CompletableFuture<List<ItemStack>> contentFuture = this.guiManager.getParcelContent(parcel.uuid())
        .thenApply(optional -> optional.map(ParcelContent::items).orElse(List.of()));

    return loreFuture.thenCombine(contentFuture, (processedLore, items) -> () -> {
        ConfigItem item = parcelItem.clone();
        item.name(item.name().replace("{NAME}", parcel.name()));

        List<String> loreWithItems = new ArrayList<>(processedLore);
        addItemsToLore(loreWithItems, items);

        item.lore(loreWithItems);
        item.glow(true);

        return item.toGuiItem(event -> {
            this.guiManager.collectParcel(player, parcel);
            refresher.removeItemBySlot(event.getSlot());
        });
    });
}

private void addItemsToLore(List<String> lore, List<ItemStack> items) {
    if (items.isEmpty()) {
        return;
    }

    lore.add(this.guiSettings.parcelItemsCollectionGui);
    items.forEach(itemStack -> lore.add(this.guiSettings.parcelItemCollectionFormat
        .replace("{ITEM}", MaterialUtil.format(itemStack.getType()))
        .replace("{AMOUNT}", String.valueOf(itemStack.getAmount()))
    ));
}

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the parcel management system by renaming the IN_PROGRESS status to SENT, adding arrival time and item display functionality to GUIs, and introducing a new utility class for duration formatting.

Key changes:

  • Renamed ParcelStatus.IN_PROGRESS to ParcelStatus.SENT for improved clarity
  • Enhanced Collection GUI to display parcel items with formatted material names and quantities
  • Added delivery information display in Parcel List GUI showing arrival time and remaining duration
  • Introduced DurationUtil for consistent duration formatting across the application

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/java/com/eternalcode/parcellockers/parcel/ParcelStatus.java Renamed enum value from IN_PROGRESS to SENT
src/main/java/com/eternalcode/parcellockers/util/DurationUtil.java New utility class for formatting durations with custom pattern
src/main/java/com/eternalcode/parcellockers/util/InventoryUtil.java Added private constructor to prevent instantiation
src/main/java/com/eternalcode/parcellockers/gui/implementation/remote/ParcelListGui.java Enhanced to fetch and display delivery arrival information with formatted dates and durations
src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/CollectionGui.java Enhanced to fetch and display parcel contents with item names and amounts
src/main/java/com/eternalcode/parcellockers/gui/GuiManager.java Added methods to retrieve parcel content and delivery information
src/main/java/com/eternalcode/parcellockers/delivery/DeliveryManager.java Added get method to retrieve deliveries with cache support
src/main/java/com/eternalcode/parcellockers/configuration/implementation/PluginConfig.java Added configuration for arrival/arrived lines and item display format, changed corner item color
src/main/java/com/eternalcode/parcellockers/gui/implementation/locker/SendingGuiState.java Updated default status to SENT
src/test/java/com/eternalcode/parcellockers/database/ParcelRepositoryIntegrationTest.java Updated test to use ParcelStatus.SENT
src/main/java/com/eternalcode/parcellockers/ParcelLockers.java Updated GuiManager constructor call with new dependencies
src/main/java/com/eternalcode/parcellockers/command/debug/DebugCommand.java Added FIXME comment about using Registry API

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +25 to +36
public static String format(Duration duration) {
if (duration.compareTo(ONE_SECOND) < 0) {
return "0s";
}
return reformat(DURATION.format(duration));
}


private static String reformat(String input) {
return REFORMAT_PATTERN.matcher(input).replaceAll(REFORMAT_REPLACEMENT).trim();
}
}
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new DurationUtil class lacks test coverage. Consider adding unit tests to verify the format method behaves correctly for various Duration inputs, including edge cases like zero duration, very short durations (less than 1 second), and durations with multiple time units (days, hours, minutes, seconds).

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +42
public CompletableFuture<Optional<Delivery>> get(UUID parcel) {
Delivery cached = this.deliveryCache.getIfPresent(parcel);
if (cached != null) {
return CompletableFuture.completedFuture(Optional.of(cached));
}
return this.deliveryRepository.fetch(parcel).thenApply(optional -> {
optional.ifPresent(delivery -> this.deliveryCache.put(parcel, delivery));
return optional;
});
}
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new get method in DeliveryManager lacks test coverage. Consider adding tests to verify correct behavior when fetching deliveries from cache versus the repository, and when deliveries are not found.

Copilot uses AI. Check for mistakes.
@Jakubk15 Jakubk15 added the 🆕 feature New feature or request label Dec 21, 2025
@Jakubk15 Jakubk15 merged commit 305711a into master Dec 21, 2025
1 check passed
@Jakubk15 Jakubk15 deleted the add-more-gui-info branch December 21, 2025 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants