refactor: fix null types

This commit is contained in:
Rongjian Zhang 2021-06-14 14:56:42 +08:00
parent 442d910dbd
commit 5b3bc45db5
24 changed files with 90 additions and 102 deletions

View File

@ -688,18 +688,15 @@ class AuthModel with ChangeNotifier {
// var _timeoutDuration = Duration(seconds: 1);
GitHub? _ghClient;
GitHub? get ghClient {
if (token == null) return null;
GitHub get ghClient {
if (_ghClient == null) {
_ghClient = GitHub(auth: Authentication.withToken(token));
}
return _ghClient;
return _ghClient!;
}
Client? _gqlClient;
Client? get gqlClient {
if (token == null) return null;
Client get gqlClient {
if (_gqlClient == null) {
_gqlClient = Client(
link: HttpLink(
@ -710,16 +707,13 @@ class AuthModel with ChangeNotifier {
);
}
return _gqlClient;
return _gqlClient!;
}
Future<dynamic> query(String query, [String? _token]) async {
if (_token == null) {
_token = token;
}
if (_token == null) {
throw 'token is null';
}
final res = await http
.post(Uri.parse(_apiPrefix + '/graphql'),

View File

@ -43,7 +43,7 @@ class GhCommits extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GCommitsData, GCommitsVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final ref = res.data!.repository!.defaultBranchRef ??
res.data!.repository!.ref!;
final history = (ref.target as GCommitsRefCommit).history;

View File

@ -20,7 +20,7 @@ class GhComparisonScreen extends StatelessWidget {
return RefreshStatefulScaffold(
title: AppBarTitle(AppLocalizations.of(context)!.files),
fetch: () async {
final res = await context.read<AuthModel>().ghClient!.getJSON(
final res = await context.read<AuthModel>().ghClient.getJSON(
'/repos/$owner/$name/compare/$before...$head',
convert: (dynamic vs) => GithubComparisonItem.fromJson(vs));
return res.files;

View File

@ -20,7 +20,7 @@ class GhContributorsScreen extends StatelessWidget {
page = page ?? 1;
final res = await context
.read<AuthModel>()
.ghClient!
.ghClient
.getJSON<List, List<GithubContributorItem>>(
'/repos/$owner/$name/contributors?page=$page',
convert: (vs) =>

View File

@ -20,7 +20,7 @@ class GhEventsScreen extends StatelessWidget {
itemBuilder: (payload) => EventItem(payload),
fetch: (page) async {
page = page ?? 1;
final events = await context.read<AuthModel>().ghClient!.getJSON(
final events = await context.read<AuthModel>().ghClient.getJSON(
'/users/$login/events?page=$page&per_page=$PAGE_SIZE',
convert: (dynamic vs) =>
[for (var v in vs) GithubEvent.fromJson(v)]);

View File

@ -31,7 +31,7 @@ class GhFilesScreen extends StatelessWidget {
page = page ?? 1;
final res = await context
.read<AuthModel>()
.ghClient!
.ghClient
.getJSON<List, List<GithubFilesItem>>(
'/repos/$owner/$name/pulls/$pullNumber/files?page=$page',
convert: (vs) => [for (var v in vs) GithubFilesItem.fromJson(v)],

View File

@ -24,7 +24,7 @@ class GhGistsScreen extends StatelessWidget {
..vars.login = login
..vars.after = page);
final OperationResponse<GGistsData, GGistsVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final gists = res.data!.user!.gists;
return ListPayload(
cursor: gists.pageInfo.endCursor,

View File

@ -26,7 +26,7 @@ class GhGistsFilesScreen extends StatelessWidget {
..vars.login = login
..vars.name = id);
final OperationResponse<GGistData, GGistVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final gist = res.data!.user!.gist;
return gist;
},

View File

@ -96,7 +96,7 @@ class GhIssueScreen extends StatelessWidget {
b.vars.cursor = cursor;
});
OperationResponse<GIssueData, GIssueVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
return res.data!.repository!;
}
@ -115,7 +115,7 @@ class GhIssueScreen extends StatelessWidget {
ActionItem(
text: d.closed ? 'Reopen issue' : 'Close issue',
onTap: (_) async {
await context.read<AuthModel>().ghClient!.issues.edit(
await context.read<AuthModel>().ghClient.issues.edit(
github.RepositorySlug(owner, name),
number,
github.IssueRequest(

View File

@ -59,7 +59,7 @@ class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
final slug = RepositorySlug(widget.owner, widget.name);
final res = await context
.read<AuthModel>()
.ghClient!
.ghClient
.issues
.create(slug, IssueRequest(title: _title, body: _body));
await theme.push(

View File

@ -33,7 +33,7 @@ class GhIssuesScreen extends StatelessWidget {
b.vars.cursor = cursor;
});
final OperationResponse<GIssuesData, GIssuesVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final issues = res.data!.repository!.issues;
return ListPayload(
cursor: issues.pageInfo.endCursor,

View File

@ -24,7 +24,7 @@ class GhNewsScreenState extends State<GhNewsScreen> {
// 1 item is enough since count is not displayed for now.
var items = await context
.read<AuthModel>()
.ghClient!
.ghClient
.getJSON('/notifications?per_page=1');
if (items is List && items.isNotEmpty) {
@ -43,7 +43,7 @@ class GhNewsScreenState extends State<GhNewsScreen> {
final auth = context.read<AuthModel>();
final login = auth.activeAccount!.login;
final events = await auth.ghClient!.getJSON(
final events = await auth.ghClient.getJSON(
'/users/$login/received_events?page=$page&per_page=$PAGE_SIZE',
convert: (dynamic vs) => [for (var v in vs) GithubEvent.fromJson(v)],
);

View File

@ -21,7 +21,7 @@ class GhNotificationScreen extends StatefulWidget {
class GhNotificationScreenState extends State<GhNotificationScreen> {
Future<Map<String, NotificationGroup>> fetchNotifications(int index) async {
final ns = await context.read<AuthModel>().ghClient!.getJSON(
final ns = await context.read<AuthModel>().ghClient.getJSON(
'/notifications?all=${index == 2}&participating=${index == 1}',
convert: (dynamic vs) =>
[for (var v in vs) GithubNotificationItem.fromJson(v)],
@ -123,7 +123,7 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
onTap: () async {
await context
.read<AuthModel>()
.ghClient!
.ghClient
.activity
.markRepositoryNotificationsRead(
RepositorySlug.full(group.fullName!));

View File

@ -37,7 +37,7 @@ class GhObjectScreen extends StatelessWidget {
final suffix = path == null ? '' : '/$path';
final res = await context
.read<AuthModel>()
.ghClient!
.ghClient
.repositories
.getContents(RepositorySlug(owner, name), suffix, ref: ref);
if (res.isDirectory) {

View File

@ -25,7 +25,7 @@ class GhOrgReposScreen extends StatelessWidget {
page = page ?? 1;
final rs = await context
.read<AuthModel>()
.ghClient!
.ghClient
.getJSON<List, List<Repository>>(
'/orgs/$owner/repos?sort=updated&page=$page',
convert: (vs) => [for (var v in vs) Repository.fromJson(v)],

View File

@ -19,7 +19,7 @@ class GhUserOrganizationScreen extends StatelessWidget {
page = page ?? 1;
final res = await context
.read<AuthModel>()
.ghClient!
.ghClient
.getJSON<List, List<GithubUserOrganizationItem>>(
'/users/$login/orgs?page=$page',
convert: (vs) =>

View File

@ -28,7 +28,7 @@ class GhPullsScreen extends StatelessWidget {
b.vars.cursor = cursor;
});
final OperationResponse<GPullsData, GPullsVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final pulls = res.data!.repository!.pullRequests;
return ListPayload(
cursor: pulls.pageInfo.endCursor,

View File

@ -26,7 +26,7 @@ class GhReleasesScreen extends StatelessWidget {
..vars.name = name
..vars.cursor = page);
final OperationResponse<GReleasesData, GReleasesVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final releases = res.data!.repository!.releases;
return ListPayload(
cursor: releases.pageInfo.endCursor,

View File

@ -57,10 +57,10 @@ class GhRepoScreen extends StatelessWidget {
..vars.branchSpecified = branch != null
..vars.branch = branch ?? '');
final OperationResponse<GRepoData, GRepoVars?> res =
await context.read<AuthModel>().gqlClient!.request(req).first;
await context.read<AuthModel>().gqlClient.request(req).first;
final repo = res.data!.repository;
final ghClient = context.read<AuthModel>().ghClient!;
final ghClient = context.read<AuthModel>().ghClient;
final countFuture = ghClient
.getJSON('/repos/$owner/$name/stats/contributors')
.then((v) => (v as List).length);
@ -132,10 +132,8 @@ class GhRepoScreen extends StatelessWidget {
ActionItem(
text: _buildWatchState(v),
onTap: (_) async {
final activityApi = context
.read<AuthModel>()
.ghClient!
.activity;
final activityApi =
context.read<AuthModel>().ghClient.activity;
switch (v) {
case GSubscriptionState.SUBSCRIBED:
case GSubscriptionState.IGNORED:
@ -173,7 +171,7 @@ class GhRepoScreen extends StatelessWidget {
text: repo.viewerHasStarred ? 'Unstar' : 'Star',
onTap: () async {
final activityApi =
context.read<AuthModel>().ghClient!.activity;
context.read<AuthModel>().ghClient.activity;
if (repo.viewerHasStarred) {
await activityApi.unstar(
RepositorySlug(repo.owner.login, repo.name));

View File

@ -25,7 +25,7 @@ class GhRepos extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GReposData, GReposVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.user!.repositories;
return ListPayload(
cursor: p.pageInfo.endCursor,
@ -56,7 +56,7 @@ class GhStars extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GStarsData, GStarsVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.user!.starredRepositories;
return ListPayload(
cursor: p.pageInfo.endCursor,

View File

@ -272,7 +272,7 @@ class GhViewer extends StatelessWidget {
fetch: () async {
final req = GViewerReq();
final OperationResponse<GViewerData, GViewerVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
return res.data!.viewer;
},
title: AppBarTitle(AppLocalizations.of(context)!.me),
@ -298,7 +298,7 @@ class GhUser extends StatelessWidget {
fetch: () async {
final req = GUserReq((b) => b..vars.login = login);
final OperationResponse<GUserData, GUserVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
return res.data;
},
title: AppBarTitle(login),
@ -322,9 +322,9 @@ class GhUser extends StatelessWidget {
: AppLocalizations.of(context)!.follow,
onTap: () async {
if (p.viewerIsFollowing) {
await auth.ghClient!.users.unfollowUser(p.login);
await auth.ghClient.users.unfollowUser(p.login);
} else {
await auth.ghClient!.users.followUser(p.login);
await auth.ghClient.users.followUser(p.login);
}
setData(data.rebuild((b) {
final u = b.repositoryOwner

View File

@ -24,7 +24,7 @@ class GhFollowers extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GFollowersData, GFollowersVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.user!.followers;
return ListPayload(
cursor: p.pageInfo.endCursor,
@ -54,7 +54,7 @@ class GhFollowing extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GFollowingData, GFollowingVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.user!.following;
return ListPayload(
cursor: p.pageInfo.endCursor,
@ -84,7 +84,7 @@ class GhMembers extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GMembersData, GMembersVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.organization!.membersWithRole;
return ListPayload(
cursor: p.pageInfo.endCursor,
@ -116,7 +116,7 @@ class GhWachers extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GWatchersData, GWatchersVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.repository!.watchers;
return ListPayload(
cursor: p.pageInfo.endCursor,
@ -148,7 +148,7 @@ class GhStargazers extends StatelessWidget {
b.vars.after = cursor;
});
final OperationResponse<GStargazersData, GStargazersVars?> res =
await auth.gqlClient!.request(req).first;
await auth.gqlClient.request(req).first;
final p = res.data!.repository!.stargazers;
return ListPayload(
cursor: p.pageInfo.endCursor,

View File

@ -44,62 +44,58 @@ class GoUserScreen extends StatelessWidget {
bodyBuilder: (p, _) {
final user = p.item1;
final repos = p.item2;
if (p.item1 != null) {
return Column(
children: <Widget>[
UserHeader(
login: user.username,
avatarUrl: user.avatarUrl,
name: user.fullName,
createdAt:
null, // TODO: API response does not have this attribute
isViewer: isViewer,
bio: null, // TODO: API response does not have this attribute
return Column(
children: <Widget>[
UserHeader(
login: user.username,
avatarUrl: user.avatarUrl,
name: user.fullName,
createdAt:
null, // TODO: API response does not have this attribute
isViewer: isViewer,
bio: null, // TODO: API response does not have this attribute
),
CommonStyle.border,
Row(children: [
EntryItem(
text: 'Repositories',
url: '/gogs/$login?tab=repositories&isViewer=$isViewer',
),
CommonStyle.border,
Row(children: [
EntryItem(
text: 'Repositories',
url: '/gogs/$login?tab=repositories&isViewer=$isViewer',
EntryItem(
text: 'Followers',
url: '/gogs/$login?tab=followers',
),
EntryItem(
text: 'Following',
url: '/gogs/$login?tab=following',
),
]),
CommonStyle.border,
TableView(
items: [
TableViewItem(
leftIconData: Octicons.home,
text: Text('Organizations'),
url:
'/gogs/${user.username}?tab=organizations&isViewer=$isViewer',
),
EntryItem(
text: 'Followers',
url: '/gogs/$login?tab=followers',
),
EntryItem(
text: 'Following',
url: '/gogs/$login?tab=following',
),
]),
CommonStyle.border,
TableView(
items: [
TableViewItem(
leftIconData: Octicons.home,
text: Text('Organizations'),
url:
'/gogs/${user.username}?tab=organizations&isViewer=$isViewer',
],
),
CommonStyle.border,
Column(
children: <Widget>[
for (var v in repos) ...[
RepositoryItem.go(
payload: v,
name: v.fullName!.split('/')[1],
owner: v.owner!.username,
),
],
),
CommonStyle.border,
Column(
children: <Widget>[
for (var v in repos) ...[
RepositoryItem.go(
payload: v,
name: v.fullName!.split('/')[1],
owner: v.owner!.username,
),
CommonStyle.border,
]
],
),
],
);
} else {
return Text('404'); // TODO:
}
CommonStyle.border,
]
],
),
],
);
},
);
}

View File

@ -83,7 +83,7 @@ class _NotificationItemState extends State<NotificationItem> {
try {
await context
.read<AuthModel>()
.ghClient!
.ghClient
.activity
.markThreadRead(payload.id!);
widget.markAsRead();