handleAutocomplete method

  1. @override
Future<void> handleAutocomplete(
  1. Map<String, dynamic> payload
)
override

Implementation

@override
Future<void> handleAutocomplete(Map<String, dynamic> payload) async {
  final data = payload['data'] as Map<String, dynamic>?;
  if (data == null) {
    _marshaller.logger.warn('Autocomplete payload missing "data" field');
    return;
  }

  final rootName = data['name'] as String?;
  if (rootName == null) {
    _marshaller.logger.warn('Autocomplete payload missing command name');
    return;
  }

  final rawOptions = data['options'];
  if (rawOptions == null) {
    _marshaller.logger.warn('Autocomplete payload has no options');
    return;
  }

  // Find focused option recursively.
  final focused = _findFocused(rawOptions as Iterable<dynamic>);
  if (focused == null) {
    _marshaller.logger.warn(
      'No focused option found in autocomplete payload',
    );
    return;
  }

  final optionName = focused['name'] as String;
  final optionValue = '${focused['value'] ?? ''}';

  // Collect other options (non-focused).
  final otherOptions = <String, dynamic>{};
  _collectNonFocused(rawOptions, otherOptions);

  // Look up handler.
  final commandHandlers = _autocompleteHandlers[rootName];
  final handler = commandHandlers?[optionName];
  if (handler == null) {
    _marshaller.logger.warn(
      'No autocomplete handler for command "$rootName" option "$optionName"',
    );
    return;
  }

  final ctx = AutocompleteContext(
    name: optionName,
    value: optionValue,
    options: otherOptions,
  );

  final choices = await handler(ctx);
  // Discord allows max 25 choices.
  final capped = choices.length > 25 ? choices.take(25).toList() : choices;

  final id = Snowflake.parse(payload['id'] as String);
  final token = payload['token'] as String;

  await _dataStore.interaction.sendAutocompleteResult(id, token, capped);
}