Remove channel provider & temp fix infinite scroll

This commit is contained in:
Tommy Chow 2021-08-22 01:24:04 -04:00
parent 893a7c262a
commit f605d2457a
3 changed files with 50 additions and 44 deletions

View file

@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:frosty/providers/authentication_provider.dart';
import 'package:frosty/providers/channel_list_provider.dart';
import 'package:frosty/widgets/channel_list.dart';
import 'package:provider/provider.dart';
@ -20,11 +19,10 @@ class MyApp extends StatelessWidget {
home: MultiProvider(
providers: [
ChangeNotifierProvider<Authentication>(create: (context) => Authentication()),
ChangeNotifierProvider<ChannelListProvider>(create: (context) => ChannelListProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text('Frosty'),
title: Text('Top Channels'),
),
body: ChannelList(),
),

View file

@ -1,28 +0,0 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:frosty/models/channel.dart';
import 'package:http/http.dart' as http;
class ChannelListProvider extends ChangeNotifier {
final channels = <Channel>[];
String? cursor;
/// Returns the top 10 streamers and a cursor for further requests.
Future<void> getTopChannels({required String token, String? cursor}) async {
final url;
if (cursor != null) {
url = Uri.parse('https://api.twitch.tv/helix/streams?first=10&after=$cursor');
} else {
url = Uri.parse('https://api.twitch.tv/helix/streams?first=10');
}
final headers = {'Authorization': 'Bearer $token', 'Client-Id': const String.fromEnvironment('CLIENT_ID')};
final response = await http.get(url, headers: headers);
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']};
channels.addAll(result['channels']);
cursor = result['cursor'];
}
}

View file

@ -1,39 +1,75 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:frosty/models/channel.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:frosty/providers/authentication_provider.dart';
import 'package:frosty/providers/channel_list_provider.dart';
import 'package:frosty/widgets/channel_card.dart';
import 'package:provider/provider.dart';
class ChannelList extends StatelessWidget {
// FIXME: EXTREMELY fast scrolling will break.
class ChannelList extends StatefulWidget {
const ChannelList({Key? key}) : super(key: key);
@override
_ChannelListState createState() => _ChannelListState();
}
class _ChannelListState extends State<ChannelList> {
final channels = <Channel>[];
var _isLoading = false;
String? currentCursor;
/// Returns the top 10 streamers and a cursor for further requests.
Future<void> getTopChannels({required String token, String? cursor}) async {
_isLoading = true;
final url;
if (cursor != null) {
url = Uri.parse('https://api.twitch.tv/helix/streams?first=10&after=$cursor');
} else {
url = Uri.parse('https://api.twitch.tv/helix/streams?first=10');
}
final headers = {'Authorization': 'Bearer $token', 'Client-Id': const String.fromEnvironment('CLIENT_ID')};
final response = await http.get(url, headers: headers);
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']};
channels.addAll(result['channels']);
currentCursor = result['cursor'];
_isLoading = false;
}
@override
Widget build(BuildContext context) {
return Consumer2<Authentication, ChannelListProvider>(
builder: (context, auth, provider, child) {
return Consumer<Authentication>(
builder: (context, auth, child) {
return FutureBuilder(
future: provider.getTopChannels(token: auth.token!),
future: getTopChannels(token: auth.token!, cursor: currentCursor),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
// TODO: Handle this case.
break;
case ConnectionState.waiting:
// TODO: Handle this case.
break;
return CircularProgressIndicator();
case ConnectionState.active:
// TODO: Handle this case.
break;
case ConnectionState.done:
return ListView.builder(
itemBuilder: (context, index) {
print(index);
if (index >= provider.channels.length / 2) {
print('fetching more channels...');
print(provider.channels.length);
provider.getTopChannels(token: auth.token!);
if (index >= channels.length / 2) {
if (!_isLoading) {
print('fetching more channels...');
getTopChannels(token: auth.token!, cursor: currentCursor);
}
}
return ChannelCard(channelInfo: provider.channels[index]);
return ChannelCard(channelInfo: channels[index]);
},
);
}