parseSongMenuData function

JsonMap parseSongMenuData(
  1. JsonMap data
)

Returns a map with data from the provided song's context menu.

Example: { "inLibrary": true, "feedbackTokens": { "add": "...", "remove": "..." }, "pinnedToListenAgain": true, "listenAgainFeedbackTokens": { "pin": "...", "unpin": "..." } }

Implementation

JsonMap parseSongMenuData(JsonMap data) {
  if (!data.containsKey('menu')) {
    return {};
  }

  final songData = <String, dynamic>{};

  for (final item in nav(data, MENU_ITEMS) as List) {
    final menuItem =
        (nav(item, [TOGGLE_MENU], nullIfAbsent: true) ??
                nav(item, ['menuServiceItemRenderer'], nullIfAbsent: true))
            as JsonMap?;

    if (menuItem == null) {
      continue;
    }

    songData['inLibrary'] ??= false;
    songData['pinnedToListenAgain'] ??= false;

    final currentIconType =
        nav(menuItem, ['defaultIcon', 'iconType'], nullIfAbsent: true) ??
        nav(menuItem, ['icon', 'iconType'], nullIfAbsent: true);

    String? feedbackToken(String endpointType) {
      return nav(menuItem, [
            endpointType,
            ...FEEDBACK_TOKEN,
          ], nullIfAbsent: true)
          as String?;
    }

    // YTM signals the current state with isToggled instead of swapping the default/toggled icons
    final isToggled = menuItem['isToggled'] == true;

    switch (currentIconType) {
      case 'KEEP': // pin to listen again
        songData['pinnedToListenAgain'] = isToggled;
        songData['listenAgainFeedbackTokens'] = {
          'pin': feedbackToken('defaultServiceEndpoint'),
          'unpin': feedbackToken('toggledServiceEndpoint'),
        };

      case 'KEEP_OFF': // unpin from listen again
        songData['pinnedToListenAgain'] = true;
        songData['listenAgainFeedbackTokens'] = {
          'pin': feedbackToken('toggledServiceEndpoint'),
          'unpin': feedbackToken('defaultServiceEndpoint'),
        };

      case 'BOOKMARK_BORDER': // add to library
        songData['inLibrary'] = isToggled;
        songData['feedbackTokens'] = {
          'add': feedbackToken('defaultServiceEndpoint'),
          'remove': feedbackToken('toggledServiceEndpoint'),
        };

      case 'BOOKMARK': // remove from library
        songData['inLibrary'] = true;
        songData['feedbackTokens'] = {
          'add': feedbackToken('toggledServiceEndpoint'),
          'remove': feedbackToken('defaultServiceEndpoint'),
        };

      case 'REMOVE_FROM_HISTORY':
        songData['feedbackToken'] = feedbackToken('serviceEndpoint');
    }
  }

  return songData;
}