Update linting and formatting rules (#261)

* Add new linting rules

* Apply new linting rules

* Fix dart sdk version

* Format code to 80 lines
This commit is contained in:
Tommy 2023-04-29 11:34:28 -04:00 • committed by GitHub
parent f17cef9523
commit 3af5406f60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
74 changed files with 1049 additions and 481 deletions

View file

@ -24,7 +24,8 @@ class BadgeInfoTwitch {
this.description,
);
factory BadgeInfoTwitch.fromJson(Map<String, dynamic> json) => _$BadgeInfoTwitchFromJson(json);
factory BadgeInfoTwitch.fromJson(Map<String, dynamic> json) =>
_$BadgeInfoTwitchFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -41,7 +42,8 @@ class BadgeInfoFFZ {
this.urls,
);
factory BadgeInfoFFZ.fromJson(Map<String, dynamic> json) => _$BadgeInfoFFZFromJson(json);
factory BadgeInfoFFZ.fromJson(Map<String, dynamic> json) =>
_$BadgeInfoFFZFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -59,7 +61,8 @@ class BadgeUrlsFFZ {
this.url4x,
);
factory BadgeUrlsFFZ.fromJson(Map<String, dynamic> json) => _$BadgeUrlsFFZFromJson(json);
factory BadgeUrlsFFZ.fromJson(Map<String, dynamic> json) =>
_$BadgeUrlsFFZFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -74,7 +77,8 @@ class BadgeInfo7TV {
this.users,
);
factory BadgeInfo7TV.fromJson(Map<String, dynamic> json) => _$BadgeInfo7TVFromJson(json);
factory BadgeInfo7TV.fromJson(Map<String, dynamic> json) =>
_$BadgeInfo7TVFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -87,7 +91,8 @@ class BadgeInfoBTTV {
this.badge,
);
factory BadgeInfoBTTV.fromJson(Map<String, dynamic> json) => _$BadgeInfoBTTVFromJson(json);
factory BadgeInfoBTTV.fromJson(Map<String, dynamic> json) =>
_$BadgeInfoBTTVFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -100,7 +105,8 @@ class BadgeDetailsBTTV {
this.svg,
);
factory BadgeDetailsBTTV.fromJson(Map<String, dynamic> json) => _$BadgeDetailsBTTVFromJson(json);
factory BadgeDetailsBTTV.fromJson(Map<String, dynamic> json) =>
_$BadgeDetailsBTTVFromJson(json);
}
class ChatBadge {

View file

@ -14,7 +14,8 @@ class CategoryTwitch {
this.name,
);
factory CategoryTwitch.fromJson(Map<String, dynamic> json) => _$CategoryTwitchFromJson(json);
factory CategoryTwitch.fromJson(Map<String, dynamic> json) =>
_$CategoryTwitchFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -27,5 +28,6 @@ class CategoriesTwitch {
this.pagination,
);
factory CategoriesTwitch.fromJson(Map<String, dynamic> json) => _$CategoriesTwitchFromJson(json);
factory CategoriesTwitch.fromJson(Map<String, dynamic> json) =>
_$CategoriesTwitchFromJson(json);
}

View file

@ -15,7 +15,8 @@ class Channel {
required this.broadcasterName,
});
factory Channel.fromJson(Map<String, dynamic> json) => _$ChannelFromJson(json);
factory Channel.fromJson(Map<String, dynamic> json) =>
_$ChannelFromJson(json);
}
// Object for Twitch channel search query.
@ -35,5 +36,6 @@ class ChannelQuery {
required this.startedAt,
});
factory ChannelQuery.fromJson(Map<String, dynamic> json) => _$ChannelQueryFromJson(json);
factory ChannelQuery.fromJson(Map<String, dynamic> json) =>
_$ChannelQueryFromJson(json);
}

View file

@ -12,7 +12,8 @@ class ChatUsers {
this.chatters,
);
factory ChatUsers.fromJson(Map<String, dynamic> json) => _$ChatUsersFromJson(json);
factory ChatUsers.fromJson(Map<String, dynamic> json) =>
_$ChatUsersFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -35,5 +36,6 @@ class Chatters {
this.viewers,
);
factory Chatters.fromJson(Map<String, dynamic> json) => _$ChattersFromJson(json);
factory Chatters.fromJson(Map<String, dynamic> json) =>
_$ChattersFromJson(json);
}

View file

@ -18,7 +18,8 @@ class EmoteTwitch {
this.ownerId,
);
factory EmoteTwitch.fromJson(Map<String, dynamic> json) => _$EmoteTwitchFromJson(json);
factory EmoteTwitch.fromJson(Map<String, dynamic> json) =>
_$EmoteTwitchFromJson(json);
}
// * BTTV Emotes *
@ -32,7 +33,8 @@ class EmoteBTTV {
this.code,
);
factory EmoteBTTV.fromJson(Map<String, dynamic> json) => _$EmoteBTTVFromJson(json);
factory EmoteBTTV.fromJson(Map<String, dynamic> json) =>
_$EmoteBTTVFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -45,7 +47,8 @@ class EmoteBTTVChannel {
this.sharedEmotes,
);
factory EmoteBTTVChannel.fromJson(Map<String, dynamic> json) => _$EmoteBTTVChannelFromJson(json);
factory EmoteBTTVChannel.fromJson(Map<String, dynamic> json) =>
_$EmoteBTTVChannelFromJson(json);
}
// * FFZ Emotes *
@ -61,7 +64,8 @@ class RoomFFZ {
this.modUrls,
);
factory RoomFFZ.fromJson(Map<String, dynamic> json) => _$RoomFFZFromJson(json);
factory RoomFFZ.fromJson(Map<String, dynamic> json) =>
_$RoomFFZFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -79,7 +83,8 @@ class ImagesFFZ {
this.url4x,
);
factory ImagesFFZ.fromJson(Map<String, dynamic> json) => _$ImagesFFZFromJson(json);
factory ImagesFFZ.fromJson(Map<String, dynamic> json) =>
_$ImagesFFZFromJson(json);
}
@JsonSerializable(createToJson: false)
@ -96,7 +101,8 @@ class EmoteFFZ {
this.urls,
);
factory EmoteFFZ.fromJson(Map<String, dynamic> json) => _$EmoteFFZFromJson(json);
factory EmoteFFZ.fromJson(Map<String, dynamic> json) =>
_$EmoteFFZFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -115,7 +121,8 @@ class Emote7TV {
this.urls,
);
factory Emote7TV.fromJson(Map<String, dynamic> json) => _$Emote7TVFromJson(json);
factory Emote7TV.fromJson(Map<String, dynamic> json) =>
_$Emote7TVFromJson(json);
}
/// The common emote class.
@ -142,7 +149,8 @@ class Emote {
factory Emote.fromTwitch(EmoteTwitch emote, EmoteType type) => Emote(
name: emote.name,
zeroWidth: false,
url: 'https://static-cdn.jtvnw.net/emoticons/v2/${emote.id}/default/dark/3.0',
url:
'https://static-cdn.jtvnw.net/emoticons/v2/${emote.id}/default/dark/3.0',
type: type,
ownerId: emote.ownerId,
);

View file

@ -45,7 +45,8 @@ class IRCMessage {
if (ircMessage.message == null) {
messages.clear();
bufferedMessages.clear();
messages.add(IRCMessage.createNotice(message: 'Chat was cleared by a moderator'));
messages.add(
IRCMessage.createNotice(message: 'Chat was cleared by a moderator'));
return;
}
@ -130,7 +131,8 @@ class IRCMessage {
final span = <InlineSpan>[];
if (timestamp != TimestampType.disabled) {
final time = tags['tmi-sent-ts'] ?? DateTime.now().millisecondsSinceEpoch.toString();
final time = tags['tmi-sent-ts'] ??
DateTime.now().millisecondsSinceEpoch.toString();
final parsedTime = DateTime.fromMillisecondsSinceEpoch(int.parse(time));
if (timestamp == TimestampType.twentyFour) {
@ -165,16 +167,20 @@ class IRCMessage {
var badgeUrl = badgeInfo.url;
// Add custom FFZ mod badge if it exists.
if (badgeInfo.name == 'Moderator' && (ffzUserBadges != null || ffzRoomInfo?.modUrls != null)) {
if (badgeInfo.name == 'Moderator' &&
(ffzUserBadges != null || ffzRoomInfo?.modUrls != null)) {
// Check if mod is bot.
final botBadge = ffzUserBadges?.firstWhereOrNull((element) => element.name == 'Bot');
final botBadge = ffzUserBadges
?.firstWhereOrNull((element) => element.name == 'Bot');
// Check if user has bot badge or room has custom FFZ mod badges
if (botBadge != null) {
badgeUrl = botBadge.url;
skipBot = true;
} else if (ffzRoomInfo?.modUrls != null) {
badgeUrl = ffzRoomInfo!.modUrls?.url4x ?? ffzRoomInfo.modUrls?.url2x ?? ffzRoomInfo.modUrls!.url1x;
badgeUrl = ffzRoomInfo!.modUrls?.url4x ??
ffzRoomInfo.modUrls?.url2x ??
ffzRoomInfo.modUrls!.url1x;
}
final newBadge = ChatBadge(
@ -196,7 +202,9 @@ class IRCMessage {
// Add custom FFZ vip badge if it exists
if (badgeInfo.name == 'VIP' && ffzRoomInfo?.vipBadge != null) {
badgeUrl = ffzRoomInfo!.vipBadge?.url4x ?? ffzRoomInfo.vipBadge?.url2x ?? ffzRoomInfo.vipBadge!.url1x;
badgeUrl = ffzRoomInfo!.vipBadge?.url4x ??
ffzRoomInfo.vipBadge?.url2x ??
ffzRoomInfo.vipBadge!.url1x;
}
final newBadge = ChatBadge(
@ -273,14 +281,23 @@ class IRCMessage {
}
}
var color = Color(int.parse((tags['color'] ?? '#868686').replaceFirst('#', '0xFF')));
var color = Color(
int.parse((tags['color'] ?? '#868686').replaceFirst('#', '0xFF')));
if (useReadableColors) {
final hsl = HSLColor.fromColor(color);
if (isLightTheme == true) {
if (hsl.lightness >= 0.5) color = hsl.withLightness(hsl.lightness + ((0 - hsl.lightness) * 0.5)).toColor();
if (hsl.lightness >= 0.5) {
color = hsl
.withLightness(hsl.lightness + ((0 - hsl.lightness) * 0.5))
.toColor();
}
} else {
if (hsl.lightness <= 0.5) color = hsl.withLightness(hsl.lightness + ((1 - hsl.lightness) * 0.5)).toColor();
if (hsl.lightness <= 0.5) {
color = hsl
.withLightness(hsl.lightness + ((1 - hsl.lightness) * 0.5))
.toColor();
}
}
}
@ -288,7 +305,9 @@ class IRCMessage {
final displayName = tags['display-name']!;
span.add(
TextSpan(
text: regexEnglish.hasMatch(displayName) ? displayName : '$displayName ($user)',
text: regexEnglish.hasMatch(displayName)
? displayName
: '$displayName ($user)',
style: TextStyle(
color: color,
fontWeight: FontWeight.bold,
@ -301,13 +320,16 @@ class IRCMessage {
if (action == false) span.add(const TextSpan(text: ':'));
// Italicize the text if it was called with an IRC Action (e.g., "/me").
final textStyle = action == true ? const TextStyle(fontStyle: FontStyle.italic) : style;
final textStyle =
action == true ? const TextStyle(fontStyle: FontStyle.italic) : style;
if (!showMessage) {
span.add(const TextSpan(text: ' <message deleted>'));
} else {
// Check if the message is a reply. If it is, remove the reply username (first word) from the message.
final words = tags.containsKey('reply-parent-display-name') ? split?.sublist(1) : split;
final words = tags.containsKey('reply-parent-display-name')
? split?.sublist(1)
: split;
// Add the message and any emotes to the span.
if (words != null) {
@ -334,7 +356,8 @@ class IRCMessage {
while (nextEmote != null && nextEmote.zeroWidth && index != 0) {
emoteStack.add(nextEmote);
index--;
nextEmote = emoteToObject[words[index]] ?? localEmotes?[words[index]];
nextEmote =
emoteToObject[words[index]] ?? localEmotes?[words[index]];
}
// If there's one more emote thats NOT zero-width, add it to the base of the stack.
@ -354,15 +377,20 @@ class IRCMessage {
...emoteStack.reversed.map(
(emote) => FrostyCachedNetworkImage(
imageUrl: emote.url,
height: emote.height != null ? emote.height! * emoteScale : emoteSize,
width: emote.width != null ? emote.width! * emoteScale : emoteSize,
height: emote.height != null
? emote.height! * emoteScale
: emoteSize,
width: emote.width != null
? emote.width! * emoteScale
: emoteSize,
useFade: false,
),
)
];
// Create the message for the tooltip
final message = emoteStack.reversed.map((emote) => '${emote.name} - ${emoteType[emote.type.index]}');
final message = emoteStack.reversed.map(
(emote) => '${emote.name} - ${emoteType[emote.type.index]}');
localSpan.add(
WidgetSpan(
alignment: PlaceholderAlignment.middle,
@ -399,7 +427,9 @@ class IRCMessage {
style: const TextStyle(color: Colors.white),
),
Text(
nextWordIsEmoji ? message.join(', ') : message.skip(1).join(', '),
nextWordIsEmoji
? message.join(', ')
: message.skip(1).join(', '),
style: const TextStyle(color: Colors.white),
),
],
@ -419,22 +449,32 @@ class IRCMessage {
// If the next word is neither an emote or emoji, add it as a text span.
if (nextEmote == null && !nextWordIsEmoji) {
localSpan.add(const TextSpan(text: ' '));
localSpan.add(_createTextSpan(text: words[index], style: textStyle, launchExternal: launchExternal));
localSpan.add(_createTextSpan(
text: words[index],
style: textStyle,
launchExternal: launchExternal));
}
} else {
localSpan.add(
_createEmoteSpan(
emote: emote,
height: emote.height != null ? emote.height! * emoteScale : emoteSize,
height: emote.height != null
? emote.height! * emoteScale
: emoteSize,
width: emote.width != null ? emote.width! * emoteScale : null,
),
);
}
} else {
if (regexEmoji.hasMatch(word)) {
localSpan.add(_createEmojiSpan(emoji: word, style: textStyle?.copyWith(fontSize: emoteSize - 5)));
localSpan.add(_createEmojiSpan(
emoji: word,
style: textStyle?.copyWith(fontSize: emoteSize - 5)));
} else {
localSpan.add(_createTextSpan(text: word, style: textStyle, launchExternal: launchExternal));
localSpan.add(_createTextSpan(
text: word,
style: textStyle,
launchExternal: launchExternal));
}
}
@ -576,16 +616,20 @@ class IRCMessage {
);
}
static TextSpan _createTextSpan({required String text, required bool launchExternal, TextStyle? style}) {
static TextSpan _createTextSpan(
{required String text, required bool launchExternal, TextStyle? style}) {
if (text.startsWith('@')) {
return TextSpan(text: text, style: style?.copyWith(fontWeight: FontWeight.bold));
return TextSpan(
text: text, style: style?.copyWith(fontWeight: FontWeight.bold));
} else if (RegExp(r'https?:\/\/').hasMatch(text)) {
return TextSpan(
text: text,
style: style?.copyWith(color: Colors.blue),
recognizer: TapGestureRecognizer()
..onTap = () => launchUrl(Uri.parse(text),
mode: launchExternal ? LaunchMode.externalApplication : LaunchMode.inAppWebView),
mode: launchExternal
? LaunchMode.externalApplication
: LaunchMode.inAppWebView),
);
} else {
return TextSpan(text: text, style: style);
@ -607,7 +651,8 @@ class IRCMessage {
// Get the tags substring and escape characters.
// IRC messages escape spaces with \s.
final tags = whole.substring(1, tagAndIrcMessageDivider).replaceAll('\\s', ' ');
final tags =
whole.substring(1, tagAndIrcMessageDivider).replaceAll('\\s', ' ');
// Next, parse and map the tags.
final mappedTags = <String, String>{};
@ -634,15 +679,18 @@ class IRCMessage {
// If the username exists, set it.
// tmi.twitch.tv means the message was sent by Twitch rather than a user, so will be irrelevant.
final String? user =
splitMessage[0] == 'tmi.twitch.tv' ? null : splitMessage[0].substring(0, splitMessage[0].indexOf('!'));
final String? user = splitMessage[0] == 'tmi.twitch.tv'
? null
: splitMessage[0].substring(0, splitMessage[0].indexOf('!'));
// If there is an associated message, set it.
//
// Also remove any "INVALID/UNDEFINED" Unicode characters.
// Rendering this character on iOS shows a question mark inside a square.
// This character is used by some clients to bypass restrictions on repeating message.
var message = splitMessage.length > 3 ? splitMessage.sublist(3).join(' ').substring(1) : null;
var message = splitMessage.length > 3
? splitMessage.sublist(3).join(' ').substring(1)
: null;
// Now process any Twitch emotes contained in the message tags.
// The map containing emotes from the user's tags to their URL.
@ -656,14 +704,16 @@ class IRCMessage {
for (final emoteIdAndPosition in emotes) {
final indexBetweenIdAndPositions = emoteIdAndPosition.indexOf(':');
final emoteId = emoteIdAndPosition.substring(0, indexBetweenIdAndPositions);
final emoteId =
emoteIdAndPosition.substring(0, indexBetweenIdAndPositions);
// Parse the range in order to extract the associated word.
// If there are more than one indices, use the first one.
// Else, use the one provided indices.
final String range;
if (emoteIdAndPosition.contains(',')) {
range = emoteIdAndPosition.substring(indexBetweenIdAndPositions + 1, emoteIdAndPosition.indexOf(','));
range = emoteIdAndPosition.substring(
indexBetweenIdAndPositions + 1, emoteIdAndPosition.indexOf(','));
} else {
range = emoteIdAndPosition.substring(indexBetweenIdAndPositions + 1);
}
@ -679,7 +729,8 @@ class IRCMessage {
localEmotes[emoteWord] = Emote(
name: emoteWord,
zeroWidth: false,
url: 'https://static-cdn.jtvnw.net/emoticons/v2/$emoteId/default/dark/3.0',
url:
'https://static-cdn.jtvnw.net/emoticons/v2/$emoteId/default/dark/3.0',
type: EmoteType.twitchSub,
);
}
@ -696,7 +747,9 @@ class IRCMessage {
}
// Check if the message mentions the logged-in user
if (userLogin != null) mention = message.toLowerCase().contains(userLogin);
if (userLogin != null) {
mention = message.toLowerCase().contains(userLogin);
}
// Escape the message
message = message
@ -725,7 +778,10 @@ class IRCMessage {
}
}
if (wordBuffer.isNotEmpty) split.addAll(wordBuffer.toString().split(' ').where((element) => element != ''));
if (wordBuffer.isNotEmpty) {
split.addAll(
wordBuffer.toString().split(' ').where((element) => element != ''));
}
if (emojiBuffer.isNotEmpty) split.add(emojiBuffer.toString());
}

View file

@ -27,7 +27,8 @@ class StreamTwitch {
this.thumbnailUrl,
);
factory StreamTwitch.fromJson(Map<String, dynamic> json) => _$StreamTwitchFromJson(json);
factory StreamTwitch.fromJson(Map<String, dynamic> json) =>
_$StreamTwitchFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -40,5 +41,6 @@ class StreamsTwitch {
this.pagination,
);
factory StreamsTwitch.fromJson(Map<String, dynamic> json) => _$StreamsTwitchFromJson(json);
factory StreamsTwitch.fromJson(Map<String, dynamic> json) =>
_$StreamsTwitchFromJson(json);
}

View file

@ -17,7 +17,8 @@ class UserTwitch {
this.profileImageUrl,
);
factory UserTwitch.fromJson(Map<String, dynamic> json) => _$UserTwitchFromJson(json);
factory UserTwitch.fromJson(Map<String, dynamic> json) =>
_$UserTwitchFromJson(json);
}
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
@ -32,5 +33,6 @@ class UserBlockedTwitch {
this.displayName,
);
factory UserBlockedTwitch.fromJson(Map<String, dynamic> json) => _$UserBlockedTwitchFromJson(json);
factory UserBlockedTwitch.fromJson(Map<String, dynamic> json) =>
_$UserBlockedTwitchFromJson(json);
}