fix: long list scaffold

This commit is contained in:
Rongjian Zhang 2021-06-05 13:54:52 +08:00
parent af52d55af9
commit 17b6fd5d78
7 changed files with 32 additions and 34 deletions

View File

@ -166,7 +166,7 @@ class GithubNotificationItemSubject {
int? _number; int? _number;
int? get number { int? get number {
if (_number == null) { if (_number == null) {
_number = int.parse(url?.split('/')?.last ?? '0'); _number = int.parse(url?.split('/').last ?? '0');
} }
return _number; return _number;
} }

View File

@ -9,17 +9,17 @@ import '../widgets/link.dart';
import '../widgets/error_reload.dart'; import '../widgets/error_reload.dart';
class LongListPayload<T, K> { class LongListPayload<T, K> {
T? header; T header;
int? totalCount; int totalCount;
String? cursor; String cursor;
List<K>? leadingItems; List<K> leadingItems;
List<K>? trailingItems; List<K>? trailingItems;
LongListPayload({ LongListPayload({
this.header, required this.header,
this.totalCount, required this.totalCount,
this.cursor, required this.cursor,
this.leadingItems, required this.leadingItems,
this.trailingItems, this.trailingItems,
}); });
} }
@ -51,12 +51,12 @@ class LongListStatefulScaffold<T, K> extends StatefulWidget {
} }
class _LongListStatefulScaffoldState<T, K> class _LongListStatefulScaffoldState<T, K>
extends State<LongListStatefulScaffold<T?, K>> { extends State<LongListStatefulScaffold<T, K>> {
late bool loading; late bool loading;
bool loadingMore = false; bool loadingMore = false;
String error = ''; String error = '';
LongListPayload<T?, K>? payload; LongListPayload<T, K>? payload;
@override @override
void initState() { void initState() {
@ -94,7 +94,7 @@ class _LongListStatefulScaffoldState<T, K>
await widget.onLoadMore(payload!.cursor); await widget.onLoadMore(payload!.cursor);
payload!.totalCount = _payload.totalCount; payload!.totalCount = _payload.totalCount;
payload!.cursor = _payload.cursor; payload!.cursor = _payload.cursor;
payload!.leadingItems!.addAll(_payload.leadingItems!); payload!.leadingItems.addAll(_payload.leadingItems);
} finally { } finally {
if (mounted) { if (mounted) {
setState(() { setState(() {
@ -113,11 +113,11 @@ class _LongListStatefulScaffoldState<T, K>
int realIndex = index ~/ 2; int realIndex = index ~/ 2;
if (realIndex < payload!.leadingItems!.length) { if (realIndex < payload!.leadingItems.length) {
return widget.itemBuilder(payload!.leadingItems![realIndex]); return widget.itemBuilder(payload!.leadingItems[realIndex]);
} else if (realIndex == payload!.leadingItems!.length) { } else if (realIndex == payload!.leadingItems.length) {
var count = payload!.totalCount! - var count = payload!.totalCount -
payload!.leadingItems!.length + payload!.leadingItems.length +
payload!.trailingItems!.length; payload!.trailingItems!.length;
return Container( return Container(
padding: CommonStyle.padding, padding: CommonStyle.padding,
@ -150,13 +150,13 @@ class _LongListStatefulScaffoldState<T, K>
); );
} else { } else {
return widget.itemBuilder(payload! return widget.itemBuilder(payload!
.trailingItems![realIndex - payload!.leadingItems!.length - 1]); .trailingItems![realIndex - payload!.leadingItems.length - 1]);
} }
} }
int get _itemCount { int get _itemCount {
int count = payload!.leadingItems!.length + payload!.trailingItems!.length; int count = payload!.leadingItems.length + payload!.trailingItems!.length;
if (payload!.totalCount! > count) { if (payload!.totalCount > count) {
count++; count++;
} }
return 2 * count; // including bottom border return 2 * count; // including bottom border

View File

@ -25,7 +25,7 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
List<List> _payloads = [[], [], []]; List<List> _payloads = [[], [], []];
TextEditingController? _controller; TextEditingController? _controller;
String get _keyword => _controller!.text?.trim() ?? ''; String get _keyword => _controller!.text.trim();
@override @override
void initState() { void initState() {

View File

@ -87,7 +87,7 @@ class GhIssueScreen extends StatelessWidget {
); );
} }
Future<GIssueData_repository?> _queryIssue(BuildContext context, Future<GIssueData_repository> _queryIssue(BuildContext context,
{String? cursor}) async { {String? cursor}) async {
final req = GIssueReq((b) { final req = GIssueReq((b) {
b.vars.owner = owner; b.vars.owner = owner;
@ -97,7 +97,7 @@ class GhIssueScreen extends StatelessWidget {
}); });
OperationResponse<GIssueData, GIssueVars?> res = OperationResponse<GIssueData, GIssueVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first; await context.read<AuthModel>().gqlClient!.request(req).first;
return res.data!.repository; return res.data!.repository!;
} }
@override @override
@ -257,15 +257,14 @@ class GhIssueScreen extends StatelessWidget {
}, },
itemBuilder: (p) => TimelineItem(p), itemBuilder: (p) => TimelineItem(p),
onRefresh: () async { onRefresh: () async {
final res = final res = await _queryIssue(context);
await (_queryIssue(context) as Future<GIssueData_repository>);
if (res.issueOrPullRequest!.G__typename == 'Issue') { if (res.issueOrPullRequest!.G__typename == 'Issue') {
final issue = res.issueOrPullRequest final issue = res.issueOrPullRequest
as GIssueData_repository_issueOrPullRequest__asIssue; as GIssueData_repository_issueOrPullRequest__asIssue;
return LongListPayload( return LongListPayload(
header: res, header: res,
totalCount: issue.timelineItems.totalCount, totalCount: issue.timelineItems.totalCount,
cursor: issue.timelineItems.pageInfo.endCursor, cursor: issue.timelineItems.pageInfo.endCursor!,
leadingItems: issue.timelineItems.nodes!.toList(), leadingItems: issue.timelineItems.nodes!.toList(),
trailingItems: [], trailingItems: [],
); );
@ -275,22 +274,21 @@ class GhIssueScreen extends StatelessWidget {
return LongListPayload( return LongListPayload(
header: res, header: res,
totalCount: pr.timelineItems.totalCount, totalCount: pr.timelineItems.totalCount,
cursor: pr.timelineItems.pageInfo.endCursor, cursor: pr.timelineItems.pageInfo.endCursor!,
leadingItems: pr.timelineItems.nodes!.toList(), leadingItems: pr.timelineItems.nodes!.toList(),
trailingItems: [], trailingItems: [],
); );
} }
}, },
onLoadMore: (_cursor) async { onLoadMore: (_cursor) async {
final res = await (_queryIssue(context, cursor: _cursor) final res = await _queryIssue(context, cursor: _cursor);
as Future<GIssueData_repository>);
if (res.issueOrPullRequest!.G__typename == 'Issue') { if (res.issueOrPullRequest!.G__typename == 'Issue') {
final issue = res.issueOrPullRequest final issue = res.issueOrPullRequest
as GIssueData_repository_issueOrPullRequest__asIssue; as GIssueData_repository_issueOrPullRequest__asIssue;
return LongListPayload( return LongListPayload(
header: res, header: res,
totalCount: issue.timelineItems.totalCount, totalCount: issue.timelineItems.totalCount,
cursor: issue.timelineItems.pageInfo.endCursor, cursor: issue.timelineItems.pageInfo.endCursor!,
leadingItems: issue.timelineItems.nodes!.toList(), leadingItems: issue.timelineItems.nodes!.toList(),
); );
} else { } else {
@ -299,7 +297,7 @@ class GhIssueScreen extends StatelessWidget {
return LongListPayload( return LongListPayload(
header: res, header: res,
totalCount: pr.timelineItems.totalCount, totalCount: pr.timelineItems.totalCount,
cursor: pr.timelineItems.pageInfo.endCursor, cursor: pr.timelineItems.pageInfo.endCursor!,
leadingItems: pr.timelineItems.nodes!.toList(), leadingItems: pr.timelineItems.nodes!.toList(),
); );
} }

View File

@ -270,7 +270,7 @@ class GhRepoScreen extends StatelessWidget {
leftIconData: Octicons.history, leftIconData: Octicons.history,
text: Text(AppLocalizations.of(context)!.commits), text: Text(AppLocalizations.of(context)!.commits),
rightWidget: Text( rightWidget: Text(
((ref.target as GRepoCommit).history?.totalCount ?? 0) ((ref.target as GRepoCommit).history.totalCount)
.toString()), .toString()),
url: '/github/$owner/$name/commits/${ref.name}', url: '/github/$owner/$name/commits/${ref.name}',
), ),

View File

@ -25,7 +25,7 @@ class _GhSearchScreenState extends State<GhSearchScreen> {
TextEditingController? _controller; TextEditingController? _controller;
String get _keyword => _controller!.text?.trim() ?? ''; String get _keyword => _controller!.text.trim();
@override @override
void initState() { void initState() {

View File

@ -26,7 +26,7 @@ class _GlSearchScreenState extends State<GlSearchScreen> {
TextEditingController? _controller; TextEditingController? _controller;
String get _keyword => _controller!.text?.trim() ?? ''; String get _keyword => _controller!.text.trim();
@override @override
void initState() { void initState() {