4199 prevent activity menu tooltip from being interfered with my other overlays to ensure it always shows (#4215)
* don't show activity dropdown instructions if word card is open * block other overlays from openning when tutorial overlay is open * remove duplicate open overlay data, don't wait for construct banners to close if overlay fails to open
This commit is contained in:
parent
171dc55242
commit
97163ce221
7 changed files with 64 additions and 53 deletions
|
|
@ -1608,15 +1608,6 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
);
|
||||
}
|
||||
|
||||
// #Pangea
|
||||
/// Close the combined selection view overlay and clear the message
|
||||
/// text and selection stored for the text in that overlay
|
||||
void closeSelectionOverlay() {
|
||||
MatrixState.pAnyState.closeAllOverlays();
|
||||
// selectedTokenIndicies.clear();
|
||||
}
|
||||
// Pangea#
|
||||
|
||||
// #Pangea
|
||||
// void clearSelectedEvents() => setState(() {
|
||||
// selectedEvents.clear();
|
||||
|
|
@ -1625,7 +1616,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
void clearSelectedEvents() {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
closeSelectionOverlay();
|
||||
MatrixState.pAnyState.closeAllOverlays();
|
||||
selectedEvents.clear();
|
||||
showEmojiPicker = false;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import 'package:fluffychat/pangea/analytics_misc/construct_type_enum.dart';
|
|||
import 'package:fluffychat/pangea/common/utils/overlay.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
|
||||
import 'package:fluffychat/pangea/instructions/instructions_enum.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class ActivityStatsButton extends StatefulWidget {
|
||||
final ChatController controller;
|
||||
|
|
@ -54,6 +55,9 @@ class _ActivityStatsButtonState extends State<ActivityStatsButton> {
|
|||
|
||||
bool get _shouldShowInstructions {
|
||||
if (InstructionsEnum.activityStatsMenu.isToggledOff ||
|
||||
MatrixState.pAnyState.isOverlayOpen(
|
||||
RegExp(r"^word-zoom-card-.*$"),
|
||||
) ||
|
||||
_xpCount <= 0 ||
|
||||
widget.controller.timeline == null) {
|
||||
return false;
|
||||
|
|
@ -111,7 +115,7 @@ class _ActivityStatsButtonState extends State<ActivityStatsButton> {
|
|||
|
||||
OverlayUtil.showTutorialOverlay(
|
||||
context,
|
||||
Center(
|
||||
overlayContent: Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
decoration: BoxDecoration(
|
||||
|
|
@ -144,12 +148,13 @@ class _ActivityStatsButtonState extends State<ActivityStatsButton> {
|
|||
),
|
||||
),
|
||||
),
|
||||
cellRect,
|
||||
overlayKey: "activity_stats_menu_instruction",
|
||||
anchorRect: cellRect,
|
||||
borderRadius: 12.0,
|
||||
padding: 8.0,
|
||||
onClick: () => widget.controller.setShowDropdown(true),
|
||||
onDismiss: () {
|
||||
onClick: () {
|
||||
InstructionsEnum.activityStatsMenu.setToggledOff(true);
|
||||
widget.controller.setShowDropdown(true);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class LevelUpUtil {
|
|||
|
||||
if (!context.mounted) return;
|
||||
|
||||
await OverlayUtil.showOverlay(
|
||||
OverlayUtil.showOverlay(
|
||||
overlayKey: "level_up_notification",
|
||||
context: context,
|
||||
child: LevelUpBanner(
|
||||
|
|
@ -66,8 +66,7 @@ class LevelUpUtil {
|
|||
|
||||
static Future<void> _waitForSnackbars(BuildContext context) async {
|
||||
final snackbarRegex = RegExp(r'_snackbar$');
|
||||
while (MatrixState.pAnyState.activeOverlays
|
||||
.any((id) => snackbarRegex.hasMatch(id))) {
|
||||
while (MatrixState.pAnyState.isOverlayOpen(snackbarRegex)) {
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class ConstructNotificationUtil {
|
|||
if (_closedOverlays.contains(overlayKey)) return;
|
||||
_closedOverlays.add(overlayKey);
|
||||
MatrixState.pAnyState.closeOverlay(overlayKey);
|
||||
MatrixState.pAnyState.activeOverlays.remove(overlayKey);
|
||||
unlockedConstructs.remove(construct);
|
||||
closeCompleter?.complete();
|
||||
closeCompleter = null;
|
||||
|
|
@ -58,7 +57,7 @@ class ConstructNotificationUtil {
|
|||
);
|
||||
closeCompleter = Completer();
|
||||
|
||||
OverlayUtil.showOverlay(
|
||||
final bool result = OverlayUtil.showOverlay(
|
||||
overlayKey: "${construct.string}_snackbar",
|
||||
context: context,
|
||||
child: ConstructNotificationOverlay(
|
||||
|
|
@ -72,13 +71,14 @@ class ConstructNotificationUtil {
|
|||
canPop: false,
|
||||
);
|
||||
|
||||
MatrixState.pAnyState.activeOverlays
|
||||
.add("${construct.string}_snackbar");
|
||||
// if the overlay could not be shown, break the loop
|
||||
if (!result) {
|
||||
showingNotification = false;
|
||||
break;
|
||||
}
|
||||
|
||||
await closeCompleter!.future;
|
||||
} catch (e) {
|
||||
MatrixState.pAnyState.activeOverlays
|
||||
.remove("${construct.string}_snackbar");
|
||||
showingNotification = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,17 @@ class OverlayListEntry {
|
|||
final OverlayEntry entry;
|
||||
final String? key;
|
||||
final bool canPop;
|
||||
final bool blockOverlay;
|
||||
|
||||
OverlayListEntry(
|
||||
this.entry, {
|
||||
this.key,
|
||||
this.canPop = true,
|
||||
this.blockOverlay = false,
|
||||
});
|
||||
}
|
||||
|
||||
class PangeaAnyState {
|
||||
final Set<String> activeOverlays = {};
|
||||
final Map<String, LayerLinkAndKey> _layerLinkAndKeys = {};
|
||||
List<OverlayListEntry> entries = [];
|
||||
|
||||
|
|
@ -39,16 +40,21 @@ class PangeaAnyState {
|
|||
return _layerLinkAndKeys[transformTargetId]!;
|
||||
}
|
||||
|
||||
void openOverlay(
|
||||
bool openOverlay(
|
||||
OverlayEntry entry,
|
||||
BuildContext context, {
|
||||
String? overlayKey,
|
||||
bool canPop = true,
|
||||
bool blockOverlay = false,
|
||||
bool rootOverlay = false,
|
||||
}) {
|
||||
if (entries.any((e) => e.blockOverlay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (overlayKey != null &&
|
||||
entries.any((element) => element.key == overlayKey)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
entries.add(
|
||||
|
|
@ -56,17 +62,16 @@ class PangeaAnyState {
|
|||
entry,
|
||||
key: overlayKey,
|
||||
canPop: canPop,
|
||||
blockOverlay: blockOverlay,
|
||||
),
|
||||
);
|
||||
|
||||
if (overlayKey != null) {
|
||||
activeOverlays.add(overlayKey);
|
||||
}
|
||||
|
||||
Overlay.of(
|
||||
context,
|
||||
rootOverlay: rootOverlay,
|
||||
).insert(entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void closeOverlay([String? overlayKey]) {
|
||||
|
|
@ -89,10 +94,6 @@ class PangeaAnyState {
|
|||
);
|
||||
}
|
||||
entries.remove(entry);
|
||||
|
||||
if (overlayKey != null) {
|
||||
activeOverlays.remove(overlayKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,10 +127,6 @@ class PangeaAnyState {
|
|||
);
|
||||
}
|
||||
|
||||
if (shouldRemove[i].key != null) {
|
||||
activeOverlays.remove(shouldRemove[i].key);
|
||||
}
|
||||
|
||||
entries.remove(shouldRemove[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -137,8 +134,10 @@ class PangeaAnyState {
|
|||
RenderBox? getRenderBox(String key) =>
|
||||
layerLinkAndKey(key).key.currentContext?.findRenderObject() as RenderBox?;
|
||||
|
||||
bool isOverlayOpen(String overlayKey) {
|
||||
return entries.any((element) => element.key == overlayKey);
|
||||
bool isOverlayOpen(RegExp regex) {
|
||||
return entries.any(
|
||||
(element) => element.key != null && regex.hasMatch(element.key!),
|
||||
);
|
||||
}
|
||||
|
||||
List<String> getMatchingOverlayKeys(RegExp regex) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ enum OverlayPositionEnum {
|
|||
}
|
||||
|
||||
class OverlayUtil {
|
||||
static showOverlay({
|
||||
static bool showOverlay({
|
||||
required BuildContext context,
|
||||
required Widget child,
|
||||
String? transformTargetId,
|
||||
|
|
@ -35,6 +35,7 @@ class OverlayUtil {
|
|||
Alignment? followerAnchor,
|
||||
bool ignorePointer = false,
|
||||
bool canPop = true,
|
||||
bool rootOverlay = false,
|
||||
}) {
|
||||
try {
|
||||
if (position == OverlayPositionEnum.transform) {
|
||||
|
|
@ -96,11 +97,12 @@ class OverlayUtil {
|
|||
),
|
||||
);
|
||||
|
||||
MatrixState.pAnyState.openOverlay(
|
||||
return MatrixState.pAnyState.openOverlay(
|
||||
entry,
|
||||
context,
|
||||
overlayKey: overlayKey,
|
||||
canPop: canPop,
|
||||
rootOverlay: rootOverlay,
|
||||
);
|
||||
} catch (err, stack) {
|
||||
debugger(when: kDebugMode);
|
||||
|
|
@ -109,6 +111,7 @@ class OverlayUtil {
|
|||
s: stack,
|
||||
data: {},
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -215,15 +218,17 @@ class OverlayUtil {
|
|||
}
|
||||
|
||||
static void showTutorialOverlay(
|
||||
BuildContext context,
|
||||
Widget overlayContent,
|
||||
Rect anchorRect, {
|
||||
BuildContext context, {
|
||||
required Widget overlayContent,
|
||||
required String overlayKey,
|
||||
required Rect anchorRect,
|
||||
double? borderRadius,
|
||||
double? padding,
|
||||
final VoidCallback? onClick,
|
||||
final VoidCallback? onDismiss,
|
||||
}) {
|
||||
MatrixState.pAnyState.closeAllOverlays();
|
||||
// force close all overlays to prevent showing
|
||||
// constuct / level up notification on top of tutorial
|
||||
MatrixState.pAnyState.closeAllOverlays(force: true);
|
||||
final entry = OverlayEntry(
|
||||
builder: (context) {
|
||||
return AnchoredOverlayWidget(
|
||||
|
|
@ -231,7 +236,7 @@ class OverlayUtil {
|
|||
borderRadius: borderRadius,
|
||||
padding: padding,
|
||||
onClick: onClick,
|
||||
onDismiss: onDismiss,
|
||||
overlayKey: overlayKey,
|
||||
child: overlayContent,
|
||||
);
|
||||
},
|
||||
|
|
@ -240,6 +245,9 @@ class OverlayUtil {
|
|||
entry,
|
||||
context,
|
||||
rootOverlay: true,
|
||||
overlayKey: overlayKey,
|
||||
canPop: false,
|
||||
blockOverlay: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ import 'package:fluffychat/widgets/matrix.dart';
|
|||
class AnchoredOverlayWidget extends StatefulWidget {
|
||||
final Widget child;
|
||||
final Rect anchorRect;
|
||||
final String overlayKey;
|
||||
final double? borderRadius;
|
||||
final double? padding;
|
||||
final VoidCallback? onClick;
|
||||
final VoidCallback? onDismiss;
|
||||
|
||||
const AnchoredOverlayWidget({
|
||||
required this.child,
|
||||
required this.anchorRect,
|
||||
required this.overlayKey,
|
||||
this.borderRadius,
|
||||
this.padding,
|
||||
this.onClick,
|
||||
this.onDismiss,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -41,6 +41,17 @@ class _AnchoredOverlayWidgetState extends State<AnchoredOverlayWidget> {
|
|||
);
|
||||
}
|
||||
|
||||
Future<void> _closeOverlay() async {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_visible = false;
|
||||
});
|
||||
await Future.delayed(FluffyThemes.animationDuration);
|
||||
}
|
||||
|
||||
MatrixState.pAnyState.closeOverlay(widget.overlayKey);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final leftPosition = (widget.anchorRect.left +
|
||||
|
|
@ -58,11 +69,9 @@ class _AnchoredOverlayWidgetState extends State<AnchoredOverlayWidget> {
|
|||
onTapDown: (details) {
|
||||
final tapPos = details.globalPosition;
|
||||
if (widget.anchorRect.contains(tapPos)) {
|
||||
_closeOverlay();
|
||||
widget.onClick?.call();
|
||||
}
|
||||
|
||||
widget.onDismiss?.call();
|
||||
MatrixState.pAnyState.closeOverlay();
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue