TetraStats/lib/widgets/tl_records_thingy.dart

117 lines
3.8 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:tetra_stats/data_objects/beta_record.dart';
import 'package:tetra_stats/main.dart';
import 'package:tetra_stats/widgets/beta_league_entry_thingy.dart';
import 'package:tetra_stats/widgets/future_error.dart';
class TLRecords extends StatefulWidget {
final String userID;
/// Widget, that displays Tetra League records.
/// Accepts list of TL records ([data]) and [userID] of player from the view
const TLRecords(this.userID);
@override
State<TLRecords> createState() => _TLRecordsState();
}
class _TLRecordsState extends State<TLRecords> {
List<BetaRecord> records = [];
bool isFetchingRecords = false;
bool reachedEndOfRecords = false;
final StreamController<List<dynamic>> _recordsStreamController = StreamController<List<dynamic>>.broadcast();
Stream<List<dynamic>> get recordsStream => _recordsStreamController.stream;
String? recordsPrisecter;
late final ScrollController _scrollController;
@override
void initState(){
_scrollController = ScrollController();
_scrollController.addListener(() {
_scrollController.addListener(() {
final maxScroll = _scrollController.position.maxScrollExtent;
final currentScroll = _scrollController.position.pixels;
if (currentScroll == maxScroll) {
_fetchRecord(widget.userID);
}
});
});
_fetchRecord(widget.userID);
super.initState();
}
Future<void> _fetchRecord(String userID) async {
if (isFetchingRecords || reachedEndOfRecords) {
// Avoid fetching new data while already fetching
return;
}
try {
isFetchingRecords = true;
final items = (await teto.fetchTLStream(userID, prisecter: recordsPrisecter)).records;
if (items.isEmpty) reachedEndOfRecords = true;
records.addAll(items);
if (items.isNotEmpty){
_recordsStreamController.add(records);
recordsPrisecter = records.last.prisecter.toString();
} else{
_recordsStreamController.add([]);
}
} catch (e) {
_recordsStreamController.addError(e);
} finally {
// Set to false when data fetching is complete
isFetchingRecords = false;
}
}
Future<void> resetRecords(String userID) async {
records.clear();
recordsPrisecter = null;
reachedEndOfRecords = false;
_fetchRecord(userID);
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: recordsStream,
builder: (context, snapshot) {
switch (snapshot.connectionState){
case ConnectionState.none:
case ConnectionState.waiting:
return const Center(child: CircularProgressIndicator());
case ConnectionState.active:
case ConnectionState.done:
if (snapshot.hasData){
return SizedBox(
height: MediaQuery.of(context).size.height - 130,
child: ListView.builder(
controller: _scrollController,
itemCount: records.length,
prototypeItem: Padding(
padding: const EdgeInsets.only(top: 4.0),
child: ListTile(
leading: Text("0"),
title: Text("ehhh...", style: TextStyle(fontSize: 22)),
trailing: SizedBox(height: 36, width: 1),
subtitle: const Text("eh\n...", style: TextStyle(color: Colors.grey, fontSize: 12)),
),
),
itemBuilder: (BuildContext context, int index){
return BetaLeagueEntryThingy(records[index], widget.userID);
}
),
);
}
if (snapshot.hasError){ return SizedBox(height: 500, child: Center(child: FutureError(snapshot))); }
return const Center(child: Text("whar?"));
}
},
);
}
}