Refactor channel list store

This commit is contained in:
Tommy Chow 2021-10-03 22:14:02 -04:00
parent 14b7aa9662
commit ca482ceb05
2 changed files with 55 additions and 187 deletions

View file

@ -1,9 +1,6 @@
import 'package:frosty/api/twitch_api.dart';
import 'package:mobx/mobx.dart';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:frosty/constants.dart';
import 'package:frosty/stores/auth_store.dart';
import 'package:http/http.dart' as http;
import 'package:frosty/models/channel.dart';
part 'channel_list_store.g.dart';
@ -17,140 +14,81 @@ abstract class _ChannelListBase with Store {
@observable
ObservableList<Channel> followedChannels = ObservableList<Channel>();
@observable
bool isLoading = false;
@observable
String? topChannelsCurrentCursor;
@observable
String? followedChannelsCurrentCursor;
final token = AuthBase.token;
final String? id;
_ChannelListBase({this.id}) {
if (token != null) {
updateTopChannels();
}
if (id != null) {
updateFollowedChannels();
}
}
String? currentCursor({required Category category}) {
ObservableList<Channel> channels({required ChannelCategory category}) {
switch (category) {
case Category.top:
return topChannelsCurrentCursor;
case Category.followed:
return followedChannelsCurrentCursor;
}
}
ObservableList<Channel> channels({required Category category}) {
switch (category) {
case Category.top:
case ChannelCategory.top:
return topChannels;
case Category.followed:
case ChannelCategory.followed:
return followedChannels;
}
}
@action
Future<void> update({required Category category}) async {
final AuthStore auth;
_ChannelListBase({required this.auth}) {
getChannels(category: ChannelCategory.top);
if (auth.user?.id != null) {
getChannels(category: ChannelCategory.followed);
}
}
bool hasMore({required ChannelCategory category}) {
switch (category) {
case Category.top:
await updateTopChannels();
break;
case Category.followed:
await updateFollowedChannels();
break;
case ChannelCategory.top:
return isLoading == false && topChannelsCurrentCursor != null;
case ChannelCategory.followed:
return isLoading == false && followedChannelsCurrentCursor != null;
}
}
/// Returns the top 10 streamers and a cursor for further requests.
@action
Future<void> updateTopChannels() async {
final url = Uri.parse('https://api.twitch.tv/helix/streams?first=10');
final headers = {'Authorization': 'Bearer $token', 'Client-Id': clientId};
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
final data = decoded['data'] as List;
final result = {'channels': data.map((channel) => Channel.fromJson(channel)).toList(), 'cursor': decoded['pagination']['cursor']};
topChannels = ObservableList.of(result['channels']);
topChannelsCurrentCursor = result['cursor'];
} else {
debugPrint('Failed to update top channels');
Future<void> refresh({required ChannelCategory category}) async {
switch (category) {
case ChannelCategory.top:
topChannelsCurrentCursor = null;
topChannels.clear();
break;
case ChannelCategory.followed:
followedChannelsCurrentCursor = null;
followedChannels.clear();
break;
}
// notifyListeners();
await getChannels(category: category);
}
@action
Future<void> getMoreChannels({required Category category}) async {
Future<void> getChannels({required ChannelCategory category}) async {
isLoading = true;
Uri url;
switch (category) {
case Category.top:
url = Uri.parse('https://api.twitch.tv/helix/streams?first=10&after=$topChannelsCurrentCursor');
case ChannelCategory.top:
final newTopChannels = await Twitch.getTopChannels(headers: auth.headersTwitch, cursor: topChannelsCurrentCursor);
if (newTopChannels != null) {
topChannels.addAll(newTopChannels['channels']);
topChannelsCurrentCursor = newTopChannels['cursor'];
}
break;
case Category.followed:
url = Uri.parse('https://api.twitch.tv/helix/streams/followed?user_id=$id&first=10&after=$followedChannelsCurrentCursor');
case ChannelCategory.followed:
final newFollowedChannels = await Twitch.getFollowedChannels(id: auth.user!.id, headers: auth.headersTwitch, cursor: followedChannelsCurrentCursor);
if (newFollowedChannels != null) {
followedChannels.addAll(newFollowedChannels['channels']);
followedChannelsCurrentCursor = newFollowedChannels['cursor'];
}
break;
}
final headers = {'Authorization': 'Bearer $token', 'Client-Id': clientId};
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
final data = decoded['data'] as List;
final result = {'channels': data.map((channel) => Channel.fromJson(channel)).toList(), 'cursor': decoded['pagination']['cursor']};
switch (category) {
case Category.top:
topChannels.addAll(result['channels']);
topChannelsCurrentCursor = result['cursor'];
break;
case Category.followed:
followedChannels.addAll(result['channels']);
followedChannelsCurrentCursor = result['cursor'];
debugPrint(followedChannelsCurrentCursor);
break;
}
} else {
debugPrint('Failed to get more channels');
}
isLoading = false;
// notifyListeners();
}
@action
Future<void> updateFollowedChannels() async {
final url = Uri.parse('https://api.twitch.tv/helix/streams/followed?first=10&user_id=$id');
final headers = {'Authorization': 'Bearer $token', 'Client-Id': clientId};
final response = await http.get(url, headers: headers);
if (response.statusCode == 200) {
final decoded = jsonDecode(response.body);
final data = decoded['data'] as List;
final result = {'channels': data.map((channel) => Channel.fromJson(channel)).toList(), 'cursor': decoded['pagination']['cursor']};
followedChannels = ObservableList.of(result['channels']);
followedChannelsCurrentCursor = result['cursor'];
} else {
debugPrint('Failed to update followed channels');
}
// notifyListeners();
}
}
enum Category { top, followed }
enum ChannelCategory { top, followed }

View file

@ -40,96 +40,26 @@ mixin _$ChannelListStore on _ChannelListBase, Store {
});
}
final _$isLoadingAtom = Atom(name: '_ChannelListBase.isLoading');
final _$refreshAsyncAction = AsyncAction('_ChannelListBase.refresh');
@override
bool get isLoading {
_$isLoadingAtom.reportRead();
return super.isLoading;
Future<void> refresh({required ChannelCategory category}) {
return _$refreshAsyncAction.run(() => super.refresh(category: category));
}
@override
set isLoading(bool value) {
_$isLoadingAtom.reportWrite(value, super.isLoading, () {
super.isLoading = value;
});
}
final _$topChannelsCurrentCursorAtom =
Atom(name: '_ChannelListBase.topChannelsCurrentCursor');
final _$getChannelsAsyncAction = AsyncAction('_ChannelListBase.getChannels');
@override
String? get topChannelsCurrentCursor {
_$topChannelsCurrentCursorAtom.reportRead();
return super.topChannelsCurrentCursor;
}
@override
set topChannelsCurrentCursor(String? value) {
_$topChannelsCurrentCursorAtom
.reportWrite(value, super.topChannelsCurrentCursor, () {
super.topChannelsCurrentCursor = value;
});
}
final _$followedChannelsCurrentCursorAtom =
Atom(name: '_ChannelListBase.followedChannelsCurrentCursor');
@override
String? get followedChannelsCurrentCursor {
_$followedChannelsCurrentCursorAtom.reportRead();
return super.followedChannelsCurrentCursor;
}
@override
set followedChannelsCurrentCursor(String? value) {
_$followedChannelsCurrentCursorAtom
.reportWrite(value, super.followedChannelsCurrentCursor, () {
super.followedChannelsCurrentCursor = value;
});
}
final _$updateAsyncAction = AsyncAction('_ChannelListBase.update');
@override
Future<void> update({required Category category}) {
return _$updateAsyncAction.run(() => super.update(category: category));
}
final _$updateTopChannelsAsyncAction =
AsyncAction('_ChannelListBase.updateTopChannels');
@override
Future<void> updateTopChannels() {
return _$updateTopChannelsAsyncAction.run(() => super.updateTopChannels());
}
final _$getMoreChannelsAsyncAction =
AsyncAction('_ChannelListBase.getMoreChannels');
@override
Future<void> getMoreChannels({required Category category}) {
return _$getMoreChannelsAsyncAction
.run(() => super.getMoreChannels(category: category));
}
final _$updateFollowedChannelsAsyncAction =
AsyncAction('_ChannelListBase.updateFollowedChannels');
@override
Future<void> updateFollowedChannels() {
return _$updateFollowedChannelsAsyncAction
.run(() => super.updateFollowedChannels());
Future<void> getChannels({required ChannelCategory category}) {
return _$getChannelsAsyncAction
.run(() => super.getChannels(category: category));
}
@override
String toString() {
return '''
topChannels: ${topChannels},
followedChannels: ${followedChannels},
isLoading: ${isLoading},
topChannelsCurrentCursor: ${topChannelsCurrentCursor},
followedChannelsCurrentCursor: ${followedChannelsCurrentCursor}
followedChannels: ${followedChannels}
''';
}
}