Add some documentation
This commit is contained in:
parent
83a3b55b08
commit
1a53101047
14 changed files with 68 additions and 61 deletions
|
|
@ -4,10 +4,11 @@ import 'package:frosty/models/badges.dart';
|
|||
import 'package:frosty/models/emotes.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
/// The BTTV service for making API calls.
|
||||
class BTTVApi {
|
||||
final Client _client;
|
||||
|
||||
BTTVApi(this._client);
|
||||
const BTTVApi(this._client);
|
||||
|
||||
/// Returns a map of global BTTV emotes to their URL.
|
||||
Future<List<Emote>> getEmotesGlobal() async {
|
||||
|
|
@ -43,6 +44,7 @@ class BTTVApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of username to their BTTV badge.
|
||||
Future<Map<String, Badge>> getBadges() async {
|
||||
final url = Uri.parse('https://api.betterttv.net/3/cached/badges');
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ import 'package:frosty/models/emotes.dart';
|
|||
import 'package:http/http.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
/// The FFZ service for making API calls.
|
||||
class FFZApi {
|
||||
final Client _client;
|
||||
|
||||
FFZApi(this._client);
|
||||
const FFZApi(this._client);
|
||||
|
||||
/// Returns a map of global FFZ emotes to their URL.
|
||||
Future<List<Emote>> getEmotesGlobal() async {
|
||||
|
|
@ -49,6 +50,7 @@ class FFZApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of badges user IDs to a list of their FFZ badges.
|
||||
Future<Map<String, List<Badge>>> getBadges() async {
|
||||
final url = Uri.parse('https://api.frankerfacez.com/v1/badges/ids');
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ import 'package:frosty/models/badges.dart';
|
|||
import 'package:frosty/models/emotes.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
// A class for general requests.
|
||||
class SevenTVAPI {
|
||||
/// The 7TV service for making API calls.
|
||||
class SevenTVApi {
|
||||
final Client _client;
|
||||
|
||||
SevenTVAPI(this._client);
|
||||
const SevenTVApi(this._client);
|
||||
|
||||
/// Returns a map of global 7TV emotes to their URL.
|
||||
Future<List<Emote>> getEmotesGlobal() async {
|
||||
|
|
@ -40,6 +40,7 @@ class SevenTVAPI {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of user IDS to a list of their 7TV badges.
|
||||
Future<Map<String, List<Badge>>> getBadges() async {
|
||||
final url = Uri.parse('https://api.7tv.app/v2/badges?user_identifier=twitch_id');
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,14 @@ import 'package:frosty/models/stream.dart';
|
|||
import 'package:frosty/models/user.dart';
|
||||
import 'package:http/http.dart';
|
||||
|
||||
/// The Twitch service for making API calls.
|
||||
class TwitchApi {
|
||||
final Client _client;
|
||||
|
||||
TwitchApi(this._client);
|
||||
const TwitchApi(this._client);
|
||||
|
||||
Future<List<Emote>> getEmotesGlobal({required Map<String, String>? headers}) async {
|
||||
/// Returns a list of all Twitch global emotes.
|
||||
Future<List<Emote>> getEmotesGlobal({required Map<String, String> headers}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/chat/emotes/global');
|
||||
final response = await _client.get(url, headers: headers);
|
||||
|
||||
|
|
@ -30,10 +32,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of a channel's Twitch emotes to their URL.
|
||||
/// Returns a list of a channel's Twitch emotes given their [id].
|
||||
Future<List<Emote>> getEmotesChannel({
|
||||
required String id,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/chat/emotes?broadcaster_id=$id');
|
||||
|
||||
|
|
@ -48,10 +50,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of a channel's Twitch emotes to their URL.
|
||||
/// Returns a list of Twitch emotes under the provided [setId].
|
||||
Future<List<Emote>> getEmotesSets({
|
||||
required String setId,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/chat/emotes/set?emote_set_id=$setId');
|
||||
|
||||
|
|
@ -76,7 +78,7 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of global Twitch badges to their URL.
|
||||
/// Returns a map of global Twitch badges to their [Emote] object.
|
||||
Future<Map<String, Badge>> getBadgesGlobal() async {
|
||||
final url = Uri.parse('https://badges.twitch.tv/v1/badges/global/display');
|
||||
|
||||
|
|
@ -93,7 +95,7 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map of a channel's Twitch badges to their URL.
|
||||
/// Returns a map of a channel's Twitch badges to their [Emote] object.
|
||||
Future<Map<String, Badge>> getBadgesChannel({required String id}) async {
|
||||
final url = Uri.parse('https://badges.twitch.tv/v1/badges/channels/$id/display');
|
||||
|
||||
|
|
@ -110,8 +112,8 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the user's info given their token (headers)
|
||||
Future<UserTwitch> getUserInfo({required Map<String, String>? headers}) async {
|
||||
/// Returns the user's info given their token through [headers].
|
||||
Future<UserTwitch> getUserInfo({required Map<String, String> headers}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/users');
|
||||
|
||||
final response = await _client.get(url, headers: headers);
|
||||
|
|
@ -145,7 +147,7 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the validity of the given token
|
||||
/// Returns a bool indicating the validity of the given token.
|
||||
Future<bool> validateToken({required String token}) async {
|
||||
final url = Uri.parse('https://id.twitch.tv/oauth2/validate');
|
||||
|
||||
|
|
@ -159,9 +161,9 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map containing top 20 streams and a cursor for further requests.
|
||||
/// Returns a [StreamsTwitch] object that contains the top 20 streams and a cursor for further requests.
|
||||
Future<StreamsTwitch> getTopStreams({
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(cursor == null ? 'https://api.twitch.tv/helix/streams' : 'https://api.twitch.tv/helix/streams?after=$cursor');
|
||||
|
|
@ -175,10 +177,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a map with the given user's top 20 followed streams and a cursor for further requests.
|
||||
/// Returns a [StreamsTwitch] object that contains the given user ID's top 20 followed streams and a cursor for further requests.
|
||||
Future<StreamsTwitch> getFollowedStreams({
|
||||
required String id,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(cursor == null
|
||||
|
|
@ -194,10 +196,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the list of streams under the given game/category ID.
|
||||
/// Returns a [StreamsTwitch] object that contains the list of streams under the given game/category ID.
|
||||
Future<StreamsTwitch> getStreamsUnderCategory({
|
||||
required String gameId,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(
|
||||
|
|
@ -212,10 +214,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the stream info given the user login.
|
||||
/// Returns a [StreamTwitch] object containing the stream info associated with the given [userLogin].
|
||||
Future<StreamTwitch> getStream({
|
||||
required String userLogin,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final uri = Uri.parse('https://api.twitch.tv/helix/streams?user_login=$userLogin');
|
||||
|
||||
|
|
@ -234,11 +236,11 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a user's info given their login name.
|
||||
/// Returns a [UserTwitch] object containing the user info associated with the given [userLogin].
|
||||
Future<UserTwitch> getUser({
|
||||
String? userLogin,
|
||||
String? id,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final url = Uri.parse(id != null ? 'https://api.twitch.tv/helix/users?id=$id' : 'https://api.twitch.tv/helix/users?login=$userLogin');
|
||||
|
||||
|
|
@ -258,10 +260,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a channels's info associated with the given ID.
|
||||
/// Returns a [Channel] object containing a channels's info associated with the given [userId].
|
||||
Future<Channel> getChannel({
|
||||
required String userId,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/channels?broadcaster_id=$userId');
|
||||
|
||||
|
|
@ -280,10 +282,10 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a list of channel query objects closest matching the given query string.
|
||||
/// Returns a list of [ChannelQuery] objects closest matching the given [query].
|
||||
Future<List<ChannelQuery>> searchChannels({
|
||||
required String query,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final url = Uri.parse('https://api.twitch.tv/helix/search/channels?first=8&query=$query');
|
||||
|
||||
|
|
@ -297,9 +299,9 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the next top 20 categories/games and a cursor for further requests.
|
||||
/// Returns a [CategoriesTwitch] object containing the next top 20 categories/games and a cursor for further requests.
|
||||
Future<CategoriesTwitch> getTopCategories({
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(cursor == null ? 'https://api.twitch.tv/helix/games/top' : 'https://api.twitch.tv/helix/games/top?after=$cursor');
|
||||
|
|
@ -313,8 +315,12 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns up to 20 categories/games closest matching the [query] and a cursor for further requests.
|
||||
Future<CategoriesTwitch> searchCategories({required Map<String, String>? headers, required String query, String? cursor}) async {
|
||||
/// Returns a [CategoriesTwitch] containing up to 20 categories/games closest matching the [query] and a cursor for further requests.
|
||||
Future<CategoriesTwitch> searchCategories({
|
||||
required Map<String, String> headers,
|
||||
required String query,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(cursor == null
|
||||
? 'https://api.twitch.tv/helix/search/categories?first=8&query=$query'
|
||||
: 'https://api.twitch.tv/helix/search/categories?first=8&query=$query&after=$cursor');
|
||||
|
|
@ -329,8 +335,11 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the sub count for a user.
|
||||
Future<int> getSubscriberCount({required String userId, required Map<String, String>? headers}) async {
|
||||
/// Returns the sub count associated with the given [userId].
|
||||
Future<int> getSubscriberCount({
|
||||
required String userId,
|
||||
required Map<String, String> headers,
|
||||
}) async {
|
||||
final uri = Uri.parse('https://api.twitch.tv/helix/subscriptions?broadcaster_id=$userId');
|
||||
|
||||
final response = await _client.get(uri, headers: headers);
|
||||
|
|
@ -343,6 +352,7 @@ class TwitchApi {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a [ChatUsers] object containing the names of chatters in the given [userLogin]'s chat.
|
||||
Future<ChatUsers> getChatters({required String userLogin}) async {
|
||||
final uri = Uri.parse('https://tmi.twitch.tv/group/user/$userLogin/chatters');
|
||||
|
||||
|
|
@ -359,7 +369,7 @@ class TwitchApi {
|
|||
/// Returns a user's list of blocked users given their id.
|
||||
Future<List<UserBlockedTwitch>> getUserBlockedList({
|
||||
required String id,
|
||||
required Map<String, String>? headers,
|
||||
required Map<String, String> headers,
|
||||
String? cursor,
|
||||
}) async {
|
||||
final url = Uri.parse(cursor == null
|
||||
|
|
|
|||
|
|
@ -39,11 +39,13 @@ Future<void> main() async {
|
|||
await SentryFlutter.init((options) => options.tracesSampleRate = sampleRate);
|
||||
}
|
||||
|
||||
/// Initialize API services with a common client.
|
||||
/// This will prevent every request from creating a new client instance.
|
||||
final client = Client();
|
||||
final twitchApiService = TwitchApi(client);
|
||||
final bttvApiService = BTTVApi(client);
|
||||
final ffzApiService = FFZApi(client);
|
||||
final sevenTvApiService = SevenTVAPI(client);
|
||||
final sevenTvApiService = SevenTVApi(client);
|
||||
|
||||
// Create and initialize the authentication store
|
||||
final authStore = AuthStore(twitchApi: twitchApiService);
|
||||
|
|
@ -57,7 +59,7 @@ Future<void> main() async {
|
|||
Provider<TwitchApi>(create: (_) => twitchApiService),
|
||||
Provider<BTTVApi>(create: (_) => bttvApiService),
|
||||
Provider<FFZApi>(create: (_) => ffzApiService),
|
||||
Provider<SevenTVAPI>(create: (_) => sevenTvApiService),
|
||||
Provider<SevenTVApi>(create: (_) => sevenTvApiService),
|
||||
],
|
||||
child: const MyApp(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -83,10 +83,10 @@ class IRCMessage {
|
|||
required ChatAssetsStore assetsStore,
|
||||
required double badgeHeight,
|
||||
required double emoteHeight,
|
||||
required bool isLightTheme,
|
||||
bool showMessage = true,
|
||||
bool useZeroWidth = false,
|
||||
bool useReadableColors = false,
|
||||
bool? isLightTheme,
|
||||
TimestampType timestamp = TimestampType.disabled,
|
||||
}) {
|
||||
final emoteToObject = assetsStore.emoteToObject;
|
||||
|
|
@ -267,9 +267,7 @@ class IRCMessage {
|
|||
);
|
||||
|
||||
// Add the colon separator between the username and their message to the span.
|
||||
if (action == false) {
|
||||
span.add(const TextSpan(text: ':'));
|
||||
}
|
||||
if (action == false) span.add(const TextSpan(text: ':'));
|
||||
|
||||
// Italicize the text it was called with an IRC Action i.e., "/me".
|
||||
final textStyle = action == true ? const TextStyle(fontStyle: FontStyle.italic) : style;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:frosty/models/irc_message.dart';
|
||||
import 'package:frosty/models/irc.dart';
|
||||
|
||||
class ChatModes extends StatelessWidget {
|
||||
final ROOMSTATE roomState;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:frosty/models/irc_message.dart';
|
||||
import 'package:frosty/models/irc.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_assets_store.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ abstract class _ChatAssetsStoreBase with Store {
|
|||
final TwitchApi twitchApi;
|
||||
final BTTVApi bttvApi;
|
||||
final FFZApi ffzApi;
|
||||
final SevenTVAPI sevenTvApi;
|
||||
final SevenTVApi sevenTvApi;
|
||||
|
||||
/// Contains any custom FFZ mod and vip badges for the channel.
|
||||
RoomFFZ? ffzRoomInfo;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'dart:io';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:frosty/api/twitch_api.dart';
|
||||
import 'package:frosty/models/chatters.dart';
|
||||
import 'package:frosty/models/irc_message.dart';
|
||||
import 'package:frosty/models/irc.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'chat_details_store.g.dart';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:flutter/scheduler.dart';
|
|||
import 'package:frosty/core/auth/auth_store.dart';
|
||||
import 'package:frosty/models/badges.dart';
|
||||
import 'package:frosty/models/emotes.dart';
|
||||
import 'package:frosty/models/irc_message.dart';
|
||||
import 'package:frosty/models/irc.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_assets_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_details_store.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
|
|
|
|||
|
|
@ -10,14 +10,9 @@ import 'package:frosty/screens/settings/settings.dart';
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
class VideoChat extends StatefulWidget {
|
||||
final String displayName;
|
||||
final ChatStore chatStore;
|
||||
|
||||
const VideoChat({
|
||||
Key? key,
|
||||
required this.displayName,
|
||||
required this.chatStore,
|
||||
}) : super(key: key);
|
||||
const VideoChat({Key? key, required this.chatStore}) : super(key: key);
|
||||
|
||||
@override
|
||||
_VideoChatState createState() => _VideoChatState();
|
||||
|
|
@ -47,7 +42,7 @@ class _VideoChatState extends State<VideoChat> {
|
|||
|
||||
final appBar = AppBar(
|
||||
title: Text(
|
||||
widget.displayName,
|
||||
chatStore.displayName,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
actions: [
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
displayName: channelInfo.broadcasterName,
|
||||
chatStore: ChatStore(
|
||||
channelName: channelInfo.broadcasterLogin,
|
||||
channelId: channelInfo.broadcasterId,
|
||||
|
|
@ -45,7 +44,7 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTvApi: context.read<SevenTVAPI>(),
|
||||
sevenTvApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
auth: searchStore.authStore,
|
||||
settings: context.read<SettingsStore>(),
|
||||
|
|
@ -110,7 +109,6 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
displayName: channel.displayName,
|
||||
chatStore: ChatStore(
|
||||
channelName: channel.broadcasterLogin,
|
||||
channelId: channel.id,
|
||||
|
|
@ -122,7 +120,7 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTvApi: context.read<SevenTVAPI>(),
|
||||
sevenTvApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
auth: searchStore.authStore,
|
||||
settings: context.read<SettingsStore>(),
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ class StreamCard extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
displayName: streamInfo.userName,
|
||||
chatStore: ChatStore(
|
||||
channelName: streamInfo.userLogin,
|
||||
channelId: streamInfo.userId,
|
||||
|
|
@ -55,7 +54,7 @@ class StreamCard extends StatelessWidget {
|
|||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTvApi: context.read<SevenTVAPI>(),
|
||||
sevenTvApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue