Skip to content

Commit

Permalink
Issue krille-chan#17 + krille-chan#23 Fluffychat: clear search result…
Browse files Browse the repository at this point in the history
…s, back to top button
  • Loading branch information
carowebtec authored and Matthias committed Dec 2, 2022
1 parent e3a56f0 commit 4923b16
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 82 deletions.
97 changes: 49 additions & 48 deletions lib/pages/chat_search/chat_search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,48 @@ import 'package:flutter/cupertino.dart';
import 'package:matrix/matrix.dart';
import 'package:vrouter/vrouter.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:scroll_to_index/scroll_to_index.dart';

enum SearchState {
searching,
finished,
noResult
}
enum SearchState { searching, finished, noResult }

class ChatSearch extends StatefulWidget {
const ChatSearch({Key? key}) : super(key: key);

@override ChatSearchController createState() => ChatSearchController();
@override
ChatSearchController createState() => ChatSearchController();
}

class ChatSearchController extends State<ChatSearch> {

String? get roomId => VRouter.of(context).pathParameters['roomid'];
Timeline? timeline;
Room? room;

Stream<List<Event>>? searchResultStream;
final TextEditingController searchController = TextEditingController();
String? searchError;
String lastSearchTerm = "";
SearchState searchState = SearchState.noResult;
bool searchResultsFound = false;
String searchTerm = "";

final AutoScrollController scrollController = AutoScrollController();
bool showScrollToTopButton = false;

static const fixedWidth = 360.0;

@override
void initState() {
super.initState();
scrollController.addListener(_updateScrollController);
searchResultStream = _emptyList();

super.initState();
}

Future<bool> getTimeline() async {

room ??= Matrix.of(context).client.getRoomById(roomId!)!;

if (timeline == null) {

await Matrix.of(context).client.roomsLoading;
await Matrix.of(context).client.accountDataLoading;
timeline = await room!.getTimeline();
Expand All @@ -54,62 +57,59 @@ class ChatSearchController extends State<ChatSearch> {
return true;
}

String searchTerm = "";
bool searchFunc(Event event) {
void _updateScrollController() {
if (!scrollController.hasClients) return;

bool found = false;
if(event.type == EventTypes.Message) {
found = event.body.toLowerCase().contains(searchTerm.toLowerCase());
if (scrollController.position.pixels > 0 && showScrollToTopButton == false) {
setState(() => showScrollToTopButton = true);
} else if (scrollController.position.pixels == 0 &&
showScrollToTopButton == true) {
setState(() => showScrollToTopButton = false);
}

return found;
}

bool searchFunction(Event event) {
if (event.type == EventTypes.Message) {
return event.body.toLowerCase().contains(searchTerm.toLowerCase());
} else {
return false;
}
}

void search() async {
try {

searchError = null;
searchTerm = searchController.text;

// start search only if a new search word was entered
// start search only if a new search term was entered
if (searchTerm != lastSearchTerm) {

lastSearchTerm = searchTerm;

// set back UI
searchError = null;
searchResultsFound = false;
searchState = SearchState.noResult;
setState(() {});

if (searchTerm.isNotEmpty) {

searchResultStream = timeline?.searchEvent(
searchTerm: searchTerm,
requestHistoryCount: 30,
maxHistoryRequests: 30,
searchFunc: searchFunc).asBroadcastStream();
searchResultStream = timeline
?.searchEvent(
searchTerm: searchTerm,
requestHistoryCount: 30,
maxHistoryRequests: 30,
searchFunc: searchFunction)
.asBroadcastStream();

searchState = SearchState.searching;
searchResultStream?.listen(_listenToSearchStream,
onDone: () => searchState = SearchState.finished,
onError: (error) {
searchState = SearchState.finished;
searchError = L10n.of(context)?.searchError;
},
cancelOnError: true
);


}
else {
searchResultStream = _emptyList().asBroadcastStream();
searchState = SearchState.finished;
searchError = L10n.of(context)?.searchError;
},
cancelOnError: true);
} else {
searchResultStream = _emptyList();
searchState = SearchState.noResult;
}

setState(() {});
}

} catch (e) {
searchError = L10n.of(context)?.searchError;
}
Expand All @@ -119,20 +119,21 @@ class ChatSearchController extends State<ChatSearch> {
searchResultsFound = true;
}


Stream<List<Event>> _emptyList() async* {
yield <Event>[];
}

void unfold(String eventId) {

}
void unfold(String eventId) {}

void onSelectMessage(Event event) {
VRouter.of(context).path.startsWith('/spaces/')
? VRouter.of(context).pop()
: VRouter.of(context)
.toSegments(['rooms', roomId!], queryParameters: {'event': event.eventId});
: VRouter.of(context).toSegments(['rooms', roomId!],
queryParameters: {'event': event.eventId});
}

void scrollToTop() {
scrollController.jumpTo(0);
}

@override
Expand All @@ -142,4 +143,4 @@ class ChatSearchController extends State<ChatSearch> {
child: ChatSearchView(this),
);
}
}
}
61 changes: 27 additions & 34 deletions lib/pages/chat_search/chat_search_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,18 @@ class ChatSearchView extends StatelessWidget {
future: controller.getTimeline(),
builder: (BuildContext context, snapshot) {
return Scaffold(
floatingActionButton: controller.showScrollToTopButton
?Padding(
padding: const EdgeInsets.only(bottom: 56.0),
child: FloatingActionButton(
onPressed: controller.scrollToTop,
mini: true,
child: const Icon(Icons.arrow_upward_outlined),
)
)
: null,
body: NestedScrollView(
controller: controller.scrollController,
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) => <Widget>[
SliverAppBar(
Expand Down Expand Up @@ -89,8 +100,7 @@ class ChatSearchView extends StatelessWidget {
itemCount: (snapshot.hasData
? snapshot.data!.length + 1
: 1),
itemBuilder: (BuildContext context, int i) => i ==
0
itemBuilder: (BuildContext context, int i) => i == 0
? Column(children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
Expand Down Expand Up @@ -118,23 +128,15 @@ class ChatSearchView extends StatelessWidget {
),
],
),
!controller.searchResultsFound &&
(controller.searchState ==
SearchState.noResult ||
controller.searchState ==
SearchState.finished)
? ListTile(
title: Text(L10n.of(context)!
.noSearchResult))
: Container(),
!controller.searchResultsFound &&
controller.searchState ==
SearchState.searching
? Center(
child: CircularProgressIndicator
.adaptive(strokeWidth: 2),
)
: Container(),
if(!controller.searchResultsFound)
if (controller.searchState == SearchState.noResult ||
controller.searchState == SearchState.finished)
ListTile(
title: Text(L10n.of(context)!.noSearchResult))
else if(controller.searchState == SearchState.searching)
Center(
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
),
])
: controller.searchResultsFound
? Column(
Expand All @@ -144,21 +146,12 @@ class ChatSearchView extends StatelessWidget {
Message(snapshot.data![i - 1],
onSwipe: (direction) => {},
unfold: controller.unfold,
onSelect: controller
.onSelectMessage,
timeline:
controller.timeline!),
i == snapshot.data?.length &&
controller.searchState ==
SearchState.searching
? Center(
child:
CircularProgressIndicator
.adaptive(
strokeWidth:
2),
)
: Container()
onSelect: controller.onSelectMessage,
timeline: controller.timeline!),
if(i == snapshot.data?.length && controller.searchState == SearchState.searching)
Center(
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
),
])
: Container());
}),
Expand Down

0 comments on commit 4923b16

Please sign in to comment.