139 lines
4.5 KiB
Dart
139 lines
4.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:localization/localization.dart';
|
|
import 'package:loris/business_logic/account/account.dart';
|
|
import 'package:loris/business_logic/timeline/timeline.dart';
|
|
import 'package:loris/global.dart' as global;
|
|
import 'package:loris/business_logic/search/search.dart' as logic;
|
|
import 'package:loris/themes/themes.dart' as themes;
|
|
|
|
import '../../partials/post.dart';
|
|
|
|
class SearchPage extends StatefulWidget {
|
|
const SearchPage({super.key});
|
|
|
|
@override
|
|
State<SearchPage> createState() => _SearchPageState();
|
|
}
|
|
|
|
class _SearchPageState extends State<SearchPage> {
|
|
String searchText = "";
|
|
String searchTextControl = "";
|
|
Map<String, logic.SearchResult> results = {};
|
|
int searched = 0;
|
|
|
|
void searchSingle(String id) async {
|
|
final result = await logic.searchForEntry(searchText, id);
|
|
if (result.key == 200 && mounted) {
|
|
setState(() {
|
|
results.addAll({id: result.value!});
|
|
searched++;
|
|
});
|
|
}
|
|
}
|
|
|
|
void search() {
|
|
searched = 0;
|
|
searchTextControl = searchText;
|
|
for (var id in global.settings!.identities.keys.toList()) {
|
|
searchSingle(id);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
List<AccountModel> accountModels = [];
|
|
List<PostModel> postModels = [];
|
|
results.forEach(
|
|
(key, value) {
|
|
for (var m in value.accountModels) {
|
|
accountModels.add(m);
|
|
}
|
|
for (var m in value.postModels) {
|
|
postModels.add(m);
|
|
}
|
|
},
|
|
);
|
|
return Container(
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
bottom: BorderSide(
|
|
color: Theme.of(context).colorScheme.primary,
|
|
width: 2,
|
|
))),
|
|
child: Material(
|
|
child: Column(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
TextField(
|
|
style: Theme.of(context).textTheme.bodyMedium,
|
|
autofocus: true,
|
|
keyboardType: TextInputType.url,
|
|
onEditingComplete: () {
|
|
if (searchText.isNotEmpty) {
|
|
search();
|
|
}
|
|
},
|
|
onChanged: ((value) => setState(() {
|
|
searchText = value;
|
|
})),
|
|
decoration: InputDecoration(
|
|
prefixIcon: Icon(
|
|
color: Theme.of(context).colorScheme.primary,
|
|
Icons.search,
|
|
))),
|
|
if (searched < global.settings!.identities.length &&
|
|
searchTextControl.isNotEmpty)
|
|
Column(
|
|
children: [
|
|
SelectableText(
|
|
"${"searched".i18n()} $searched ${searched == 1 ? "instance".i18n() : "instances".i18n()}"),
|
|
const LinearProgressIndicator(),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
Expanded(
|
|
child: Container(
|
|
width: global.getWidth(context),
|
|
constraints: BoxConstraints(
|
|
maxWidth: global.getConstraints(context).maxWidth,
|
|
),
|
|
child: ListView.builder(
|
|
shrinkWrap: true,
|
|
itemCount: accountModels.length + postModels.length,
|
|
itemBuilder: (context, index) {
|
|
if (index < accountModels.length) {
|
|
final model = accountModels[index];
|
|
return Padding(
|
|
padding: themes.defaultMargins,
|
|
child: Column(
|
|
children: [
|
|
SelectableText(model.identity),
|
|
DisplayName(account: model)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
final model = postModels[index - accountModels.length];
|
|
return Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: [
|
|
SelectableText(model.identity),
|
|
Post(
|
|
model: model,
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|