Skip to content
This repository has been archived by the owner on Sep 9, 2024. It is now read-only.

Commit

Permalink
fix: state not updated on post change
Browse files Browse the repository at this point in the history
  • Loading branch information
Craftplacer committed Oct 29, 2023
1 parent 0a1fe7c commit aee96db
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 28 deletions.
69 changes: 41 additions & 28 deletions src/kaiteki/lib/ui/shared/posts/post_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,44 +103,57 @@ class _PostContentWidgetState extends ConsumerState<PostContent> {
);
}

@override
void didUpdateWidget(covariant PostContent oldWidget) {
super.didUpdateWidget(oldWidget);

if (oldWidget.post != widget.post) {
_renderContent();
_updateCollapsed();
}
}

@override
void didChangeDependencies() {
super.didChangeDependencies();

_renderContent();
_updateCollapsed();
}

void _updateCollapsed() {
final cwBehavior = ref.watch(preferences.cwBehavior).value;

final subject = widget.post.subject;
final hasSubject = subject != null && subject.isNotEmpty;

if (hasSubject) {
switch (cwBehavior) {
case ContentWarningBehavior.collapse:
collapsed = true;
break;
case ContentWarningBehavior.expanded:
collapsed = false;
break;
case ContentWarningBehavior.automatic:
final plainText = renderedContent?.toPlainText(
includeSemanticsLabels: false,
includePlaceholders: false,
);

final strings = [if (plainText != null) plainText, subject];

if (strings.isEmpty) break;

final words = strings
.map((e) => e.toLowerCase())
.map((e) => e.split(RegExp(r"([\s:])+")))
.flattened;

collapsed = sensitiveWords.any(words.contains);
break;
}
}
collapsed = switch (cwBehavior) {
ContentWarningBehavior.collapse => hasSubject,
ContentWarningBehavior.expanded => false,
ContentWarningBehavior.automatic => _containsSensitiveWords(),
};
}

bool _containsSensitiveWords() {
final plainText = renderedContent?.toPlainText(
includeSemanticsLabels: false,
includePlaceholders: false,
);

final subject = widget.post.subject;

final strings = [
if (plainText != null) plainText,
if (subject != null) subject,
];

if (strings.isEmpty) return false;

final words = strings
.map((e) => e.toLowerCase())
.map((e) => e.split(RegExp(r"([\s:])+")))
.flattened;

return sensitiveWords.any(words.contains);
}

void _renderContent() {
Expand Down
83 changes: 83 additions & 0 deletions src/kaiteki/test/post_state_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import "package:flutter/material.dart";
import "package:flutter_test/flutter_test.dart";
import "package:kaiteki/model/auth/account.dart";
import "package:kaiteki/model/auth/account_key.dart";
import "package:kaiteki/ui/shared/posts/post_widget.dart";
import "package:kaiteki_core/kaiteki_core.dart";

import "utils/bootstrap.dart";
import "utils/dummy_adapter.dart";

void main() {
testWidgets("Test post widget state updating", (tester) async {
final boot = await Bootstrapper.getInstance(
initialAccounts: [
Account(
key: const AccountKey(ApiType.mastodon, "example.com", "alice"),
adapter: DummyAdapter(),
accountSecret: null,
clientSecret: null,
user: exampleUser,
),
],
);

final post = Post(
id: "1",
content: "Hello world",
postedAt: DateTime.now(),
author: exampleUser,
);

final key = GlobalKey<_TestPostWidgetState>();

await tester.pumpWidget(
boot.wrap(_TestPostWidget(post: post, key: key)),
);

final contentFinder = find.text(post.content!);

expect(contentFinder, findsOneWidget);

final newPost = post.copyWith(content: "Hello world 2");

key.currentState!.post = newPost;

await tester.pumpAndSettle();

expect(contentFinder, findsNothing);
});
}

class _TestPostWidget extends StatefulWidget {
final Post post;

const _TestPostWidget({required this.post, super.key});

@override
State<_TestPostWidget> createState() => _TestPostWidgetState();
}

class _TestPostWidgetState extends State<_TestPostWidget> {
late Post _post;

set post(Post post) => setState(() => _post = post);

@override
void initState() {
super.initState();
_post = widget.post;
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 600),
child: PostWidget(_post),
),
),
);
}
}

0 comments on commit aee96db

Please sign in to comment.