1
0
mirror of https://github.com/git-touch/git-touch synced 2025-02-02 08:56:54 +01:00

refactor: list scaffold

This commit is contained in:
Rongjian Zhang 2021-06-14 01:23:16 +08:00
parent ac02fd705a
commit 917a8018f3
14 changed files with 94 additions and 126 deletions

View File

@ -1,5 +1,4 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
part 'account.g.dart';

View File

@ -415,7 +415,6 @@ class ThemeModel with ChangeNotifier {
}
showActions(BuildContext context, List<ActionItem> actionItems) async {
if (actionItems == null) return;
final value = await showCupertinoModalPopup<int>(
context: context,
builder: (BuildContext context) {

View File

@ -5,14 +5,14 @@ import 'package:git_touch/models/theme.dart';
import 'package:git_touch/scaffolds/common.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:provider/provider.dart';
import '../widgets/error_reload.dart';
import '../widgets/loading.dart';
import '../widgets/empty.dart';
import 'package:git_touch/widgets/error_reload.dart';
import 'package:git_touch/widgets/loading.dart';
import 'package:git_touch/widgets/empty.dart';
class ListPayload<T, K> {
K cursor;
Iterable<T>? items;
bool? hasMore;
Iterable<T> items;
bool hasMore;
ListPayload({
required this.items,
@ -56,7 +56,15 @@ class _ListStatefulScaffoldState<T, K>
void initState() {
super.initState();
_refresh();
_controller.addListener(onScroll);
_controller.addListener(() {
if (_controller.position.maxScrollExtent - _controller.offset < 100 &&
!_controller.position.outOfRange &&
!loading &&
!loadingMore &&
hasMore != false) {
_loadMore();
}
});
}
@override
@ -65,40 +73,17 @@ class _ListStatefulScaffoldState<T, K>
super.dispose();
}
void onScroll() {
// Fimber.d(_controller.position.maxScrollExtent - _controller.offset);
if (_controller.position.maxScrollExtent - _controller.offset < 100 &&
!_controller.position.outOfRange &&
!loading &&
!loadingMore &&
hasMore!) {
_loadMore();
}
}
// if items not enough, fetch next page
// This should be triggered after build
// TODO: disabled
void _makeSureItemsFill() {
// Future.delayed(Duration(milliseconds: 300)).then((_) {
// onScroll();
// });
}
Future<void> _refresh({bool force = false}) async {
Future<void> _refresh() async {
// Fimber.d('list scaffold refresh');
setState(() {
error = '';
loading = true;
if (force) {
items = [];
}
});
try {
final ListPayload<T, K?> _payload = await widget.fetch(null);
items = _payload.items!.toList();
cursor = _payload.cursor;
hasMore = _payload.hasMore;
final ListPayload<T, K> p = await widget.fetch(null);
items = p.items.toList();
cursor = p.cursor;
hasMore = p.hasMore;
} catch (err) {
error = err.toString();
throw err;
@ -107,7 +92,6 @@ class _ListStatefulScaffoldState<T, K>
setState(() {
loading = false;
});
_makeSureItemsFill();
}
}
}
@ -118,10 +102,10 @@ class _ListStatefulScaffoldState<T, K>
loadingMore = true;
});
try {
ListPayload<T, K?> _payload = await widget.fetch(cursor);
items.addAll(_payload.items!);
cursor = _payload.cursor;
hasMore = _payload.hasMore;
ListPayload<T, K> p = await widget.fetch(cursor);
items.addAll(p.items);
cursor = p.cursor;
hasMore = p.hasMore;
} catch (err) {
error = err.toString();
throw err;
@ -130,25 +114,22 @@ class _ListStatefulScaffoldState<T, K>
setState(() {
loadingMore = false;
});
_makeSureItemsFill();
}
}
}
Widget _buildItem(BuildContext context, int index) {
if (index == 2 * items.length) {
if (hasMore!) {
if (hasMore != false) {
return Loading(more: true);
} else {
return Container();
}
}
if (index % 2 == 1) {
} else if (index % 2 == 1) {
return CommonStyle.border;
} else {
return widget.itemBuilder(items[index ~/ 2]);
}
return widget.itemBuilder(items[index ~/ 2]);
}
Widget _buildCupertinoSliver() {

View File

@ -82,34 +82,33 @@ class BbRepoScreen extends StatelessWidget {
url:
'/bitbucket/$owner/$name/commits/${branch ?? p.mainbranch!.name}',
),
if (branches != null)
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text((branch ?? p.mainbranch!.name)! +
'' +
branches.length.toString()),
onTap: () async {
if (branches.length < 2) return;
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text((branch ?? p.mainbranch!.name)! +
'' +
branches.length.toString()),
onTap: () async {
if (branches.length < 2) return;
await theme.showPicker(
context,
PickerGroupItem(
value: branch,
items: branches
.map((b) => PickerItem(b.name, text: b.name))
.toList(),
onClose: (ref) {
if (ref != branch) {
theme.push(context,
'/bitbucket/$owner/$name?branch=$ref',
replace: true);
}
},
),
);
},
),
await theme.showPicker(
context,
PickerGroupItem(
value: branch,
items: branches
.map((b) => PickerItem(b.name, text: b.name))
.toList(),
onClose: (ref) {
if (ref != branch) {
theme.push(
context, '/bitbucket/$owner/$name?branch=$ref',
replace: true);
}
},
),
);
},
),
],
),
CommonStyle.verticalGap,

View File

@ -159,34 +159,33 @@ class GeRepoScreen extends StatelessWidget {
url:
'/gitee/$owner/$name/commits?branch=${branch ?? p.defaultBranch}',
),
if (branches != null)
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text((branch ?? p.defaultBranch)! +
'' +
branches.length.toString()),
onTap: () async {
if (branches.length < 2) return;
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text((branch ?? p.defaultBranch)! +
'' +
branches.length.toString()),
onTap: () async {
if (branches.length < 2) return;
await theme.showPicker(
context,
PickerGroupItem(
value: branch,
items: branches
.map((b) => PickerItem(b.name, text: b.name))
.toList(),
onClose: (ref) {
if (ref != branch) {
theme.push(
context, '/gitee/$owner/$name?branch=$ref',
replace: true);
}
},
),
);
},
),
await theme.showPicker(
context,
PickerGroupItem(
value: branch,
items: branches
.map((b) => PickerItem(b.name, text: b.name))
.toList(),
onClose: (ref) {
if (ref != branch) {
theme.push(
context, '/gitee/$owner/$name?branch=$ref',
replace: true);
}
},
),
);
},
),
TableViewItem(
leftIconData: Octicons.organization,
text: Text('Contributors'),

View File

@ -50,7 +50,7 @@ class GhCommits extends StatelessWidget {
return ListPayload(
cursor: history.pageInfo.endCursor,
hasMore: history.pageInfo.hasNextPage,
items: history.nodes,
items: history.nodes ?? [],
);
},
itemBuilder: (p) {

View File

@ -28,7 +28,7 @@ class GhGistsScreen extends StatelessWidget {
final gists = res.data!.user!.gists;
return ListPayload(
cursor: gists.pageInfo.endCursor,
items: gists.nodes,
items: gists.nodes ?? [],
hasMore: gists.pageInfo.hasNextPage,
);
},

View File

@ -30,7 +30,7 @@ class GhReleasesScreen extends StatelessWidget {
final releases = res.data!.repository!.releases;
return ListPayload(
cursor: releases.pageInfo.endCursor,
items: releases.nodes,
items: releases.nodes ?? [],
hasMore: releases.pageInfo.hasNextPage,
);
},

View File

@ -75,7 +75,7 @@ class GhRepoScreen extends StatelessWidget {
return res.body;
}).catchError((err) {
// 404
return null;
return '';
});
};
};

View File

@ -30,7 +30,7 @@ class GhRepos extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {
@ -61,7 +61,7 @@ class GhStars extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {

View File

@ -29,7 +29,7 @@ class GhFollowers extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {
@ -59,7 +59,7 @@ class GhFollowing extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {
@ -89,7 +89,7 @@ class GhMembers extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {
@ -121,7 +121,7 @@ class GhWachers extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {
@ -153,7 +153,7 @@ class GhStargazers extends StatelessWidget {
return ListPayload(
cursor: p.pageInfo.endCursor,
hasMore: p.pageInfo.hasNextPage,
items: p.nodes,
items: p.nodes!,
);
},
itemBuilder: (p) {

View File

@ -114,12 +114,10 @@ class GoRepoScreen extends StatelessWidget {
TableViewItem(
leftIconData: Octicons.git_branch,
text: Text(AppLocalizations.of(context)!.branches),
rightWidget: Text((branch ?? 'master')! +
rightWidget: Text((branch ?? 'master') +
'' +
'${branches == null ? '1' : branches.length.toString()}'),
'${branches.length.toString()}'),
onTap: () async {
if (branches == null) return;
await theme.showPicker(
context,
PickerGroupItem(

View File

@ -119,7 +119,7 @@ List<T> join<T>(T seperator, List<T> xs) {
List<T> joinAll<T>(T seperator, List<List<T>> xss) {
List<T> result = [];
xss.asMap().forEach((index, x) {
if (x == null || x.isEmpty) return;
if (x.isEmpty) return;
result.addAll(x);
if (index < xss.length - 1) {
@ -136,11 +136,6 @@ bool isNotNullOrEmpty(String? text) {
return text != null && text.isNotEmpty;
}
String getBranchQueryKey(String branch, {bool withParams = false}) {
if (branch == null) return 'defaultBranchRef';
return 'ref' + (withParams ? '(qualifiedName: "$branch")' : '');
}
// TODO: Primer
class PrimerBranchName extends StatelessWidget {
final String? name;

View File

@ -101,9 +101,7 @@ class ReleaseItem extends StatelessWidget {
),
rightWidget: IconButton(
onPressed: () {
if (asset.downloadUrl != null) {
theme.push(context, asset.downloadUrl);
}
theme.push(context, asset.downloadUrl);
},
icon: Icon(Ionicons.download_outline)),
hideRightChevron: true,