Scroll to make space for toolbar

This commit is contained in:
Kelrap 2024-07-15 16:07:21 -04:00
parent 87b1b98f0e
commit 3da1f79863
7 changed files with 56 additions and 10 deletions

View file

@ -168,6 +168,7 @@ class ChatEventList extends StatelessWidget {
onSelect: controller.onSelectMessage,
scrollToEventId: (String eventId) =>
controller.scrollToEventId(eventId),
scrollController: controller.scrollController,
longPressSelect: controller.selectedEvents.isNotEmpty,
// #Pangea
selectedDisplayLang:

View file

@ -43,6 +43,7 @@ class Message extends StatelessWidget {
final bool immersionMode;
final bool definitions;
final ChatController controller;
final ScrollController scrollController;
// Pangea#
final Color? avatarPresenceBackgroundColor;
@ -68,6 +69,7 @@ class Message extends StatelessWidget {
required this.immersionMode,
required this.definitions,
required this.controller,
required this.scrollController,
// Pangea#
super.key,
});
@ -317,10 +319,12 @@ class Message extends StatelessWidget {
padding: const EdgeInsets.only(left: 8),
child: GestureDetector(
// #Pangea
onTap: () =>
toolbarController?.showToolbar(context),
onDoubleTap: () =>
toolbarController?.showToolbar(context),
onTap: () => toolbarController?.showToolbar(
context,
scrollController,
),
onDoubleTap: () => toolbarController
?.showToolbar(context, scrollController),
// Pangea#
onLongPress: longPressSelect
? null
@ -443,6 +447,8 @@ class Message extends StatelessWidget {
immersionMode: immersionMode,
toolbarController:
toolbarController,
scrollController:
scrollController,
// Pangea#
),
if (event.hasAggregatedEvents(
@ -588,7 +594,9 @@ class Message extends StatelessWidget {
: MainAxisAlignment.start,
children: [
if (pangeaMessageEvent?.showMessageButtons ?? false)
MessageButtons(toolbarController: toolbarController),
MessageButtons(
toolbarController: toolbarController,
scrollController: scrollController),
MessageReactions(event, timeline),
],
),

View file

@ -39,6 +39,7 @@ class MessageContent extends StatelessWidget {
final bool immersionMode;
final ToolbarDisplayController? toolbarController;
final bool isOverlay;
final ScrollController scrollController;
// Pangea#
const MessageContent(
@ -52,6 +53,7 @@ class MessageContent extends StatelessWidget {
required this.immersionMode,
required this.toolbarController,
this.isOverlay = false,
required this.scrollController,
// Pangea#
required this.borderRadius,
});
@ -299,6 +301,7 @@ class MessageContent extends StatelessWidget {
style: messageTextStyle,
pangeaMessageEvent: pangeaMessageEvent!,
immersionMode: immersionMode,
scrollController: scrollController,
toolbarController: toolbarController,
);
} else if (pangeaMessageEvent != null) {
@ -322,7 +325,8 @@ class MessageContent extends StatelessWidget {
toolbarController?.toolbar?.textSelection
.onTextSelection(selection);
},
onTap: () => toolbarController?.showToolbar(context),
onTap: () =>
toolbarController?.showToolbar(context, scrollController),
contextMenuBuilder: (context, state) =>
(toolbarController?.highlighted ?? false)
? const SizedBox.shrink()
@ -331,10 +335,12 @@ class MessageContent extends StatelessWidget {
textSelection: state,
onDefine: () => toolbarController?.showToolbar(
context,
scrollController,
mode: MessageMode.definition,
),
onListen: () => toolbarController?.showToolbar(
context,
scrollController,
mode: MessageMode.textToSpeech,
),
),

View file

@ -4,15 +4,18 @@ import 'package:flutter/material.dart';
class MessageButtons extends StatelessWidget {
final ToolbarDisplayController? toolbarController;
final ScrollController scrollController;
const MessageButtons({
super.key,
required this.scrollController,
this.toolbarController,
});
void showActivity(BuildContext context) {
toolbarController?.showToolbar(
context,
scrollController,
mode: MessageMode.practiceActivity,
);
}

View file

@ -59,7 +59,11 @@ class ToolbarDisplayController {
);
}
void showToolbar(BuildContext context, {MessageMode? mode}) {
void showToolbar(
BuildContext context,
ScrollController scrollController, {
MessageMode? mode,
}) {
bool toolbarUp = true;
if (highlighted) return;
if (controller.selectMode) {
@ -79,8 +83,23 @@ class ToolbarDisplayController {
final Size transformTargetSize = (targetRenderBox as RenderBox).size;
messageWidth = transformTargetSize.width;
final Offset targetOffset = (targetRenderBox).localToGlobal(Offset.zero);
final double screenHeight = MediaQuery.of(context).size.height;
toolbarUp = targetOffset.dy >= screenHeight / 2;
// final double screenHeight = MediaQuery.of(context).size.height;
// If message is too close to top, make space for toolbar
if (targetOffset.dy < 360) {
// If chat can scroll up, do so
final scrollTo = scrollController.offset - targetOffset.dy + 360 + 118;
if (scrollTo >= 0) {
scrollController.animateTo(
scrollTo,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
);
}
// If cannot scroll up enough, show toolbar underneath instead
else {
toolbarUp = false;
}
}
}
final Widget overlayMessage = OverlayMessage(
@ -89,6 +108,7 @@ class ToolbarDisplayController {
immersionMode: immersionMode,
ownMessage: pangeaMessageEvent.ownMessage,
toolbarController: this,
scrollController: scrollController,
width: messageWidth,
nextEvent: nextEvent,
previousEvent: previousEvent,

View file

@ -21,6 +21,7 @@ class OverlayMessage extends StatelessWidget {
final bool ownMessage;
final ToolbarDisplayController toolbarController;
final double? width;
final ScrollController scrollController;
const OverlayMessage(
this.event, {
@ -31,6 +32,7 @@ class OverlayMessage extends StatelessWidget {
required this.immersionMode,
required this.ownMessage,
required this.toolbarController,
required this.scrollController,
this.width,
super.key,
});
@ -151,6 +153,7 @@ class OverlayMessage extends StatelessWidget {
pangeaMessageEvent: pangeaMessageEvent,
immersionMode: immersionMode,
toolbarController: toolbarController,
scrollController: scrollController,
isOverlay: true,
),
if (event.hasAggregatedEvents(

View file

@ -21,12 +21,14 @@ class PangeaRichText extends StatefulWidget {
final bool immersionMode;
final ToolbarDisplayController? toolbarController;
final TextStyle? style;
final ScrollController scrollController;
const PangeaRichText({
super.key,
required this.pangeaMessageEvent,
required this.immersionMode,
required this.toolbarController,
required this.scrollController,
this.style,
});
@ -151,7 +153,8 @@ class PangeaRichTextState extends State<PangeaRichText> {
widget.toolbarController?.toolbar?.textSelection
.onTextSelection(selection);
},
onTap: () => widget.toolbarController?.showToolbar(context),
onTap: () => widget.toolbarController
?.showToolbar(context, widget.scrollController),
enableInteractiveSelection:
widget.toolbarController?.highlighted ?? false,
contextMenuBuilder: (context, state) =>
@ -162,10 +165,12 @@ class PangeaRichTextState extends State<PangeaRichText> {
textSelection: state,
onDefine: () => widget.toolbarController?.showToolbar(
context,
widget.scrollController,
mode: MessageMode.definition,
),
onListen: () => widget.toolbarController?.showToolbar(
context,
widget.scrollController,
mode: MessageMode.textToSpeech,
),
),