Add top games request, tweak models (#40)

[skip ci]
This commit is contained in:
tommyxchow 2021-11-18 22:13:01 -05:00
parent 11db07a7d2
commit 051b8678e5
7 changed files with 193 additions and 45 deletions

View file

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:frosty/constants.dart';
import 'package:frosty/models/badges.dart';
import 'package:frosty/models/category.dart';
import 'package:frosty/models/channel.dart';
import 'package:frosty/models/emotes.dart';
import 'package:frosty/models/stream.dart';
@ -229,4 +230,26 @@ class Twitch {
return [];
}
}
/// Returns a map containing top 20 categories/games and a cursor for further requests.
static Future<CategoriesTwitch?> getTopGames({required Map<String, String>? headers, required String? cursor}) async {
final Uri uri;
if (cursor == null) {
uri = Uri.parse('https://api.twitch.tv/helix/games/top');
} else {
uri = Uri.parse('https://api.twitch.tv/helix/games/top?after=$cursor');
}
final response = await http.get(uri, headers: headers);
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
final data = decoded['data'] as List;
return CategoriesTwitch(data.map((category) => CategoryTwitch.fromJson(category)).toList(), decoded['pagination']['cursor']);
} else {
debugPrint('Failed to update top games');
}
}
}

28
lib/models/category.dart Normal file
View file

@ -0,0 +1,28 @@
import 'package:json_annotation/json_annotation.dart';
part 'category.g.dart';
@JsonSerializable(createToJson: false, fieldRename: FieldRename.snake)
class CategoryTwitch {
final String boxArtUrl;
final String id;
final String name;
const CategoryTwitch(
this.boxArtUrl,
this.id,
this.name,
);
factory CategoryTwitch.fromJson(Map<String, dynamic> json) => _$CategoryTwitchFromJson(json);
}
class CategoriesTwitch {
final List<CategoryTwitch> data;
final String cursor;
const CategoriesTwitch(
this.data,
this.cursor,
);
}

View file

@ -0,0 +1,14 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'category.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CategoryTwitch _$CategoryTwitchFromJson(Map<String, dynamic> json) =>
CategoryTwitch(
json['box_art_url'] as String,
json['id'] as String,
json['name'] as String,
);

View file

@ -12,7 +12,11 @@ class ImagesTwitch {
@JsonKey(name: 'url_4x')
final String url4x;
const ImagesTwitch(this.url1x, this.url2x, this.url4x);
const ImagesTwitch(
this.url1x,
this.url2x,
this.url4x,
);
factory ImagesTwitch.fromJson(Map<String, dynamic> json) => _$ImagesTwitchFromJson(json);
}
@ -29,7 +33,17 @@ class EmoteTwitch {
final List<String> scale;
final List<String> themeMode;
const EmoteTwitch(this.id, this.name, this.images, this.tier, this.emoteType, this.emoteSetId, this.format, this.scale, this.themeMode);
const EmoteTwitch(
this.id,
this.name,
this.images,
this.tier,
this.emoteType,
this.emoteSetId,
this.format,
this.scale,
this.themeMode,
);
factory EmoteTwitch.fromJson(Map<String, dynamic> json) => _$EmoteTwitchFromJson(json);
}
@ -42,7 +56,12 @@ class EmoteBTTVGlobal {
final String imageType;
final String userId;
const EmoteBTTVGlobal(this.id, this.code, this.imageType, this.userId);
const EmoteBTTVGlobal(
this.id,
this.code,
this.imageType,
this.userId,
);
factory EmoteBTTVGlobal.fromJson(Map<String, dynamic> json) => _$EmoteBTTVGlobalFromJson(json);
}
@ -54,7 +73,12 @@ class UserBTTV {
final String displayName;
final String providerId;
const UserBTTV(this.id, this.name, this.displayName, this.providerId);
const UserBTTV(
this.id,
this.name,
this.displayName,
this.providerId,
);
factory UserBTTV.fromJson(Map<String, dynamic> json) => _$UserBTTVFromJson(json);
}
@ -66,7 +90,12 @@ class EmoteBTTVShared {
final String imageType;
final UserBTTV user;
const EmoteBTTVShared(this.id, this.code, this.imageType, this.user);
const EmoteBTTVShared(
this.id,
this.code,
this.imageType,
this.user,
);
factory EmoteBTTVShared.fromJson(Map<String, dynamic> json) => _$EmoteBTTVSharedFromJson(json);
}
@ -78,7 +107,12 @@ class EmoteBTTVChannel {
final List<EmoteBTTVGlobal> channelEmotes;
final List<EmoteBTTVShared> sharedEmotes;
const EmoteBTTVChannel(this.id, this.bots, this.channelEmotes, this.sharedEmotes);
const EmoteBTTVChannel(
this.id,
this.bots,
this.channelEmotes,
this.sharedEmotes,
);
factory EmoteBTTVChannel.fromJson(Map<String, dynamic> json) => _$EmoteBTTVChannelFromJson(json);
}
@ -90,7 +124,11 @@ class UserFFZ {
final String name;
final String displayName;
const UserFFZ(this.id, this.name, this.displayName);
const UserFFZ(
this.id,
this.name,
this.displayName,
);
factory UserFFZ.fromJson(Map<String, dynamic> json) => _$UserFFZFromJson(json);
}
@ -104,7 +142,11 @@ class ImagesFFZ {
@JsonKey(name: '4x')
final String? url4x;
const ImagesFFZ(this.url1x, this.url2x, this.url4x);
const ImagesFFZ(
this.url1x,
this.url2x,
this.url4x,
);
factory ImagesFFZ.fromJson(Map<String, dynamic> json) => _$ImagesFFZFromJson(json);
}
@ -117,7 +159,13 @@ class EmoteFFZ {
final ImagesFFZ images;
final String imageType;
const EmoteFFZ(this.id, this.user, this.code, this.images, this.imageType);
const EmoteFFZ(
this.id,
this.user,
this.code,
this.images,
this.imageType,
);
factory EmoteFFZ.fromJson(Map<String, dynamic> json) => _$EmoteFFZFromJson(json);
}
@ -135,7 +183,15 @@ class Role7TV {
@JsonKey(name: 'default')
final bool? defaults;
Role7TV(this.id, this.name, this.position, this.color, this.allowed, this.denied, this.defaults);
const Role7TV(
this.id,
this.name,
this.position,
this.color,
this.allowed,
this.denied,
this.defaults,
);
factory Role7TV.fromJson(Map<String, dynamic> json) => _$Role7TVFromJson(json);
}
@ -148,7 +204,13 @@ class Owner7TV {
final String displayName;
final Role7TV role;
Owner7TV(this.id, this.twitchId, this.login, this.displayName, this.role);
const Owner7TV(
this.id,
this.twitchId,
this.login,
this.displayName,
this.role,
);
factory Owner7TV.fromJson(Map<String, dynamic> json) => _$Owner7TVFromJson(json);
}
@ -167,7 +229,19 @@ class Emote7TV {
final List<int> height;
final List<List<String>> urls;
Emote7TV(this.id, this.name, this.owner, this.visibility, this.visibilitySimple, this.mime, this.status, this.tags, this.width, this.height, this.urls);
const Emote7TV(
this.id,
this.name,
this.owner,
this.visibility,
this.visibilitySimple,
this.mime,
this.status,
this.tags,
this.width,
this.height,
this.urls,
);
factory Emote7TV.fromJson(Map<String, dynamic> json) => _$Emote7TVFromJson(json);
}

View file

@ -20,22 +20,22 @@ class Stream {
final List<String>? tagIds;
final bool isMature;
const Stream({
required this.id,
required this.userId,
required this.userLogin,
required this.userName,
required this.gameId,
required this.gameName,
required this.type,
required this.title,
required this.viewerCount,
required this.startedAt,
required this.language,
required this.thumbnailUrl,
required this.tagIds,
required this.isMature,
});
const Stream(
this.id,
this.userId,
this.userLogin,
this.userName,
this.gameId,
this.gameName,
this.type,
this.title,
this.viewerCount,
this.startedAt,
this.language,
this.thumbnailUrl,
this.tagIds,
this.isMature,
);
factory Stream.fromJson(Map<String, dynamic> json) => _$StreamFromJson(json);
}

View file

@ -7,19 +7,18 @@ part of 'stream.dart';
// **************************************************************************
Stream _$StreamFromJson(Map<String, dynamic> json) => Stream(
id: json['id'] as String,
userId: json['user_id'] as String,
userLogin: json['user_login'] as String,
userName: json['user_name'] as String,
gameId: json['game_id'] as String,
gameName: json['game_name'] as String,
type: json['type'] as String,
title: json['title'] as String,
viewerCount: json['viewer_count'] as int,
startedAt: json['started_at'] as String,
language: json['language'] as String,
thumbnailUrl: json['thumbnail_url'] as String,
tagIds:
(json['tag_ids'] as List<dynamic>?)?.map((e) => e as String).toList(),
isMature: json['is_mature'] as bool,
json['id'] as String,
json['user_id'] as String,
json['user_login'] as String,
json['user_name'] as String,
json['game_id'] as String,
json['game_name'] as String,
json['type'] as String,
json['title'] as String,
json['viewer_count'] as int,
json['started_at'] as String,
json['language'] as String,
json['thumbnail_url'] as String,
(json['tag_ids'] as List<dynamic>?)?.map((e) => e as String).toList(),
json['is_mature'] as bool,
);

View file

@ -16,8 +16,18 @@ class UserTwitch {
final int viewCount;
final String createdAt;
const UserTwitch(this.id, this.login, this.displayName, this.type, this.broadcasterType, this.description, this.profileImageUrl, this.offlineImageUrl,
this.viewCount, this.createdAt);
const UserTwitch(
this.id,
this.login,
this.displayName,
this.type,
this.broadcasterType,
this.description,
this.profileImageUrl,
this.offlineImageUrl,
this.viewCount,
this.createdAt,
);
factory UserTwitch.fromJson(Map<String, dynamic> json) => _$UserTwitchFromJson(json);
}