git-touch-android-ios-app/lib/screens/ge_search.dart

166 lines
4.9 KiB
Dart
Raw Normal View History

2022-09-24 20:46:37 +02:00
import 'package:antd_mobile/antd_mobile.dart';
2021-01-06 07:57:31 +01:00
import 'package:flutter/cupertino.dart';
2022-09-17 14:35:45 +02:00
import 'package:flutter_gen/gen_l10n/S.dart';
2022-10-07 18:55:47 +02:00
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
2022-09-17 14:35:45 +02:00
import 'package:git_touch/models/auth.dart';
import 'package:git_touch/models/gitee.dart';
2021-01-06 07:57:31 +01:00
import 'package:git_touch/scaffolds/common.dart';
import 'package:git_touch/widgets/issue_item.dart';
import 'package:git_touch/widgets/loading.dart';
2022-10-02 06:49:55 +02:00
import 'package:git_touch/widgets/repo_item.dart';
2021-01-06 07:57:31 +01:00
import 'package:git_touch/widgets/user_item.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago;
2020-11-01 17:32:47 +01:00
2021-01-06 07:57:31 +01:00
class GeSearchScreen extends StatefulWidget {
2020-11-01 17:32:47 +01:00
@override
2022-10-03 19:05:29 +02:00
State<GeSearchScreen> createState() => _GeSearchScreenState();
2021-01-06 07:57:31 +01:00
}
class _GeSearchScreenState extends State<GeSearchScreen> {
2021-05-16 09:16:35 +02:00
int? _activeTab = 0;
2021-01-06 07:57:31 +01:00
bool _loading = false;
2022-09-06 18:28:12 +02:00
final List<List> _payloads = [[], [], []];
2021-01-06 07:57:31 +01:00
2021-05-16 09:16:35 +02:00
TextEditingController? _controller;
2021-06-05 07:54:52 +02:00
String get _keyword => _controller!.text.trim();
2021-01-06 07:57:31 +01:00
@override
void initState() {
super.initState();
_controller = TextEditingController();
}
@override
void dispose() {
2021-05-16 09:16:35 +02:00
_controller!.dispose();
2021-01-06 07:57:31 +01:00
super.dispose();
}
Future<void> _query() async {
if (_loading || _keyword.isEmpty) return;
2022-09-24 07:41:46 +02:00
final keyword = _controller!.text;
2021-01-06 07:57:31 +01:00
setState(() {
_loading = true;
});
try {
final auth = context.read<AuthModel>();
final searchRepositories =
await auth.fetchGitee('/search/repositories?q=$keyword').then((v) {
return [for (var repo in v) GiteeRepo.fromJson(repo)];
});
final searchUsers =
await auth.fetchGitee('/search/users?q=$keyword').then((v) {
return [for (var user in v) GiteeUser.fromJson(user)];
});
final searchIssues =
await auth.fetchGitee('/search/issues?q=$keyword').then((v) {
return [for (var issue in v) GiteeIssue.fromJson(issue)];
});
_payloads[0] = searchRepositories;
_payloads[1] = searchUsers;
_payloads[2] = searchIssues;
} finally {
setState(() {
_loading = false;
});
}
}
2021-05-16 09:16:35 +02:00
_onTabSwitch(int? index) {
2021-01-06 07:57:31 +01:00
setState(() {
_activeTab = index;
});
2021-05-16 09:16:35 +02:00
if (_payloads[_activeTab!].isEmpty) {
2021-01-06 07:57:31 +01:00
_query();
}
}
static const tabs = ['Repositories', 'Users', 'Issues'];
Widget _buildItem(p) {
switch (_activeTab) {
case 0:
2022-10-02 06:49:55 +02:00
return RepoItem(
2021-01-06 07:57:31 +01:00
owner: p.namespace.path,
avatarUrl: p.owner.avatarUrl,
name: p.path,
description: p.description,
starCount: p.stargazersCount,
forkCount: p.forksCount,
note: 'Updated ${timeago.format(p.updatedAt)}',
url: '/gitee/${p.namespace.path}/${p.path}',
avatarLink: '/gitee/${p.namespace.path}',
);
case 1:
return UserItem.gitee(
login: p.login,
name: p.name,
avatarUrl: p.avatarUrl,
2022-09-06 18:28:12 +02:00
bio: Text(p.bio ?? p.htmlUrl),
2021-01-06 07:57:31 +01:00
);
default:
return IssueItem(
author: p.user.login,
avatarUrl: p.user.avatarUrl,
commentCount: p.comments,
2022-10-03 19:05:29 +02:00
subtitle: '#${p.number}',
2021-01-06 07:57:31 +01:00
title: p.title,
updatedAt: DateTime.parse(p.updatedAt),
url:
'/gitee/${p.repository.namespace.path}/${p.repository.path}/issues/${p.number}',
);
}
}
@override
Widget build(BuildContext context) {
2022-09-17 14:35:45 +02:00
return CommonScaffold(
title: Container(
2022-09-24 20:46:37 +02:00
color: AntTheme.of(context).colorBackground,
2022-09-17 14:35:45 +02:00
child: CupertinoTextField(
prefix: Row(
children: const <Widget>[
SizedBox(width: 8),
Icon(Octicons.search, size: 20, color: PrimerColors.gray400),
],
),
placeholder: AppLocalizations.of(context)!.search,
clearButtonMode: OverlayVisibilityMode.editing,
textInputAction: TextInputAction.go,
onSubmitted: (_) => _query(),
controller: _controller,
),
),
2021-01-06 07:57:31 +01:00
body: SingleChildScrollView(
child: Column(
children: [
2022-09-17 14:46:39 +02:00
Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: CupertinoSlidingSegmentedControl(
groupValue: _activeTab,
onValueChanged: _onTabSwitch,
children: tabs.asMap().map((key, text) => MapEntry(
key,
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Text(text, style: const TextStyle(fontSize: 14)),
))),
2021-01-06 07:57:31 +01:00
),
),
2022-09-17 14:46:39 +02:00
),
2021-01-06 07:57:31 +01:00
if (_loading)
2022-09-06 18:28:12 +02:00
const Loading()
2021-01-06 07:57:31 +01:00
else
2021-05-16 09:16:35 +02:00
..._payloads[_activeTab!].map(_buildItem).toList(),
2021-01-06 07:57:31 +01:00
],
),
),
2020-11-01 17:32:47 +01:00
);
}
}