Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add insertion API and a few other things #56

Merged
merged 5 commits into from
Jan 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions src/main/java/mkremins/fanciful/FancyMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ public FancyMessage text(String text) {
return this;
}

/**
* Sets the text of the current editing component to a value.
* @param text The new text of the current editing component.
* @return This builder instance.
*/
public FancyMessage text(TextualComponent text) {
MessagePart latest = latest();
latest.text = text;
Expand All @@ -126,6 +131,7 @@ public FancyMessage text(TextualComponent text) {
* Sets the color of the current editing component to a value.
* @param color The new color of the current editing component.
* @return This builder instance.
* @exception IllegalArgumentException If the specified {@code ChatColor} enumeration value is not a color (but a format value).
*/
public FancyMessage color(final ChatColor color) {
if (!color.isColor()) {
Expand Down Expand Up @@ -183,6 +189,18 @@ public FancyMessage suggest(final String command) {
onClick("suggest_command", command);
return this;
}

/**
* Set the behavior of the current editing component to instruct the client to append the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is SHIFT-CLICKED.
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
* @param command The text to append to the chat bar of the client.
* @return This builder instance.
*/
public FancyMessage insert(final String command) {
latest().insertionData = command;
dirty = true;
return this;
}

/**
* Set the behavior of the current editing component to instruct the client to send the specified string to the server as a chat message when the currently edited part of the {@code FancyMessage} is clicked.
Expand Down Expand Up @@ -343,6 +361,7 @@ public FancyMessage itemTooltip(final ItemStack itemStack) {
return this;
}
}


/**
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
Expand Down Expand Up @@ -450,6 +469,60 @@ public FancyMessage formattedTooltip(final Iterable<FancyMessage> lines){
return formattedTooltip(ArrayWrapper.toArray(lines, FancyMessage.class));
}

/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final String... replacements){
for(String str : replacements){
latest().translationReplacements.add(new JsonString(str));
}
dirty = true;

return this;
}
/*

/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/ /* ------------
public FancyMessage translationReplacements(final Iterable<? extends CharSequence> replacements){
for(CharSequence str : replacements){
latest().translationReplacements.add(new JsonString(str));
}

return this;
}

*/

/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final FancyMessage... replacements){
for(FancyMessage str : replacements){
latest().translationReplacements.add(str);
}

dirty = true;

return this;
}

/**
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
* @param replacements The replacements, in order, that will be used in the language-specific message.
* @return This builder instance.
*/
public FancyMessage translationReplacements(final Iterable<FancyMessage> replacements){
return translationReplacements(ArrayWrapper.toArray(replacements, FancyMessage.class));
}

/**
* Terminate construction of the current editing component, and begin construction of a new message component.
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
Expand Down Expand Up @@ -733,6 +806,18 @@ public static FancyMessage deserialize(String json){
// Therefore, recursion time!
component.hoverActionData = deserialize(object.get("value").toString() /* This should properly serialize the JSON object as a JSON string */);
}
}else if(entry.getKey().equals("insertion")){
component.insertionData = entry.getValue().getAsString();
}else if(entry.getKey().equals("with")){
for(JsonElement object : entry.getValue().getAsJsonArray()){
if(object.isJsonPrimitive()){
component.translationReplacements.add(new JsonString(object.getAsString()));
}else{
// Only composite type stored in this array is - again - FancyMessages
// Recurse within this function to parse this as a translation replacement
component.translationReplacements.add(deserialize(object.toString()));
}
}
}
}
returnVal.messageParts.add(component);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/mkremins/fanciful/JsonString.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ final class JsonString implements JsonRepresentedObject, ConfigurationSerializab

private String _value;

public JsonString(String value){
_value = value;
public JsonString(CharSequence value){
_value = value == null ? null : value.toString();
}

@Override
Expand Down
23 changes: 20 additions & 3 deletions src/main/java/mkremins/fanciful/MessagePart.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ final class MessagePart implements JsonRepresentedObject, ConfigurationSerializa
hoverActionName = null;
JsonRepresentedObject hoverActionData = null;
TextualComponent text = null;
String insertionData = null;
ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<JsonRepresentedObject>();

MessagePart(final TextualComponent text){
this.text = text;
Expand All @@ -49,6 +51,7 @@ public MessagePart clone() throws CloneNotSupportedException{
}else if(hoverActionData instanceof FancyMessage){
obj.hoverActionData = ((FancyMessage)hoverActionData).clone();
}
obj.translationReplacements = (ArrayList<JsonRepresentedObject>)translationReplacements.clone();
return obj;

}
Expand Down Expand Up @@ -100,6 +103,16 @@ public void writeJson(JsonWriter json) {
hoverActionData.writeJson(json);
json.endObject();
}
if(insertionData != null){
json.name("insertion").value(insertionData);
}
if(translationReplacements.size() > 0 && text != null && TextualComponent.isTranslatableText(text)){
json.name("with").beginArray();
for(JsonRepresentedObject obj : translationReplacements){
obj.writeJson(json);
}
json.endArray();
}
json.endObject();
} catch(IOException e){
Bukkit.getLogger().log(Level.WARNING, "A problem occured during writing of JSON string", e);
Expand All @@ -115,6 +128,8 @@ public Map<String, Object> serialize() {
map.put("hoverActionData", hoverActionData);
map.put("clickActionName", clickActionName);
map.put("clickActionData", clickActionData);
map.put("insertion", insertionData);
map.put("translationReplacements", translationReplacements);
return map;
}

Expand All @@ -123,10 +138,12 @@ public static MessagePart deserialize(Map<String, Object> serialized){
MessagePart part = new MessagePart((TextualComponent)serialized.get("text"));
part.styles = (ArrayList<ChatColor>)serialized.get("styles");
part.color = ChatColor.getByChar(serialized.get("color").toString());
part.hoverActionName = serialized.get("hoverActionName").toString();
part.hoverActionName = (String)serialized.get("hoverActionName");
part.hoverActionData = (JsonRepresentedObject)serialized.get("hoverActionData");
part.clickActionName = serialized.get("clickActionName").toString();
part.clickActionData = serialized.get("clickActionData").toString();
part.clickActionName = (String)serialized.get("clickActionName");
part.clickActionData = (String)serialized.get("clickActionData");
part.insertionData = (String)serialized.get("insertion");
part.translationReplacements = (ArrayList<JsonRepresentedObject>)serialized.get("translationReplacements");
return part;
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/mkremins/fanciful/TextualComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Represents a textual component of a message part.
* This can be used to not only represent string literals in a JSON message,
* but also to represent localized strings and other text values.
* <p>Different instances of this class can be created with static constructor methods.</p>
*/
public abstract class TextualComponent implements Cloneable {

Expand Down Expand Up @@ -69,6 +70,10 @@ static boolean isTextKey(String key){
return key.equals("translate") || key.equals("text") || key.equals("score") || key.equals("selector");
}

static boolean isTranslatableText(TextualComponent component){
return component instanceof ComplexTextTypeComponent && ((ComplexTextTypeComponent)component).getKey().equals("translate");
}

/**
* Internal class used to represent all types of text components.
* Exception validating done is on keys and values.
Expand Down