Add support for BTTV badges

This commit is contained in:
Tommy Chow 2022-01-01 00:58:06 -05:00
parent e3688bd3ac
commit 02b4519d01
7 changed files with 112 additions and 0 deletions

View file

@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:frosty/models/badges.dart';
import 'package:frosty/models/emotes.dart';
import 'package:http/http.dart' as http;
@ -39,4 +40,18 @@ class BTTV {
return [];
}
}
static Future<Map<String, BadgeInfoBTTV>?> getBadges() async {
final url = Uri.parse('https://api.betterttv.net/3/cached/badges');
final response = await http.get(url);
if (response.statusCode == 200) {
final badges = jsonDecode(response.body) as List;
final badgeObjects = badges.map((badge) => BadgeInfoBTTV.fromJson(badge)).toList();
return {for (final badge in badgeObjects) badge.providerId: badge};
}
debugPrint('Failed to get FFZ badges');
}
}

View file

@ -91,3 +91,35 @@ class BadgeInfo7TV {
factory BadgeInfo7TV.fromJson(Map<String, dynamic> json) => _$BadgeInfo7TVFromJson(json);
}
@JsonSerializable(createToJson: false)
class BadgeInfoBTTV {
final String id;
final String name;
final String displayName;
final String providerId;
final BadgeDetailsBTTV badge;
BadgeInfoBTTV(
this.id,
this.name,
this.displayName,
this.providerId,
this.badge,
);
factory BadgeInfoBTTV.fromJson(Map<String, dynamic> json) => _$BadgeInfoBTTVFromJson(json);
}
@JsonSerializable(createToJson: false)
class BadgeDetailsBTTV {
final String description;
final String svg;
BadgeDetailsBTTV(
this.description,
this.svg,
);
factory BadgeDetailsBTTV.fromJson(Map<String, dynamic> json) => _$BadgeDetailsBTTVFromJson(json);
}

View file

@ -43,3 +43,18 @@ BadgeInfo7TV _$BadgeInfo7TVFromJson(Map<String, dynamic> json) => BadgeInfo7TV(
.toList(),
(json['users'] as List<dynamic>).map((e) => e as String).toList(),
);
BadgeInfoBTTV _$BadgeInfoBTTVFromJson(Map<String, dynamic> json) =>
BadgeInfoBTTV(
json['id'] as String,
json['name'] as String,
json['displayName'] as String,
json['providerId'] as String,
BadgeDetailsBTTV.fromJson(json['badge'] as Map<String, dynamic>),
);
BadgeDetailsBTTV _$BadgeDetailsBTTVFromJson(Map<String, dynamic> json) =>
BadgeDetailsBTTV(
json['description'] as String,
json['svg'] as String,
);

View file

@ -1,6 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:frosty/models/badges.dart';
import 'package:frosty/models/emotes.dart';
import 'package:intl/intl.dart';
@ -75,6 +76,7 @@ class IRCMessage {
required Map<String, BadgeInfoTwitch> twitchBadgeToObject,
required Map<String, List<BadgeInfoFFZ>> ffzUserToBadges,
required Map<String, List<BadgeInfo7TV>> sevenTVUserToBadges,
required Map<String, BadgeInfoBTTV> bttvUserToBadge,
RoomFFZ? ffzRoomInfo,
bool hideMessage = false,
bool zeroWidthEnabled = false,
@ -293,6 +295,26 @@ class IRCMessage {
}
}
// Add BTTV badges to span
final userBTTVBadge = bttvUserToBadge[tags['user-id']];
if (userBTTVBadge != null) {
span.add(
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Tooltip(
message: userBTTVBadge.badge.description,
preferBelow: false,
child: SvgPicture.network(
userBTTVBadge.badge.svg,
placeholderBuilder: (context) => const SizedBox(),
height: 20,
),
),
),
);
span.add(const TextSpan(text: ' '));
}
// Add 7TV badges to end of badges span
final user7TVBadges = sevenTVUserToBadges[tags['user-id']];
if (user7TVBadges != null) {

View file

@ -43,6 +43,10 @@ abstract class _ChatAssetsStoreBase with Store {
@readonly
var _userTo7TVBadges = <String, List<BadgeInfo7TV>>{};
/// The map of usernames to their BTTV badge.
@readonly
var _userToBTTVBadges = <String, BadgeInfoBTTV>{};
/// The current index of the emote menu stack.
@observable
var emoteMenuIndex = 0;
@ -100,6 +104,9 @@ abstract class _ChatAssetsStoreBase with Store {
final sevenTVBadges = await SevenTV.getBadges();
if (sevenTVBadges != null) _userTo7TVBadges = sevenTVBadges;
final bttvBadges = await BTTV.getBadges();
if (bttvBadges != null) _userToBTTVBadges = bttvBadges;
}
}

View file

@ -123,6 +123,24 @@ mixin _$ChatAssetsStore on _ChatAssetsStoreBase, Store {
});
}
final _$_userToBTTVBadgesAtom =
Atom(name: '_ChatAssetsStoreBase._userToBTTVBadges');
Map<String, BadgeInfoBTTV> get userToBTTVBadges {
_$_userToBTTVBadgesAtom.reportRead();
return super._userToBTTVBadges;
}
@override
Map<String, BadgeInfoBTTV> get _userToBTTVBadges => userToBTTVBadges;
@override
set _userToBTTVBadges(Map<String, BadgeInfoBTTV> value) {
_$_userToBTTVBadgesAtom.reportWrite(value, super._userToBTTVBadges, () {
super._userToBTTVBadges = value;
});
}
final _$emoteMenuIndexAtom =
Atom(name: '_ChatAssetsStoreBase.emoteMenuIndex');

View file

@ -37,6 +37,7 @@ class ChatMessage extends StatelessWidget {
twitchBadgeToObject: assetsStore.twitchBadgesToObject,
ffzUserToBadges: assetsStore.userToFFZBadges,
sevenTVUserToBadges: assetsStore.userTo7TVBadges,
bttvUserToBadge: assetsStore.userToBTTVBadges,
ffzRoomInfo: assetsStore.ffzRoomInfo,
zeroWidthEnabled: settingsStore.zeroWidthEnabled,
timestamp: timeStamps,
@ -63,6 +64,7 @@ class ChatMessage extends StatelessWidget {
twitchBadgeToObject: assetsStore.twitchBadgesToObject,
ffzUserToBadges: assetsStore.userToFFZBadges,
sevenTVUserToBadges: assetsStore.userTo7TVBadges,
bttvUserToBadge: assetsStore.userToBTTVBadges,
ffzRoomInfo: assetsStore.ffzRoomInfo,
hideMessage: settingsStore.hideBannedMessages,
zeroWidthEnabled: settingsStore.zeroWidthEnabled,
@ -115,6 +117,7 @@ class ChatMessage extends StatelessWidget {
twitchBadgeToObject: assetsStore.twitchBadgesToObject,
ffzUserToBadges: assetsStore.userToFFZBadges,
sevenTVUserToBadges: assetsStore.userTo7TVBadges,
bttvUserToBadge: assetsStore.userToBTTVBadges,
ffzRoomInfo: assetsStore.ffzRoomInfo,
zeroWidthEnabled: settingsStore.zeroWidthEnabled,
timestamp: timeStamps,