Files

83 lines
2.2 KiB
Dart

import 'dart:typed_data';
import 'messages.dart';
class OutgoingText {
static int _lastCid = 0;
static int nextCid() {
final now = DateTime.now().microsecondsSinceEpoch;
_lastCid = now > _lastCid ? now : _lastCid + 1;
return -_lastCid;
}
static CachedMessage prepare({
required int accountId,
required int chatId,
required String wireText,
required bool encrypted,
Map<String, dynamic>? payload,
Uint8List? sealedText,
int e2ee = CachedMessage.e2eeNone,
}) {
if (accountId == 0 || wireText.isEmpty) {
throw ArgumentError('An account and prepared text are required');
}
final cid = nextCid();
return CachedMessage(
id: 'temp_outbox_${-cid}',
accountId: accountId,
chatId: chatId,
senderId: accountId,
text: wireText,
time: DateTime.now().millisecondsSinceEpoch,
status: 'pending',
sealedText: sealedText,
e2ee: e2ee,
payload: {
...?payload,
'_outbox': {
'version': 1,
'cid': cid,
'encrypted': encrypted,
'attempts': 0,
'retryAt': 0,
},
},
);
}
static Map<String, dynamic>? metadata(CachedMessage message) {
final raw = message.payload?['_outbox'];
if (raw is! Map ||
raw['version'] != 1 ||
raw['cid'] is! int ||
(raw['cid'] as int) >= 0 ||
raw['encrypted'] is! bool) {
return null;
}
return Map<String, dynamic>.from(raw);
}
static List<Map<String, dynamic>> elements(CachedMessage message) =>
(message.payload?['elements'] as List? ?? const [])
.whereType<Map>()
.map((e) => Map<String, dynamic>.from(e))
.toList();
static int? replyId(CachedMessage message) {
final link = message.payload?['link'];
if (link is! Map || link['type'] != 'REPLY') return null;
final original = link['message'];
return _int(original is Map ? original['id'] : link['messageId']);
}
static int? replyChatId(CachedMessage message) {
final link = message.payload?['link'];
return link is Map && link['type'] == 'REPLY' ? _int(link['chatId']) : null;
}
static int? _int(Object? value) =>
value is int ? value : int.tryParse(value?.toString() ?? '');
}