Skip to content

Commit

Permalink
TW-403: refactor chat_list and forward screen
Browse files Browse the repository at this point in the history
  • Loading branch information
sherlockvn committed Aug 25, 2023
1 parent e20bc9f commit 4eb6085
Show file tree
Hide file tree
Showing 7 changed files with 495 additions and 423 deletions.
87 changes: 7 additions & 80 deletions lib/pages/chat_list/chat_list.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:io';

import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:async/async.dart';
Expand All @@ -10,12 +9,12 @@ import 'package:fluffychat/domain/usecases/get_recovery_words_interactor.dart';
import 'package:fluffychat/mixin/comparable_presentation_contact_mixin.dart';
import 'package:fluffychat/pages/bootstrap/tom_bootstrap_dialog.dart';
import 'package:fluffychat/pages/chat_list/chat_list_view.dart';
import 'package:fluffychat/pages/chat_list/receive_sharing_intent_mixin.dart';
import 'package:fluffychat/pages/settings_security/settings_security.dart';
import 'package:fluffychat/utils/famedlysdk_store.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:fluffychat/utils/tor_stub.dart'
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
import 'package:flutter/foundation.dart';
Expand All @@ -24,14 +23,9 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
import 'package:go_router/go_router.dart';
import 'package:matrix/matrix.dart';
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
import 'package:uni_links/uni_links.dart';

import '../../../utils/account_bundles.dart';
import '../../utils/matrix_sdk_extensions/matrix_file_extension.dart';
import '../../utils/url_launcher.dart';
import '../../utils/voip/callkeep_manager.dart';
import '../../widgets/fluffy_chat_app.dart';
import '../../widgets/matrix.dart';
import '../bootstrap/bootstrap_dialog.dart';

Expand Down Expand Up @@ -80,13 +74,8 @@ class ChatListController extends State<ChatList>
with
TickerProviderStateMixin,
RouteAware,
ComparablePresentationContactMixin {
StreamSubscription? _intentDataStreamSubscription;

StreamSubscription? _intentFileStreamSubscription;

StreamSubscription? _intentUriStreamSubscription;

ComparablePresentationContactMixin,
ReceiveSharingIntentMixin {
final _getRecoveryWordsInteractor = getIt.get<GetRecoveryWordsInteractor>();

bool get displayNavigationBar => false;
Expand Down Expand Up @@ -287,71 +276,9 @@ class ChatListController extends State<ChatList>
? SelectMode.normal
: SelectMode.select;

void _processIncomingSharedFiles(List<SharedMediaFile> files) {
if (files.isEmpty) return;
final file = File(files.first.path.replaceFirst('file://', ''));

Matrix.of(context).shareContent = {
'msgtype': 'chat.fluffy.shared_file',
'file': MatrixFile(
bytes: file.readAsBytesSync(),
name: file.path,
).detectFileType,
};
context.go('/rooms');
}

void _processIncomingSharedText(String? text) {
if (text == null) return;
if (text.toLowerCase().startsWith(AppConfig.deepLinkPrefix) ||
text.toLowerCase().startsWith(AppConfig.inviteLinkPrefix) ||
(text.toLowerCase().startsWith(AppConfig.schemePrefix) &&
!RegExp(r'\s').hasMatch(text))) {
return _processIncomingUris(text);
}
Matrix.of(context).shareContent = {
'msgtype': 'm.text',
'body': text,
};
context.go('/rooms');
}

void _processIncomingUris(String? text) async {
if (text == null) return;
context.go('/rooms');
WidgetsBinding.instance.addPostFrameCallback((_) {
UrlLauncher(context, text).openMatrixToUrl();
});
}

void _initReceiveSharingIntent() {
if (!PlatformInfos.isMobile) return;

// For sharing images coming from outside the app while the app is in the memory
_intentFileStreamSubscription = ReceiveSharingIntent.getMediaStream()
.listen(_processIncomingSharedFiles, onError: print);

// For sharing images coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialMedia().then(_processIncomingSharedFiles);

// For sharing or opening urls/text coming from outside the app while the app is in the memory
_intentDataStreamSubscription = ReceiveSharingIntent.getTextStream()
.listen(_processIncomingSharedText, onError: print);

// For sharing or opening urls/text coming from outside the app while the app is closed
ReceiveSharingIntent.getInitialText().then(_processIncomingSharedText);

// For receiving shared Uris
_intentUriStreamSubscription = linkStream.listen(_processIncomingUris);
if (FluffyChatApp.gotInitialLink == false) {
FluffyChatApp.gotInitialLink = true;
getInitialLink().then(_processIncomingUris);
}
}

@override
void initState() {
_initReceiveSharingIntent();
initReceiveSharingIntent();

scrollController.addListener(_onScroll);
_waitForFirstSync();
Expand All @@ -370,9 +297,9 @@ class ChatListController extends State<ChatList>

@override
void dispose() {
_intentDataStreamSubscription?.cancel();
_intentFileStreamSubscription?.cancel();
_intentUriStreamSubscription?.cancel();
intentDataStreamSubscription?.cancel();
intentFileStreamSubscription?.cancel();
intentUriStreamSubscription?.cancel();
scrollController.removeListener(_onScroll);
super.dispose();
}
Expand Down
234 changes: 103 additions & 131 deletions lib/pages/chat_list/chat_list_header.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:fluffychat/pages/chat_list/chat_list.dart';
import 'package:fluffychat/pages/chat_list/chat_list_header_style.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/twake_components/twake_header.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
Expand All @@ -19,143 +18,116 @@ class ChatListHeader extends StatelessWidget {
Widget build(BuildContext context) {
final selectMode = controller.selectMode;

Widget child;

switch (selectMode) {
case SelectMode.select:
child = selectModeWidgets(context);
case SelectMode.normal:
child = normalModeWidgets(context);
case SelectMode.share:
child = const SizedBox.shrink();
default:
child = normalModeWidgets(context);
}

return Column(
children: [
TwakeHeader(controller: controller),
Container(
height: ChatListHeaderStyle.searchBarContainerHeight,
height: selectMode == SelectMode.share
? 0
: ChatListHeaderStyle.searchBarContainerHeight,
padding: const EdgeInsets.symmetric(vertical: 0.0, horizontal: 16.0),
child: Row(
children: [
if (selectMode == SelectMode.select)
IconButton(
tooltip: L10n.of(context)!.cancel,
icon: const Icon(Icons.close_outlined),
onPressed: controller.cancelAction,
color: Theme.of(context).colorScheme.primary,
),
Expanded(
child: selectMode == SelectMode.select
? Text(
controller.selectedRoomIds.length.toString(),
key: const ValueKey(SelectMode.select),
)
: SizedBox(
height: ChatListHeaderStyle.searchBarHeight,
child: InkWell(
onTap: onOpenSearchPage,
child: TextField(
controller: controller.searchChatController,
textInputAction: TextInputAction.search,
onChanged: controller.onSearchEnter,
enabled: false,
decoration: InputDecoration(
filled: true,
contentPadding: const EdgeInsets.all(0),
fillColor: Theme.of(context).colorScheme.surface,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(
ChatListHeaderStyle.searchRadiusBorder,
),
),
hintText: L10n.of(context)!.search,
floatingLabelBehavior:
FloatingLabelBehavior.never,
prefixIcon: controller.isSearchMode
? IconButton(
tooltip: L10n.of(context)!.cancel,
icon: const Icon(
Icons.close_outlined,
),
onPressed: controller.cancelSearch,
color: Theme.of(context)
.colorScheme
.onBackground,
)
: Icon(
Icons.search_outlined,
color: Theme.of(context)
.colorScheme
.onBackground,
),
suffixIcon: controller.isSearchMode
? controller.isSearching
? const Padding(
padding: EdgeInsets.symmetric(
vertical: 9.0,
horizontal: 14.0,
),
child: SizedBox.square(
dimension: 20,
child: CircularProgressIndicator
.adaptive(
strokeWidth: 2,
),
),
)
: TextButton(
onPressed: controller.setServer,
style: TextButton.styleFrom(
textStyle: const TextStyle(
fontSize: 12,
),
),
child: Text(
controller.searchServer ??
Matrix.of(context)
.client
.homeserver!
.host,
maxLines: 2,
),
)
: const SizedBox.shrink(),
),
),
),
),
),
if (selectMode == SelectMode.select)
IconButton(
tooltip: L10n.of(context)!.toggleUnread,
icon: Icon(
controller.anySelectedRoomNotMarkedUnread
? Icons.mark_chat_read_outlined
: Icons.mark_chat_unread_outlined,
),
onPressed: controller.toggleUnread,
),
if (selectMode == SelectMode.select)
IconButton(
tooltip: L10n.of(context)!.toggleFavorite,
icon: Icon(
controller.anySelectedRoomNotFavorite
? Icons.push_pin_outlined
: Icons.push_pin,
),
onPressed: controller.toggleFavouriteRoom,
),
if (selectMode == SelectMode.select)
IconButton(
icon: Icon(
controller.anySelectedRoomNotMuted
? Icons.notifications_off_outlined
: Icons.notifications_outlined,
),
tooltip: L10n.of(context)!.toggleMuted,
onPressed: controller.toggleMuted,
),
if (selectMode == SelectMode.select)
IconButton(
icon: const Icon(Icons.archive_outlined),
tooltip: L10n.of(context)!.archive,
onPressed: controller.archiveAction,
),
],
),
child: child,
)
],
);
}

Widget selectModeWidgets(BuildContext context) {
return Row(
children: [
IconButton(
tooltip: L10n.of(context)!.cancel,
icon: const Icon(Icons.close_outlined),
onPressed: controller.cancelAction,
color: Theme.of(context).colorScheme.primary,
),
Expanded(
child: Text(
controller.selectedRoomIds.length.toString(),
key: const ValueKey(SelectMode.select),
),
),
IconButton(
tooltip: L10n.of(context)!.toggleUnread,
icon: Icon(
controller.anySelectedRoomNotMarkedUnread
? Icons.mark_chat_read_outlined
: Icons.mark_chat_unread_outlined,
),
onPressed: controller.toggleUnread,
),
IconButton(
tooltip: L10n.of(context)!.toggleFavorite,
icon: Icon(
controller.anySelectedRoomNotFavorite
? Icons.push_pin_outlined
: Icons.push_pin,
),
onPressed: controller.toggleFavouriteRoom,
),
IconButton(
icon: Icon(
controller.anySelectedRoomNotMuted
? Icons.notifications_off_outlined
: Icons.notifications_outlined,
),
tooltip: L10n.of(context)!.toggleMuted,
onPressed: controller.toggleMuted,
),
IconButton(
icon: const Icon(Icons.archive_outlined),
tooltip: L10n.of(context)!.archive,
onPressed: controller.archiveAction,
),
],
);
}

Widget normalModeWidgets(BuildContext context) => Row(
children: [
Expanded(
child: InkWell(
borderRadius: BorderRadius.circular(24.0),
onTap: onOpenSearchPage,
child: TextField(
controller: controller.searchChatController,
textInputAction: TextInputAction.search,
onChanged: controller.onSearchEnter,
enabled: false,
decoration: InputDecoration(
filled: true,
contentPadding: const EdgeInsets.all(0),
fillColor: Theme.of(context).colorScheme.surface,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(
ChatListHeaderStyle.searchRadiusBorder,
),
),
hintText: L10n.of(context)!.search,
floatingLabelBehavior: FloatingLabelBehavior.never,
prefixIcon: Icon(
Icons.search_outlined,
color: Theme.of(context).colorScheme.onBackground,
),
suffixIcon: const SizedBox.shrink(),
),
),
),
),
],
);
}
Loading

0 comments on commit 4eb6085

Please sign in to comment.