fix(learn): an editor with nobody signed in above it checks nothing
Some checks failed
CI / check (push) Successful in 10s
CI / deploy (push) Failing after 7s

The full window editor is also shown without a person's scope, as a
privacy test pumps it, where GrammarHost asserted for want of one.
halkyon_app's PersonScope gains maybeOf beside of.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-26 00:05:48 +01:00
commit 46be998329
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
4 changed files with 39 additions and 7 deletions

View file

@ -132,6 +132,10 @@ class PersonDependencies({
static PersonDependencies of(BuildContext context) => static PersonDependencies of(BuildContext context) =>
PersonScope.of<PersonDependencies>(context); PersonScope.of<PersonDependencies>(context);
/// As [of], or null where nobody is signed in above [context].
static PersonDependencies? maybeOf(BuildContext context) =>
PersonScope.maybeOf<PersonDependencies>(context);
/// Closes what was opened for the person. /// Closes what was opened for the person.
@override @override
Future<void> dispose() async { Future<void> dispose() async {

View file

@ -5,6 +5,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:halkyon_learn_flutter/l10n/app_localizations.dart'; import 'package:halkyon_learn_flutter/l10n/app_localizations.dart';
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart'; import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
import 'package:halkyon_learn_flutter/src/core/dependencies/person_dependencies.dart';
import 'package:halkyon_learn_flutter/src/core/editor/block_menu.dart'; import 'package:halkyon_learn_flutter/src/core/editor/block_menu.dart';
import 'package:halkyon_learn_flutter/src/core/editor/core_blocks.dart'; import 'package:halkyon_learn_flutter/src/core/editor/core_blocks.dart';
import 'package:halkyon_learn_flutter/src/core/editor/editor_blocks.dart'; import 'package:halkyon_learn_flutter/src/core/editor/editor_blocks.dart';
@ -194,13 +195,15 @@ class _RichContentEditorState() extends State<RichContentEditor> {
), ),
); );
final checked = switch (widget.grammar) { final checked = switch (widget.grammar) {
final language? => GrammarHost( // Checked for the person signed in; nobody is outside their app.
editorState: _editorState, final language? when PersonDependencies.maybeOf(context) != null =>
focusNode: _focus, GrammarHost(
language: language, editorState: _editorState,
child: appFlowyEditor, focusNode: _focus,
), language: language,
null => appFlowyEditor, child: appFlowyEditor,
),
_ => appFlowyEditor,
}; };
final editor = switch (defaultTargetPlatform) { final editor = switch (defaultTargetPlatform) {
TargetPlatform.android || TargetPlatform.iOS => MobileFloatingToolbar( TargetPlatform.android || TargetPlatform.iOS => MobileFloatingToolbar(

View file

@ -26,6 +26,14 @@ class const PersonScope({
return scope!.dependencies as P; return scope!.dependencies as P;
} }
/// As [of], or null where nobody is signed in above [context]: for what
/// also shows outside a person's app and does without their data there.
static P? maybeOf<P extends Disposable>(BuildContext context) =>
context
.getInheritedWidgetOfExactType<_PersonDependenciesScope>()
?.dependencies
as P?;
@override @override
State<PersonScope> createState() => _PersonScopeState(); State<PersonScope> createState() => _PersonScopeState();
} }

View file

@ -45,6 +45,23 @@ void main() {
expect(find.text('Data of ada'), findsOneWidget); expect(find.text('Data of ada'), findsOneWidget);
}); });
testWidgets('maybeOf finds the dependencies of the person signed in '
'above, and none where nobody is', (tester) async {
TestPerson? found;
Widget looking() => Builder(
builder: (context) {
found = PersonScope.maybeOf<TestPerson>(context);
return const SizedBox();
},
);
await show(tester, PersonScope(person: ada, child: looking()));
expect(found?.person, ada);
await show(tester, looking());
expect(found, isNull);
});
testWidgets("closes the person's data when it goes away", (tester) async { testWidgets("closes the person's data when it goes away", (tester) async {
await show(tester, const PersonScope(person: ada, child: _Person())); await show(tester, const PersonScope(person: ada, child: _Person()));