Files

110 lines
3.2 KiB
Dart

import '../core/utils/text_format.dart';
import 'contact_info.dart';
class BotCommand {
final String name;
final String? description;
const BotCommand({required this.name, this.description});
factory BotCommand.fromMap(Map map) => BotCommand(
name: map['name']?.toString() ?? '',
description: (map['description'] as String?)?.trim().isNotEmpty == true
? (map['description'] as String).trim()
: null,
);
String get slash => '/$name';
}
// #***! данные бота плюс карточка контакта
class BotStartMessage {
final String text;
final List<FormatRange> ranges;
const BotStartMessage({required this.text, this.ranges = const []});
static BotStartMessage? fromPayload(Object? raw) {
if (raw is! Map) return null;
final body = raw['text'];
if (body is! Map) return null;
final text = body['text'];
if (text is! String || text.trim().isEmpty) return null;
return BotStartMessage(
text: text,
ranges: parseFormatElements(body['elements']),
);
}
({String heading, String body, List<FormatRange> bodyRanges}) get sections {
var split = 0;
for (final range in ranges) {
if (range.format == TextFormat.heading && range.start == 0) {
split = range.end.clamp(0, text.length);
break;
}
}
final rest = text.substring(split);
final bodyStart = split + rest.length - rest.trimLeft().length;
final body = text.substring(bodyStart).trimRight();
return (
heading: text.substring(0, split).trim(),
body: body,
bodyRanges: [
for (final range in ranges)
if (range.format != TextFormat.heading &&
range.start >= bodyStart &&
range.start - bodyStart < body.length)
FormatRange(
format: range.format,
start: range.start - bodyStart,
length: range.end - bodyStart > body.length
? body.length - (range.start - bodyStart)
: range.length,
entityId: range.entityId,
entityName: range.entityName,
attributes: range.attributes,
),
],
);
}
}
class BotInfo {
final int botId;
final List<BotCommand> commands;
final ContactInfo? contact;
final BotStartMessage? startMessage;
const BotInfo({
required this.botId,
required this.commands,
this.contact,
this.startMessage,
});
factory BotInfo.fromPayload(int botId, Map<String, dynamic> payload) {
final rawCommands = payload['commands'];
final commands = <BotCommand>[];
if (rawCommands is List) {
for (final c in rawCommands.whereType<Map>()) {
final command = BotCommand.fromMap(c);
if (command.name.isNotEmpty) commands.add(command);
}
}
final rawContact = payload['contact'];
return BotInfo(
botId: botId,
commands: commands,
contact: rawContact is Map
? ContactInfo.fromMap(Map<String, dynamic>.from(rawContact))
: null,
startMessage: BotStartMessage.fromPayload(payload['startMessage']),
);
}
String? get description => contact?.raw['description'] as String?;
String? get link => contact?.raw['link'] as String?;
}