parent
11db07a7d2
commit
051b8678e5
7 changed files with 193 additions and 45 deletions
|
|
@ -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
28
lib/models/category.dart
Normal 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,
|
||||
);
|
||||
}
|
||||
14
lib/models/category.g.dart
Normal file
14
lib/models/category.g.dart
Normal 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,
|
||||
);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue