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

Implement XEP-0444: Message Reactions in Smack #647

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ismael221
Copy link

@ismael221 ismael221 commented Jan 30, 2025

This commit adds support for XEP-0444 (Message Reactions) in Smack. Key changes include:

  • Added ReactionsManager to handle reactions, including adding, removing, and listening for reactions on messages.
  • Introduced ReactionsElement and Reaction classes to represent the element and individual emoji reactions.
  • Added ReactionsFilter to detect messages containing reactions.
  • Implemented ReactionRestrictions to manage restrictions like max reactions per user and allowed emojis.
  • Integrated reaction restrictions with XMPP service discovery.
  • Added ReactionsListener for applications to handle incoming reactions.
  • Included unit tests to verify functionality.

This enables emoji reactions in XMPP messages, with support for restrictions and service discovery.

Related: XEP-0444 (https://xmpp.org/extensions/xep-0444.html)

This commit adds support for XEP-0444 (Message Reactions) in Smack.
Key changes include:

- Added ReactionsManager to handle reactions, including adding,
  removing, and listening for reactions on messages.
- Introduced ReactionsElement and Reaction classes to represent
  the <reactions> element and individual emoji reactions.
- Added ReactionsFilter to detect messages containing reactions.
- Implemented ReactionRestrictions to manage restrictions like
  max reactions per user and allowed emojis.
- Integrated reaction restrictions with XMPP service discovery.
- Added ReactionsListener for applications to handle incoming
  reactions.
- Included unit tests to verify functionality.

This enables emoji reactions in XMPP messages, with support for
restrictions and service discovery.

Related: XEP-0444 (https://xmpp.org/extensions/xep-0444.html)
Copy link
Member

@Flowdalic Flowdalic left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution. Gave your PR a quick review from the top of my head. Hence my comments could a bit off and there is probably more.

Also, make sure that your code passes ./gradlew check.

public static DataForm createReactionRestrictionsForm(int maxReactionsPerUser, List<String> allowedEmojis) {

DataForm.Builder builder = DataForm.builder();
builder.setFormType(String.valueOf(DataForm.Type.result));
Copy link
Member

Choose a reason for hiding this comment

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

That String.valueOf can probably be dropped.

* @param listener The reactions listener to be added.
*/
public synchronized void addReactionsListener(ReactionsListener listener){
listeners.add(listener);
Copy link
Member

Choose a reason for hiding this comment

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

We usually expose the return value of add()

* @param listener The reactions listener to be removed.
*/
public synchronized void removeReactionsListener(ReactionsListener listener){
listeners.remove(listener);
Copy link
Member

Choose a reason for hiding this comment

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

We usually expose the return value of remove()

FormField.Builder<TextSingleFormField, TextSingleFormField.Builder> allowlistFieldBuilder = FormField.builder("allowlist");
for (String emoji : allowedEmojis) {
Reaction reaction = new Reaction(emoji);
FormField.builder("value").setValue((CharSequence) reaction);
Copy link
Member

Choose a reason for hiding this comment

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

This cast to CharSequence probably does not what you want.

while (true) {
XmlPullParser.Event tag = parser.next();

if (tag == XmlPullParser.Event.END_ELEMENT && parser.getName().equals(ReactionsElement.ELEMENT)) {
Copy link
Member

Choose a reason for hiding this comment

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

Please follow the idiom in the other Providers where we break out of the lop if END_ELEMENT and depth are correct.


ReactionsManager.addReactionsToMessage(message, emojis, messageId, null);

ReactionsElement reactionsElement = (ReactionsElement) message.getExtensionElement(ReactionsElement.ELEMENT, ReactionsElement.NAMESPACE);
Copy link
Member

Choose a reason for hiding this comment

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

Casts are bad, better use the type safe approach (may need adjustments)

Suggested change
ReactionsElement reactionsElement = (ReactionsElement) message.getExtensionElement(ReactionsElement.ELEMENT, ReactionsElement.NAMESPACE);
ReactionsElement reactionsElement = message.getExtensionElement(ReactionsElement.class);

reactionsManager.reactionsElementListener(message);

// Assertions: Ensure that the message contains the reactions element
assertNotNull(message.getExtensionElement(ReactionsElement.ELEMENT, ReactionsElement.NAMESPACE));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
assertNotNull(message.getExtensionElement(ReactionsElement.ELEMENT, ReactionsElement.NAMESPACE));
assertNotNull(message.getExtensionElement(ReactionsElement.class));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants