Lamp icon indicating copy to clipboard operation
Lamp copied to clipboard

[Feature] Custom message types in Locale/Translator

Open bivashy opened this issue 1 year ago • 2 comments

Pull Request Etiquette

  • [x] I have checked the PRs for upcoming features/bug fixes.

Changes

  • [X] Internal code
  • [X] API (affecting end-user code)
  • [ ] Other: _

Closes Issue: #75

Description

This pull request makes possible to create custom locale reader types that can send adventure component, discord embed messages, and etc.

Breaking changes:

I believe that this Pull Request doesn't have any breaking changes. Please let me know if you have found one.

How to use:

Simply implement DynamicLocaleReader instead of LocaleReader, and register using Translator#add. childrenList Example: ComponentLocaleReader:

public final class ComponentLocaleReader implements DynamicLocaleReader<Component> {

    private static final String ANSI_RED = "\u001B[31m";
    private static final String ANSI_GREEN = "\u001B[32m";
    private final Map<String, Component> components;

    public ComponentLocaleReader(Map<String, Component> components) {
        this.components = components;
    }

    @Override
    public boolean containsKey(String s) {
        return components.containsKey(s);
    }

    @Override
    public Component get(String s) {
        return components.get(s);
    }

    @Override
    public Locale getLocale() {
        return Locale.ENGLISH;
    }

    @Override
    public void reply(CommandActor actor, Component message) {
        // We could cast CommandActor instead, but this is only for example.
        actor.reply(ANSI_GREEN + message.raw());
    }

    @Override
    public void error(CommandActor actor, Component message) {
        // We could cast CommandActor instead, but this is only for example.
        actor.error(ANSI_RED + message.raw());
    }

    @Override
    public Component format(Component component, Object... objects) {
        for (int i = 0; i < objects.length; i += 2)
            component.replace(objects[i].toString(), objects[i + 1].toString());
        return component;
    }

}

Component:

public final class Component {

    private String component;

    public Component(String component) {
        this.component = component;
    }

    public void replace(String pattern, String replacement) {
        component = component.replace(pattern, replacement);
    }

    public String raw() {
        return component;
    }

}

Current state

Currently this Pull Request was tested using ConsoleCommandHandler.

bivashy avatar Nov 23 '23 20:11 bivashy

Hello there! Any update on this? If you have reviewed this PR, make sure that your comments doesn't have PENDING state (I cannot see them) (Related link)

bivashy avatar Jan 17 '24 05:01 bivashy

I apologize for not replying earlier. I've seen this, however, I haven't settled on a satisfying design yet. I'm looking for something that ticks these boxes:

  • [ ] Backwards-compatibility, such that it plays nicely with the current system. If this is impossible, at least it can work side-by-side until the older one is removed.
  • [ ] Type-safety, so attempting to send an unsupported object would show a compile-time error. I'm not sure if that's possible, but it's what I'm aiming for.
  • [ ] Intuitiveness, it should be very easy for developers to work with that API. It should avoid doing more magic than the underlying gluing logic, and anyone looking at the code should be able to tell clearly what it does, without having to run it.
  • [ ] Efficient, it should avoid creating so many unnecessary wrappers and delegating function calls (although we could go easy on that point).

I'm still considering multiple designs, the most prominent one I have is some sort of Serializers. If you've ever used kotlinx.serialization, it's pretty much the design I'm thinking of, as it ticks all the boxes above. There's still some experimentation and adaptation needed with the idea to ensure the developer experience goes smooth.

I might do a follow-up comment with sample code that shows the concept. If I forget, please shamelessly ping me on Discord. I'm perfectly okay with that 😛

Revxrsal avatar Jan 19 '24 17:01 Revxrsal

This has been addressed in Lamp v4. Thanks for the help.

Revxrsal avatar Aug 16 '24 13:08 Revxrsal