Skip to content

Commit

Permalink
draft web
Browse files Browse the repository at this point in the history
  • Loading branch information
sherlockvn committed Dec 11, 2023
1 parent 1983317 commit dfda829
Show file tree
Hide file tree
Showing 20 changed files with 538 additions and 194 deletions.
3 changes: 2 additions & 1 deletion assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2966,5 +2966,6 @@
"sharedMediaAndFiles": "Shared media and files",
"unpinAllMessages": "Unpin all messages",
"pinnedMessagesTooltip": "Pinned messages",
"jumpToMessage": "Jump to message"
"jumpToMessage": "Jump to message",
"failedToUnpin": "Failed to unpin message"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ import 'package:matrix/matrix.dart';
class ChatGetPinnedEventsInteractor {
Stream<Either<Failure, Success>> execute({
required Room room,
List<Event?>? eventsInMem,
}) async* {
Logs().d(
"ChatGetPinnedEventsInteractor()::execute()::roomId: ${room.id}",
);
yield Right(ChatGetPinnedEventsLoading());
try {
if (eventsInMem != null && eventsInMem.isNotEmpty) {
yield Right(ChatGetPinnedEventsSuccess(pinnedEvents: eventsInMem));
return;
}
final pinnedEvents = room.pinnedEventIds;
final result = await Future.wait(
pinnedEvents.map(room.getEventById),
Expand Down
20 changes: 18 additions & 2 deletions lib/pages/chat/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ class ChatController extends State<Chat>
inputFocus.requestFocus();
}

void scrollToEventIdAndHighlight(String eventId) {
Future<void> scrollToEventIdAndHighlight(String eventId) {
return scrollToEventId(eventId, highlight: true);
}

Expand Down Expand Up @@ -834,7 +834,7 @@ class ChatController extends State<Chat>
}
}

void scrollToEventId(String eventId, {bool highlight = false}) async {
Future<void> scrollToEventId(String eventId, {bool highlight = false}) async {
final eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId);
if (eventIndex == -1) {
timeline = null;
Expand Down Expand Up @@ -1439,6 +1439,22 @@ class ChatController extends State<Chat>
}
}

void handlePopBackFromPinnedScreen(Object? popResult) async {
Logs().d(
"PinnedEventsController()::handlePopBack(): popResult: $popResult",
);
if (popResult is Event) {
await TwakeDialog.showFutureLoadingDialogFullScreen(
future: () => scrollToEventIdAndHighlight(popResult.eventId),
);
} else if (popResult is List<Event?>) {
final room = popResult.first?.room;
if (room != null) {
pinnedEventsController.handlePopBack(popResult);
}
}
}

@override
Widget build(BuildContext context) {
return ChatView(this, key: widget.key);
Expand Down
26 changes: 24 additions & 2 deletions lib/pages/chat/chat_pinned_events/pinned_events_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@ class PinnedEventsController {

void getPinnedMessageAction({
required Room room,
List<Event?>? eventsInMem,
bool isInitial = false,
String? eventId,
}) async {
await Future.delayed(_timeDelayGetPinnedMessage);
_pinnedEventsSubscription =
getPinnedMessageInteractor.execute(room: room).listen((event) {
_pinnedEventsSubscription = getPinnedMessageInteractor
.execute(
room: room,
eventsInMem: eventsInMem,
)
.listen((event) {
getPinnedMessageNotifier.value = event;
event.fold((_) => null, (success) {
if (success is ChatGetPinnedEventsSuccess) {
Expand Down Expand Up @@ -96,6 +101,23 @@ class PinnedEventsController {
);
}

void handlePopBack(Object? popResult) {
Logs().d(
"PinnedEventsController()::handlePopBack(): popResult: $popResult",
);
if (popResult is Event) {
} else if (popResult is List<Event?>) {
final room = popResult.first?.room;
if (room != null) {
getPinnedMessageAction(
room: room,
eventsInMem: popResult,
isInitial: true,
);
}
}
}

void jumpToCurrentMessage(
List<Event?> pinnedEvents, {
String? eventId,
Expand Down
2 changes: 2 additions & 0 deletions lib/pages/chat/chat_pinned_events/pinned_events_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import 'package:flutter/material.dart';

class PinnedEventsStyle {
static const double maxHeight = 48;
static const double maxWidthContextItem = 100;
static const double minWidthContextItem = 80;
static const double minHeightIndicator = 12;
static const double maxWidthIndicator = 2.0;
static const double maxLengthIndicator = 5.0;
Expand Down
9 changes: 7 additions & 2 deletions lib/pages/chat/chat_pinned_events/pinned_events_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,19 @@ class PinnedEventsView extends StatelessWidget {
margin: PinnedEventsStyle.marginPinIcon,
paddingAll:
PinnedEventsStyle.paddingPinIcon,
onTap: () {
context.pushChild(
onTap: () async {
final popResult =
await context.pushChild(
'pinnedmessages',
extra: PinnedEventsArgument(
pinnedEvents: data.pinnedEvents,
timeline: controller.timeline,
),
);
controller
.handlePopBackFromPinnedScreen(
popResult,
);
},
),
],
Expand Down
58 changes: 23 additions & 35 deletions lib/pages/chat/chat_pinned_events/pinned_messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:fluffychat/presentation/model/chat/pop_up_menu_item_model.dart';
import 'package:fluffychat/resource/image_paths.dart';
import 'package:fluffychat/utils/extension/build_context_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
import 'package:fluffychat/utils/twake_snackbar.dart';
import 'package:fluffychat/widgets/mixins/popup_context_menu_action_mixin.dart';
import 'package:fluffychat/widgets/mixins/popup_menu_widget_mixin.dart';
import 'package:flutter/material.dart';
Expand All @@ -22,28 +23,43 @@ class PinnedMessages extends StatefulWidget {

class PinnedMessagesController extends State<PinnedMessages>
with PopupContextMenuActionMixin, PopupMenuWidgetMixin {
List<Event?> get events => widget.events;
ValueNotifier<List<Event?>> eventsNotifier = ValueNotifier([]);

final ValueNotifier<String?> isHoverNotifier = ValueNotifier(null);

final ScrollController scrollController = ScrollController();

final MenuController menuController = MenuController();

List<PopupMenuItemModel> get pinnedMessagesActionsList => [
PopupMenuItemModel(
text: L10n.of(context)!.unpin,
imagePath: ImagePaths.icUnpin,
color: Theme.of(context).colorScheme.onSurface,
onTap: ({extra}) async {
if (extra is Event) {
await extra.unpin();
Navigator.of(context).pop();
final result = await extra.unpin();
if (result) {
eventsNotifier.value.remove(extra);
eventsNotifier.value = List.from(eventsNotifier.value);
if (eventsNotifier.value.isEmpty) {
Navigator.of(context).pop(eventsNotifier.value);
}
} else {
TwakeSnackBar.show(context, L10n.of(context)!.failedToUnpin);
}
}
},
),
PopupMenuItemModel(
text: L10n.of(context)!.jumpToMessage,
imagePath: ImagePaths.icJumpTo,
color: Theme.of(context).colorScheme.onSurface,
onTap: ({extra}) async {
if (extra is Event) {
Navigator.pop(context, extra);
}
},
),
PopupMenuItemModel(
text: L10n.of(context)!.copy,
Expand All @@ -52,7 +68,6 @@ class PinnedMessagesController extends State<PinnedMessages>
onTap: ({extra}) async {
if (extra is Event && widget.timeline != null) {
await extra.copy(context, widget.timeline!);
Navigator.of(context).pop();
}
},
),
Expand Down Expand Up @@ -84,37 +99,10 @@ class PinnedMessagesController extends State<PinnedMessages>
);
}

void handleContextMenuActionInEachMessage(
BuildContext context,
Event event, {
RelativeRect? relativeRect,
}) {
openPopupMenuAction(
context,
relativeRect ?? context.getCurrentRelativeRectOfWidget(),
_popupMenuActionTile(context, event),
);
}

List<PopupMenuItem> _popupMenuActionTile(
BuildContext context,
Event event,
) {
return pinnedMessagesActionsList
.map(
(action) => PopupMenuItem(
padding: EdgeInsets.zero,
child: popupItemByTwakeAppRouter(
context,
action.text,
iconAction: action.iconData,
imagePath: action.imagePath,
colorIcon: action.color,
onCallbackAction: () => action.onTap?.call(extra: event),
),
),
)
.toList();
@override
void initState() {
super.initState();
eventsNotifier.value = widget.events;
}

@override
Expand Down
129 changes: 88 additions & 41 deletions lib/pages/chat/chat_pinned_events/pinned_messages_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ class PinnedMessagesScreen extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
L10n.of(context)!.pinnedMessages(controller.events.length),
title: ValueListenableBuilder(
valueListenable: controller.eventsNotifier,
builder: (context, events, child) {
return Text(
L10n.of(context)!.pinnedMessages(events.length),
);
},
),
leading: TwakeIconButton(
tooltip: L10n.of(context)!.back,
Expand All @@ -47,48 +52,90 @@ class PinnedMessagesScreen extends StatelessWidget {
Expanded(
child: Padding(
padding: PinnedMessagesStyle.paddingListMessages(context),
child: ListView.custom(
controller: controller.scrollController,
shrinkWrap: true,
reverse: true,
childrenDelegate: SliverChildBuilderDelegate(
(context, index) {
// The message at this index:
final currentEventIndex =
controller.events.length - index - 1;
final event = controller.events[currentEventIndex];
final nextEvent = currentEventIndex > 0
? controller.events[currentEventIndex - 1]
: null;
final previousEvent =
currentEventIndex < controller.events.length - 1
? controller.events[currentEventIndex + 1]
child: ValueListenableBuilder(
valueListenable: controller.eventsNotifier,
builder: (context, events, child) {
return ListView.custom(
controller: controller.scrollController,
shrinkWrap: true,
reverse: true,
childrenDelegate: SliverChildBuilderDelegate(
(context, index) {
// The message at this index:
final currentEventIndex = events.length - index - 1;
final event = events[currentEventIndex];
final nextEvent = currentEventIndex > 0
? events[currentEventIndex - 1]
: null;
return Builder(
builder: (context) {
return GestureDetector(
onSecondaryTapDown: (details) {
controller.handleContextMenuActionInEachMessage(
context,
event,
);
},
child: Message(
event!,
previousEvent: previousEvent,
nextEvent: nextEvent,
timeline: controller.widget.timeline!,
isHoverNotifier: controller.isHoverNotifier,
listHorizontalActionMenu: const [],
longPressSelect: true,
selectMode: false,
),
final previousEvent =
currentEventIndex < events.length - 1
? events[currentEventIndex + 1]
: null;
return Message(
event!,
previousEvent: previousEvent,
nextEvent: nextEvent,
timeline: controller.widget.timeline!,
isHoverNotifier: controller.isHoverNotifier,
listHorizontalActionMenu: const [],
longPressSelect: true,
selectMode: false,
menuChildren: (context) => controller
.pinnedMessagesActionsList
.map(
(action) => InkWell(
onTap: () {
action.onTap?.call(extra: event);
Navigator.of(context).pop();
},
child: Container(
height: PinnedMessagesStyle
.heightContextMenuItem,
padding: const EdgeInsets.all(
PinnedMessagesStyle
.paddingAllContextMenuItem,
),
child: Row(
children: [
if (action.imagePath != null)
SvgPicture.asset(
action.imagePath!,
colorFilter: ColorFilter.mode(
action.color ??
Theme.of(context)
.colorScheme
.primary,
BlendMode.srcIn,
),
),
if (action.iconData != null)
Icon(
action.iconData,
color: action.color,
),
if (action.imagePath != null ||
action.iconData != null)
PinnedMessagesStyle
.paddingIconAndUnpin,
Text(
action.text,
style: Theme.of(context)
.textTheme
.labelLarge
?.copyWith(color: action.color),
),
],
),
),
),
)
.toList(),
);
},
);
},
childCount: controller.events.length,
),
childCount: controller.eventsNotifier.value.length,
),
);
},
),
),
),
Expand Down
Loading

0 comments on commit dfda829

Please sign in to comment.