8 Commits

Author SHA1 Message Date
0ae13acca0 chore(release): publish packages
- moxxmpp@0.1.6+1
 - moxxmpp_socket_tcp@0.1.2+9
2022-11-26 15:48:48 +01:00
d383fa31ae fix: Fix LMC not working 2022-11-26 15:48:29 +01:00
d1de394cd9 chore(release): publish packages
- moxxmpp@0.1.6
 - moxxmpp_socket_tcp@0.1.2+8
2022-11-26 15:09:05 +01:00
14c48bcc64 feat: Implement XEP-0308 2022-11-26 15:08:20 +01:00
138edffb0a chore(release): publish packages
- moxxmpp@0.1.5
 - moxxmpp_socket_tcp@0.1.2+7
2022-11-22 22:49:41 +01:00
eb8f6ba17a feat: Message events now contain the stanza error, if available 2022-11-22 22:49:10 +01:00
beff05765b chore(release): publish packages
- moxxmpp@0.1.4
 - moxxmpp_socket_tcp@0.1.2+6
2022-11-21 16:06:49 +01:00
3b7ded3b96 fix: Only stanza-id required 'sid:0' support 2022-11-21 15:27:53 +01:00
15 changed files with 179 additions and 26 deletions

View File

@@ -16,10 +16,10 @@ dependencies:
version: 0.1.4+1 version: 0.1.4+1
moxxmpp: moxxmpp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.1.3+1 version: 0.1.6+1
moxxmpp_socket_tcp: moxxmpp_socket_tcp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: 0.1.2+5 version: 0.1.2+9
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

View File

@@ -1,3 +1,20 @@
## 0.1.6+1
- **FIX**: Fix LMC not working.
## 0.1.6
- **FEAT**: Implement XEP-0308.
## 0.1.5
- **FEAT**: Message events now contain the stanza error, if available.
## 0.1.4
- **FIX**: Only stanza-id required 'sid:0' support.
- **FEAT**: Implement parsing and sending of retractions.
## 0.1.3+1 ## 0.1.3+1
- **FIX**: Expose the error classes. - **FIX**: Expose the error classes.

View File

@@ -59,6 +59,7 @@ export 'package:moxxmpp/src/xeps/xep_0203.dart';
export 'package:moxxmpp/src/xeps/xep_0280.dart'; export 'package:moxxmpp/src/xeps/xep_0280.dart';
export 'package:moxxmpp/src/xeps/xep_0297.dart'; export 'package:moxxmpp/src/xeps/xep_0297.dart';
export 'package:moxxmpp/src/xeps/xep_0300.dart'; export 'package:moxxmpp/src/xeps/xep_0300.dart';
export 'package:moxxmpp/src/xeps/xep_0308.dart';
export 'package:moxxmpp/src/xeps/xep_0333.dart'; export 'package:moxxmpp/src/xeps/xep_0333.dart';
export 'package:moxxmpp/src/xeps/xep_0334.dart'; export 'package:moxxmpp/src/xeps/xep_0334.dart';
export 'package:moxxmpp/src/xeps/xep_0352.dart'; export 'package:moxxmpp/src/xeps/xep_0352.dart';

View File

@@ -63,6 +63,7 @@ class MessageEvent extends XmppEvent {
required this.isMarkable, required this.isMarkable,
required this.encrypted, required this.encrypted,
required this.other, required this.other,
this.error,
this.type, this.type,
this.oob, this.oob,
this.sfs, this.sfs,
@@ -73,7 +74,9 @@ class MessageEvent extends XmppEvent {
this.funReplacement, this.funReplacement,
this.funCancellation, this.funCancellation,
this.messageRetraction, this.messageRetraction,
this.messageCorrectionId,
}); });
final StanzaError? error;
final String body; final String body;
final JID fromJid; final JID fromJid;
final JID toJid; final JID toJid;
@@ -93,6 +96,7 @@ class MessageEvent extends XmppEvent {
final String? funCancellation; final String? funCancellation;
final bool encrypted; final bool encrypted;
final MessageRetractionData? messageRetraction; final MessageRetractionData? messageRetraction;
final String? messageCorrectionId;
final Map<String, dynamic> other; final Map<String, dynamic> other;
} }

View File

@@ -59,6 +59,8 @@ class StanzaHandlerData with _$StanzaHandlerData {
// If non-null, then it indicates the origin Id of the message that should be // If non-null, then it indicates the origin Id of the message that should be
// retracted // retracted
MessageRetractionData? messageRetraction, MessageRetractionData? messageRetraction,
// If non-null, then the message is a correction for the specified stanza Id
String? lastMessageCorrectionSid,
} }
) = _StanzaHandlerData; ) = _StanzaHandlerData;
} }

View File

@@ -58,7 +58,8 @@ mixin _$StanzaHandlerData {
throw _privateConstructorUsedError; // If non-null, then it indicates the origin Id of the message that should be throw _privateConstructorUsedError; // If non-null, then it indicates the origin Id of the message that should be
// retracted // retracted
MessageRetractionData? get messageRetraction => MessageRetractionData? get messageRetraction =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError; // If non-null, then the message is a correction for the specified stanza Id
String? get lastMessageCorrectionSid => throw _privateConstructorUsedError;
@JsonKey(ignore: true) @JsonKey(ignore: true)
$StanzaHandlerDataCopyWith<StanzaHandlerData> get copyWith => $StanzaHandlerDataCopyWith<StanzaHandlerData> get copyWith =>
@@ -92,7 +93,8 @@ abstract class $StanzaHandlerDataCopyWith<$Res> {
ExplicitEncryptionType? encryptionType, ExplicitEncryptionType? encryptionType,
DelayedDelivery? delayedDelivery, DelayedDelivery? delayedDelivery,
Map<String, dynamic> other, Map<String, dynamic> other,
MessageRetractionData? messageRetraction}); MessageRetractionData? messageRetraction,
String? lastMessageCorrectionSid});
} }
/// @nodoc /// @nodoc
@@ -128,6 +130,7 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
Object? delayedDelivery = freezed, Object? delayedDelivery = freezed,
Object? other = freezed, Object? other = freezed,
Object? messageRetraction = freezed, Object? messageRetraction = freezed,
Object? lastMessageCorrectionSid = freezed,
}) { }) {
return _then(_value.copyWith( return _then(_value.copyWith(
done: done == freezed done: done == freezed
@@ -218,6 +221,10 @@ class _$StanzaHandlerDataCopyWithImpl<$Res>
? _value.messageRetraction ? _value.messageRetraction
: messageRetraction // ignore: cast_nullable_to_non_nullable : messageRetraction // ignore: cast_nullable_to_non_nullable
as MessageRetractionData?, as MessageRetractionData?,
lastMessageCorrectionSid: lastMessageCorrectionSid == freezed
? _value.lastMessageCorrectionSid
: lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
as String?,
)); ));
} }
} }
@@ -251,7 +258,8 @@ abstract class _$$_StanzaHandlerDataCopyWith<$Res>
ExplicitEncryptionType? encryptionType, ExplicitEncryptionType? encryptionType,
DelayedDelivery? delayedDelivery, DelayedDelivery? delayedDelivery,
Map<String, dynamic> other, Map<String, dynamic> other,
MessageRetractionData? messageRetraction}); MessageRetractionData? messageRetraction,
String? lastMessageCorrectionSid});
} }
/// @nodoc /// @nodoc
@@ -289,6 +297,7 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
Object? delayedDelivery = freezed, Object? delayedDelivery = freezed,
Object? other = freezed, Object? other = freezed,
Object? messageRetraction = freezed, Object? messageRetraction = freezed,
Object? lastMessageCorrectionSid = freezed,
}) { }) {
return _then(_$_StanzaHandlerData( return _then(_$_StanzaHandlerData(
done == freezed done == freezed
@@ -379,6 +388,10 @@ class __$$_StanzaHandlerDataCopyWithImpl<$Res>
? _value.messageRetraction ? _value.messageRetraction
: messageRetraction // ignore: cast_nullable_to_non_nullable : messageRetraction // ignore: cast_nullable_to_non_nullable
as MessageRetractionData?, as MessageRetractionData?,
lastMessageCorrectionSid: lastMessageCorrectionSid == freezed
? _value.lastMessageCorrectionSid
: lastMessageCorrectionSid // ignore: cast_nullable_to_non_nullable
as String?,
)); ));
} }
} }
@@ -404,7 +417,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
this.encryptionType, this.encryptionType,
this.delayedDelivery, this.delayedDelivery,
final Map<String, dynamic> other = const <String, dynamic>{}, final Map<String, dynamic> other = const <String, dynamic>{},
this.messageRetraction}) this.messageRetraction,
this.lastMessageCorrectionSid})
: _other = other; : _other = other;
// Indicates to the runner that processing is now done. This means that all // Indicates to the runner that processing is now done. This means that all
@@ -484,10 +498,13 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
// retracted // retracted
@override @override
final MessageRetractionData? messageRetraction; final MessageRetractionData? messageRetraction;
// If non-null, then the message is a correction for the specified stanza Id
@override
final String? lastMessageCorrectionSid;
@override @override
String toString() { String toString() {
return 'StanzaHandlerData(done: $done, cancel: $cancel, cancelReason: $cancelReason, stanza: $stanza, retransmitted: $retransmitted, sims: $sims, sfs: $sfs, oob: $oob, stableId: $stableId, reply: $reply, chatState: $chatState, isCarbon: $isCarbon, deliveryReceiptRequested: $deliveryReceiptRequested, isMarkable: $isMarkable, fun: $fun, funReplacement: $funReplacement, funCancellation: $funCancellation, encrypted: $encrypted, encryptionType: $encryptionType, delayedDelivery: $delayedDelivery, other: $other, messageRetraction: $messageRetraction)'; return 'StanzaHandlerData(done: $done, cancel: $cancel, cancelReason: $cancelReason, stanza: $stanza, retransmitted: $retransmitted, sims: $sims, sfs: $sfs, oob: $oob, stableId: $stableId, reply: $reply, chatState: $chatState, isCarbon: $isCarbon, deliveryReceiptRequested: $deliveryReceiptRequested, isMarkable: $isMarkable, fun: $fun, funReplacement: $funReplacement, funCancellation: $funCancellation, encrypted: $encrypted, encryptionType: $encryptionType, delayedDelivery: $delayedDelivery, other: $other, messageRetraction: $messageRetraction, lastMessageCorrectionSid: $lastMessageCorrectionSid)';
} }
@override @override
@@ -525,7 +542,9 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
.equals(other.delayedDelivery, delayedDelivery) && .equals(other.delayedDelivery, delayedDelivery) &&
const DeepCollectionEquality().equals(other._other, this._other) && const DeepCollectionEquality().equals(other._other, this._other) &&
const DeepCollectionEquality() const DeepCollectionEquality()
.equals(other.messageRetraction, messageRetraction)); .equals(other.messageRetraction, messageRetraction) &&
const DeepCollectionEquality().equals(
other.lastMessageCorrectionSid, lastMessageCorrectionSid));
} }
@override @override
@@ -552,7 +571,8 @@ class _$_StanzaHandlerData implements _StanzaHandlerData {
const DeepCollectionEquality().hash(encryptionType), const DeepCollectionEquality().hash(encryptionType),
const DeepCollectionEquality().hash(delayedDelivery), const DeepCollectionEquality().hash(delayedDelivery),
const DeepCollectionEquality().hash(_other), const DeepCollectionEquality().hash(_other),
const DeepCollectionEquality().hash(messageRetraction) const DeepCollectionEquality().hash(messageRetraction),
const DeepCollectionEquality().hash(lastMessageCorrectionSid)
]); ]);
@JsonKey(ignore: true) @JsonKey(ignore: true)
@@ -582,7 +602,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
final ExplicitEncryptionType? encryptionType, final ExplicitEncryptionType? encryptionType,
final DelayedDelivery? delayedDelivery, final DelayedDelivery? delayedDelivery,
final Map<String, dynamic> other, final Map<String, dynamic> other,
final MessageRetractionData? messageRetraction}) = _$_StanzaHandlerData; final MessageRetractionData? messageRetraction,
final String? lastMessageCorrectionSid}) = _$_StanzaHandlerData;
@override // Indicates to the runner that processing is now done. This means that all @override // Indicates to the runner that processing is now done. This means that all
// pre-processing is done and no other handlers should be consulted. // pre-processing is done and no other handlers should be consulted.
@@ -635,6 +656,8 @@ abstract class _StanzaHandlerData implements StanzaHandlerData {
@override // If non-null, then it indicates the origin Id of the message that should be @override // If non-null, then it indicates the origin Id of the message that should be
// retracted // retracted
MessageRetractionData? get messageRetraction; MessageRetractionData? get messageRetraction;
@override // If non-null, then the message is a correction for the specified stanza Id
String? get lastMessageCorrectionSid;
@override @override
@JsonKey(ignore: true) @JsonKey(ignore: true)
_$$_StanzaHandlerDataCopyWith<_$_StanzaHandlerData> get copyWith => _$$_StanzaHandlerDataCopyWith<_$_StanzaHandlerData> get copyWith =>

View File

@@ -25,3 +25,4 @@ const emeManager = 'org.moxxmpp.ememanager';
const cryptographicHashManager = 'org.moxxmpp.cryptographichashmanager'; const cryptographicHashManager = 'org.moxxmpp.cryptographichashmanager';
const delayedDeliveryManager = 'org.moxxmpp.delayeddeliverymanager'; const delayedDeliveryManager = 'org.moxxmpp.delayeddeliverymanager';
const messageRetractionManager = 'org.moxxmpp.messageretractionmanager'; const messageRetractionManager = 'org.moxxmpp.messageretractionmanager';
const lastMessageCorrectionManager = 'org.moxxmpp.lastmessagecorrectionmanager';

View File

@@ -11,6 +11,7 @@ import 'package:moxxmpp/src/xeps/staging/file_upload_notification.dart';
import 'package:moxxmpp/src/xeps/xep_0066.dart'; import 'package:moxxmpp/src/xeps/xep_0066.dart';
import 'package:moxxmpp/src/xeps/xep_0085.dart'; import 'package:moxxmpp/src/xeps/xep_0085.dart';
import 'package:moxxmpp/src/xeps/xep_0184.dart'; import 'package:moxxmpp/src/xeps/xep_0184.dart';
import 'package:moxxmpp/src/xeps/xep_0308.dart';
import 'package:moxxmpp/src/xeps/xep_0333.dart'; import 'package:moxxmpp/src/xeps/xep_0333.dart';
import 'package:moxxmpp/src/xeps/xep_0359.dart'; import 'package:moxxmpp/src/xeps/xep_0359.dart';
import 'package:moxxmpp/src/xeps/xep_0424.dart'; import 'package:moxxmpp/src/xeps/xep_0424.dart';
@@ -36,6 +37,7 @@ class MessageDetails {
this.funCancellation, this.funCancellation,
this.shouldEncrypt = false, this.shouldEncrypt = false,
this.messageRetraction, this.messageRetraction,
this.lastMessageCorrectionId,
}); });
final String to; final String to;
final String? body; final String? body;
@@ -53,6 +55,7 @@ class MessageDetails {
final String? funCancellation; final String? funCancellation;
final bool shouldEncrypt; final bool shouldEncrypt;
final MessageRetractionData? messageRetraction; final MessageRetractionData? messageRetraction;
final String? lastMessageCorrectionId;
} }
class MessageManager extends XmppManagerBase { class MessageManager extends XmppManagerBase {
@@ -98,7 +101,9 @@ class MessageManager extends XmppManagerBase {
funCancellation: state.funCancellation, funCancellation: state.funCancellation,
encrypted: state.encrypted, encrypted: state.encrypted,
messageRetraction: state.messageRetraction, messageRetraction: state.messageRetraction,
messageCorrectionId: state.lastMessageCorrectionSid,
other: state.other, other: state.other,
error: StanzaError.fromStanza(message),
),); ),);
return state.copyWith(done: true); return state.copyWith(done: true);
@@ -249,6 +254,14 @@ class MessageManager extends XmppManagerBase {
} }
} }
if (details.lastMessageCorrectionId != null) {
stanza.addChild(
makeLastMessageCorrectionEdit(
details.lastMessageCorrectionId!,
),
);
}
getAttributes().sendStanza(stanza, awaitable: false); getAttributes().sendStanza(stanza, awaitable: false);
} }
} }

View File

@@ -76,6 +76,9 @@ const hashSha3512 = 'sha3-512';
const hashBlake2b256 = 'blake2b-256'; const hashBlake2b256 = 'blake2b-256';
const hashBlake2b512 = 'blake2b-512'; const hashBlake2b512 = 'blake2b-512';
// XEP-0308
const lmcXmlns = 'urn:xmpp:message-correct:0';
// XEP-0333 // XEP-0333
const chatMarkersXmlns = 'urn:xmpp:chat-markers:0'; const chatMarkersXmlns = 'urn:xmpp:chat-markers:0';

View File

@@ -1,6 +1,28 @@
import 'package:moxxmpp/src/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stringxml.dart'; import 'package:moxxmpp/src/stringxml.dart';
/// A simple description of the <error /> element that may be inside a stanza
class StanzaError {
StanzaError(this.type, this.error);
String type;
String error;
/// Returns a StanzaError if [stanza] contains a <error /> element. If not, returns
/// null.
static StanzaError? fromStanza(Stanza stanza) {
final error = stanza.firstTag('error');
if (error == null) return null;
final stanzaError = error.firstTagByXmlns(fullStanzaXmlns);
if (stanzaError == null) return null;
return StanzaError(
error.attributes['type']! as String,
stanzaError.tag,
);
}
}
class Stanza extends XMLNode { class Stanza extends XMLNode {
// ignore: use_super_parameters // ignore: use_super_parameters
Stanza({ this.to, this.from, this.type, this.id, List<XMLNode> children = const [], required String tag, Map<String, String> attributes = const {} }) : super( Stanza({ this.to, this.from, this.type, this.id, List<XMLNode> children = const [], required String tag, Map<String, String> attributes = const {} }) : super(

View File

@@ -0,0 +1,50 @@
import 'package:moxxmpp/src/managers/base.dart';
import 'package:moxxmpp/src/managers/data.dart';
import 'package:moxxmpp/src/managers/handlers.dart';
import 'package:moxxmpp/src/managers/namespaces.dart';
import 'package:moxxmpp/src/namespaces.dart';
import 'package:moxxmpp/src/stanza.dart';
import 'package:moxxmpp/src/stringxml.dart';
XMLNode makeLastMessageCorrectionEdit(String id) {
return XMLNode.xmlns(
tag: 'replace',
xmlns: lmcXmlns,
attributes: <String, String>{
'id': id,
},
);
}
class LastMessageCorrectionManager extends XmppManagerBase {
@override
String getName() => 'LastMessageCorrectionManager';
@override
String getId() => lastMessageCorrectionManager;
@override
List<String> getDiscoFeatures() => [ lmcXmlns ];
@override
List<StanzaHandler> getIncomingStanzaHandlers() => [
StanzaHandler(
stanzaTag: 'message',
tagName: 'replace',
tagXmlns: lmcXmlns,
callback: _onMessage,
// Before the message handler
priority: -99,
)
];
@override
Future<bool> isSupported() async => true;
Future<StanzaHandlerData> _onMessage(Stanza stanza, StanzaHandlerData state) async {
final edit = stanza.firstTag('replace', xmlns: lmcXmlns)!;
return state.copyWith(
lastMessageCorrectionSid: edit.attributes['id']! as String,
);
}
}

View File

@@ -58,8 +58,16 @@ class StableIdManager extends XmppManagerBase {
String? stanzaIdBy; String? stanzaIdBy;
final originIdTag = message.firstTag('origin-id', xmlns: stableIdXmlns); final originIdTag = message.firstTag('origin-id', xmlns: stableIdXmlns);
final stanzaIdTag = message.firstTag('stanza-id', xmlns: stableIdXmlns); final stanzaIdTag = message.firstTag('stanza-id', xmlns: stableIdXmlns);
if (originIdTag != null || stanzaIdTag != null) {
logger.finest('Found Unique and Stable Stanza Id tag'); // Process the origin id
if (originIdTag != null) {
logger.finest('Found origin Id tag');
originId = originIdTag.attributes['id']! as String;
}
// Process the stanza id tag
if (stanzaIdTag != null) {
logger.finest('Found stanza Id tag');
final attrs = getAttributes(); final attrs = getAttributes();
final disco = attrs.getManagerById<DiscoManager>(discoManager)!; final disco = attrs.getManagerById<DiscoManager>(discoManager)!;
final result = await disco.discoInfoQuery(from.toString()); final result = await disco.discoInfoQuery(from.toString());
@@ -68,17 +76,10 @@ class StableIdManager extends XmppManagerBase {
logger.finest('Got info for ${from.toString()}'); logger.finest('Got info for ${from.toString()}');
if (info.features.contains(stableIdXmlns)) { if (info.features.contains(stableIdXmlns)) {
logger.finest('${from.toString()} supports $stableIdXmlns.'); logger.finest('${from.toString()} supports $stableIdXmlns.');
if (originIdTag != null) {
originId = originIdTag.attributes['id']! as String;
}
if (stanzaIdTag != null) {
stanzaId = stanzaIdTag.attributes['id']! as String; stanzaId = stanzaIdTag.attributes['id']! as String;
stanzaIdBy = stanzaIdTag.attributes['by']! as String; stanzaIdBy = stanzaIdTag.attributes['by']! as String;
}
} else { } else {
logger.finest('${from.toString()} does not support $stableIdXmlns. Ignoring... '); logger.finest('${from.toString()} does not support $stableIdXmlns. Ignoring stanza id... ');
} }
} else { } else {
logger.finest('Failed to find out if ${from.toString()} supports $stableIdXmlns. Ignoring... '); logger.finest('Failed to find out if ${from.toString()} supports $stableIdXmlns. Ignoring... ');

View File

@@ -1,6 +1,6 @@
name: moxxmpp name: moxxmpp
description: A pure-Dart XMPP library description: A pure-Dart XMPP library
version: 0.1.3+1 version: 0.1.6+1
homepage: https://codeberg.org/moxxy/moxxmpp homepage: https://codeberg.org/moxxy/moxxmpp
publish_to: https://git.polynom.me/api/packages/Moxxy/pub publish_to: https://git.polynom.me/api/packages/Moxxy/pub
@@ -31,6 +31,6 @@ dev_dependencies:
build_runner: ^2.1.11 build_runner: ^2.1.11
moxxmpp_socket_tcp: moxxmpp_socket_tcp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: ^0.1.2+5 version: ^0.1.2+9
test: ^1.16.0 test: ^1.16.0
very_good_analysis: ^3.0.1 very_good_analysis: ^3.0.1

View File

@@ -1,3 +1,19 @@
## 0.1.2+9
- Update a dependency to the latest release.
## 0.1.2+8
- Update a dependency to the latest release.
## 0.1.2+7
- Update a dependency to the latest release.
## 0.1.2+6
- Update a dependency to the latest release.
## 0.1.2+5 ## 0.1.2+5
- Update a dependency to the latest release. - Update a dependency to the latest release.

View File

@@ -1,6 +1,6 @@
name: moxxmpp_socket_tcp name: moxxmpp_socket_tcp
description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368 description: A socket for moxxmpp using TCP that implements the RFC6120 connection algorithm and XEP-0368
version: 0.1.2+5 version: 0.1.2+9
homepage: https://codeberg.org/moxxy/moxxmpp homepage: https://codeberg.org/moxxy/moxxmpp
publish_to: https://git.polynom.me/api/packages/Moxxy/pub publish_to: https://git.polynom.me/api/packages/Moxxy/pub
@@ -12,7 +12,7 @@ dependencies:
meta: ^1.6.0 meta: ^1.6.0
moxxmpp: moxxmpp:
hosted: https://git.polynom.me/api/packages/Moxxy/pub hosted: https://git.polynom.me/api/packages/Moxxy/pub
version: ^0.1.3+1 version: ^0.1.6+1
dev_dependencies: dev_dependencies:
lints: ^2.0.0 lints: ^2.0.0