Skip to content

Commit

Permalink
Merge pull request #476 from DanXi-Dev/fix-475
Browse files Browse the repository at this point in the history
Fix #475
  • Loading branch information
w568w authored Jan 4, 2025
2 parents e982d21 + 3ff80c1 commit 2c81401
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 18 deletions.
3 changes: 2 additions & 1 deletion lib/page/forum/hole_detail.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import 'package:dan_xi/repository/forum/forum_repository.dart';
import 'package:dan_xi/util/master_detail_view.dart';
import 'package:dan_xi/util/noticing.dart';
import 'package:dan_xi/util/platform_universal.dart';
import 'package:dan_xi/util/watermark.dart';
import 'package:dan_xi/widget/forum/forum_widgets.dart';
import 'package:dan_xi/widget/forum/ottag_selector.dart';
import 'package:dan_xi/widget/forum/post_render.dart';
Expand Down Expand Up @@ -430,7 +431,7 @@ class BBSPostDetailState extends State<BBSPostDetail> {
},
),
),
);
).withWatermarkRegion();
}

// Load all floors, in case we have to scroll to end or to a specific floor
Expand Down
3 changes: 2 additions & 1 deletion lib/page/forum/hole_messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:dan_xi/generated/l10n.dart';
import 'package:dan_xi/model/forum/message.dart';
import 'package:dan_xi/page/subpage_forum.dart';
import 'package:dan_xi/repository/forum/forum_repository.dart';
import 'package:dan_xi/util/watermark.dart';
import 'package:dan_xi/widget/libraries/paged_listview.dart';
import 'package:dan_xi/widget/libraries/platform_app_bar_ex.dart';
import 'package:dan_xi/widget/libraries/top_controller.dart';
Expand Down Expand Up @@ -144,6 +145,6 @@ class OTMessagesPageState extends State<OTMessagesPage> {
),
),
),
);
).withWatermarkRegion();
}
}
9 changes: 2 additions & 7 deletions lib/page/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -717,13 +717,8 @@ class HomePageState extends State<HomePage> with WidgetsBindingObserver {
itemChanged: (index) {
if (index != pageIndex) {
// Dispatch [SubpageViewState] events.
for (int i = 0; i < _subpage.length; i++) {
if (index != i) {
_subpage[i]
.onViewStateChanged(SubpageViewState.INVISIBLE);
}
}
_subpage[index].onViewStateChanged(SubpageViewState.VISIBLE);
_subpage[pageIndex].onViewStateChanged(context, SubpageViewState.INVISIBLE);
_subpage[index].onViewStateChanged(context, SubpageViewState.VISIBLE);
_pageIndex.value = index;
} else {
_subpage[index].onDoubleTapOnTab();
Expand Down
7 changes: 4 additions & 3 deletions lib/page/platform_subpage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ abstract class PlatformSubpage<T> extends StatefulWidget {
void onDoubleTapOnTab() {}

@mustCallSuper
void onViewStateChanged(SubpageViewState state) =>
void onViewStateChanged(BuildContext parentContext, SubpageViewState state) =>
Constant.eventBus.fire(_ViewStateChangedNotification<T>(state));
}

Expand Down Expand Up @@ -93,11 +93,13 @@ abstract class PlatformSubpageState<T extends PlatformSubpage>

Widget buildPage(BuildContext context);

@mustCallSuper
void detachItself() {
_isOnShow = false;
_thisPrimaryScrollController?.detachPosition.call();
}

@mustCallSuper
void reattachItself() {
_isOnShow = true;
_thisPrimaryScrollController?.reattachPosition.call();
Expand Down Expand Up @@ -166,8 +168,7 @@ abstract class PlatformSubpageState<T extends PlatformSubpage>
cupertino: (_, __) => CupertinoNavigationBarData(
title: MediaQuery(
data: MediaQueryData(
textScaler: TextScaler.linear(
MediaQuery.textScaleFactorOf(context))),
textScaler: MediaQuery.textScalerOf(context)),
child: TopController(child: widget.title(context))),
),
material: (_, __) => MaterialAppBarData(
Expand Down
17 changes: 17 additions & 0 deletions lib/page/subpage_danke.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'package:dan_xi/provider/state_provider.dart';
import 'package:dan_xi/repository/danke/curriculum_board_repository.dart';
import 'package:dan_xi/repository/forum/forum_repository.dart';
import 'package:dan_xi/util/master_detail_view.dart';
import 'package:dan_xi/util/watermark.dart';
import 'package:dan_xi/widget/danke/course_list_widget.dart';
import 'package:dan_xi/widget/danke/course_search_bar.dart';
import 'package:dan_xi/widget/danke/random_review_widgets.dart';
Expand All @@ -43,6 +44,22 @@ class DankeSubPage extends PlatformSubpage<DankeSubPage> {

@override
Create<Widget> get title => (cxt) => Text(S.of(cxt).curriculum);

@override
void onViewStateChanged(BuildContext parentContext, SubpageViewState state) {
super.onViewStateChanged(parentContext, state);
switch (state) {
case SubpageViewState.VISIBLE:
// Subpage is always mounted even if it is invisible.
// Monitoring within State lifecycle methods like `initState` and `dispose` isn't effective.
// So we have to count on the onViewStateChanged hook to add/remove watermark.
Watermark.addWatermark(parentContext);
break;
case SubpageViewState.INVISIBLE:
Watermark.remove();
break;
}
}
}

class DankeSubPageState extends PlatformSubpageState<DankeSubPage> {
Expand Down
21 changes: 17 additions & 4 deletions lib/page/subpage_forum.dart
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,22 @@ class ForumSubpage extends PlatformSubpage<ForumSubpage> {

@override
void onDoubleTapOnTab() => RefreshListEvent().fire();

@override
void onViewStateChanged(BuildContext parentContext, SubpageViewState state) {
super.onViewStateChanged(parentContext, state);
switch (state) {
case SubpageViewState.VISIBLE:
// Subpage is always mounted even if it is invisible.
// Monitoring within State lifecycle methods like `initState` and `dispose` isn't effective.
// So we have to count on the onViewStateChanged hook to add/remove watermark.
Watermark.addWatermark(parentContext);
break;
case SubpageViewState.INVISIBLE:
Watermark.remove();
break;
}
}
}

class CreateNewPostEvent {}
Expand Down Expand Up @@ -541,9 +557,6 @@ class ForumSubpageState extends PlatformSubpageState<ForumSubpage> {
});
}),
hashCode);
WidgetsBinding.instance.addPostFrameCallback((_) {
Watermark.addWatermark(context, rowCount: 4, columnCount: 8);
});
}

@override
Expand Down Expand Up @@ -645,7 +658,7 @@ class ForumSubpageState extends PlatformSubpageState<ForumSubpage> {
await AnnouncementRepository.getInstance().loadAnnouncements();
bannerKey.currentState?.updateBannerList();
// ... and scroll it to the top.
if (!mounted) return;
if (!context.mounted) return;
try {
await PrimaryScrollController.of(context).animateTo(0,
duration: const Duration(milliseconds: 200),
Expand Down
54 changes: 53 additions & 1 deletion lib/util/watermark.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,28 @@ import 'package:dan_xi/util/platform_universal.dart';
import 'package:dan_xi/widget/forum/flutter_watermark_widget.dart';
import 'package:flutter/material.dart';

/// A reference-counted full-screen watermark that shows user ID overlay on the screen.
class Watermark {
static OverlayEntry? overlayEntry;

/// The reference count of the watermark. When it is 0, the watermark will be removed.
static int refCount = 0;

static void remove() {
assert(refCount > 0, 'The watermark reference count is already 0.');
refCount--;
if (refCount == 0) {
assert(overlayEntry != null, 'The watermark overlay entry is null.');
overlayEntry?.remove();
overlayEntry = null;
}
}

/// Add a watermark to the screen.
static void addWatermark(BuildContext context,
{int rowCount = 3, int columnCount = 10, TextStyle? textStyle}) async {
{int rowCount = 4, int columnCount = 8, TextStyle? textStyle}) async {
if (overlayEntry != null) {
// If the watermark is already added, remove it first so that the new one can be added.
overlayEntry!.remove();
}

Expand All @@ -48,5 +63,42 @@ class Watermark {
));

overlayState.insert(overlayEntry!);
refCount++;
}
}

/// A state widget that shows a full-screen watermark when the child widget is shown,
/// and removes the watermark when the child widget is destroyed.
///
/// You can use the [withWatermarkRegion] extension method to wrap a widget with a watermark region.
class WatermarkRegion extends StatefulWidget {
final Widget child;
const WatermarkRegion({super.key, required this.child});

@override
State<WatermarkRegion> createState() => _WatermarkRegionState();
}

class _WatermarkRegionState extends State<WatermarkRegion> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Watermark.addWatermark(context);
});
}

@override
Widget build(BuildContext context) => widget.child;

@override
void dispose() {
Watermark.remove();
super.dispose();
}
}

extension WatermarkRegionExtension on Widget {
/// Wrap the widget with a watermark region.
Widget withWatermarkRegion() => WatermarkRegion(child: this);
}
3 changes: 2 additions & 1 deletion lib/widget/forum/forum_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import 'package:dan_xi/util/noticing.dart';
import 'package:dan_xi/util/platform_universal.dart';
import 'package:dan_xi/util/public_extension_methods.dart';
import 'package:dan_xi/util/viewport_utils.dart';
import 'package:dan_xi/util/watermark.dart';
import 'package:dan_xi/widget/forum/render/base_render.dart';
import 'package:dan_xi/widget/libraries/chip_widgets.dart';
import 'package:dan_xi/widget/libraries/future_widget.dart';
Expand Down Expand Up @@ -675,7 +676,7 @@ class OTFloorMentionWidget extends StatelessWidget {
),
),
],
);
).withWatermarkRegion();
if (PlatformX.isCupertino(context)) {
return SafeArea(
child: Card(
Expand Down

0 comments on commit 2c81401

Please sign in to comment.