perf(learn): local reads no longer wait on the instance
Every read of the person's content refreshes their keys, and a refresh asked the instance whether the account has keys until it once answered yes, which an account signing in with SimpleLogin alone never does. So on a poor connection every read waited on a request: the library's progress, a request per studyset in a row, took over five minutes, and Home was slow too. A device holding the keys already knows the account has them, so the keys now open first and the instance is asked only while no other sign says so (a device without the keys still asks at every refresh). Whats-New: The library and Home open quickly again without a good connection. Whats-New-De: Die Bibliothek und die Startseite öffnen sich ohne gute Verbindung wieder schnell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
151f848360
commit
1781553f1d
3 changed files with 44 additions and 137 deletions
|
|
@ -65,6 +65,39 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
test('a device holding the keys never asks the instance whether the '
|
||||
'account has them, which reads would otherwise wait on (offline: '
|
||||
'minutes); one without asks at every refresh', () async {
|
||||
var asked = 0;
|
||||
Future<bool?> register() async {
|
||||
asked++;
|
||||
return false;
|
||||
}
|
||||
|
||||
final laptop = ContentKeys(
|
||||
synced,
|
||||
FakeContentCipher(),
|
||||
() async => alice,
|
||||
registerHasKeys: register,
|
||||
);
|
||||
addTearDown(laptop.dispose);
|
||||
await laptop.refresh();
|
||||
await laptop.refresh();
|
||||
expect(asked, 0);
|
||||
expect(laptop.accountHasKeys, isTrue);
|
||||
|
||||
final keyless = ContentKeys(
|
||||
FakeContentKeyGateway(),
|
||||
FakeContentCipher(),
|
||||
() async => null,
|
||||
registerHasKeys: register,
|
||||
);
|
||||
addTearDown(keyless.dispose);
|
||||
await keyless.refresh();
|
||||
await keyless.refresh();
|
||||
expect(asked, 2);
|
||||
});
|
||||
|
||||
test("another account's device opens nothing of it", () async {
|
||||
final laptop = await device(alice);
|
||||
final keyId = await laptop.newStudysetKey('studyset-1');
|
||||
|
|
|
|||
|
|
@ -1,92 +0,0 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_payload.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
||||
import 'package:material_ui/material_ui.dart';
|
||||
|
||||
import '../../../support/fake_studyset_gateway.dart';
|
||||
import '../../../support/memory_private_offer_store.dart';
|
||||
import '../../../support/pump_app.dart';
|
||||
import '../../../support/test_dependencies.dart';
|
||||
|
||||
/// The library's one offer to make the studysets from before private (ADR
|
||||
/// 0019, D4).
|
||||
void main() {
|
||||
late FakeStudysetGateway gateway;
|
||||
late MemoryPrivateOfferStore offer;
|
||||
|
||||
setUp(() {
|
||||
gateway = FakeStudysetGateway()..canMakePrivate = true;
|
||||
offer = MemoryPrivateOfferStore();
|
||||
gateway
|
||||
..receiveRemoteChange(
|
||||
'japanese',
|
||||
encodeStudysetPayload(StudysetContent.titled('Japanese')),
|
||||
)
|
||||
..receiveRemoteChange(
|
||||
'kanji',
|
||||
encodeStudysetPayload(StudysetContent.titled('Kanji')),
|
||||
parentId: 'japanese',
|
||||
)
|
||||
..receiveRemoteChange(
|
||||
'diary',
|
||||
encodeStudysetPayload(StudysetContent.titled('Diary')),
|
||||
isPrivate: true,
|
||||
);
|
||||
});
|
||||
|
||||
Future<void> showLibrary(WidgetTester tester) async {
|
||||
tester.view.physicalSize = const Size(1200, 1600);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.reset);
|
||||
await pumpApp(
|
||||
tester,
|
||||
testDependencies(studysetGateway: gateway, privateOffer: offer),
|
||||
location: RoutePaths.library,
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
}
|
||||
|
||||
testWidgets('makes every top-level studyset that is not private private '
|
||||
'at once, then never asks again', (tester) async {
|
||||
await showLibrary(tester);
|
||||
|
||||
expect(find.text('Make your studysets private?'), findsOneWidget);
|
||||
await tester.tap(find.text('Make all private'));
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(gateway.privacyChanges, [('japanese', true)]);
|
||||
expect(offer.isAnswered, isTrue);
|
||||
expect(find.text('Make your studysets private?'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('not now leaves them as they are, and asks no more', (
|
||||
tester,
|
||||
) async {
|
||||
await showLibrary(tester);
|
||||
|
||||
await tester.tap(find.text('Not now'));
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(gateway.privacyChanges, isEmpty);
|
||||
expect(offer.isAnswered, isTrue);
|
||||
expect(find.text('Make your studysets private?'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('is never shown once answered', (tester) async {
|
||||
offer.isAnswered = true;
|
||||
await showLibrary(tester);
|
||||
expect(find.text('Make your studysets private?'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("is never shown on a device without the account's keys", (
|
||||
tester,
|
||||
) async {
|
||||
gateway.canMakePrivate = false;
|
||||
await showLibrary(tester);
|
||||
expect(find.text('Make your studysets private?'), findsNothing);
|
||||
});
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import 'package:halkyon_learn_flutter/src/feature/studyset/data/private_offer_store.dart';
|
||||
|
||||
/// [PrivateOfferStore] in memory.
|
||||
class MemoryPrivateOfferStore() implements PrivateOfferStore {
|
||||
/// Whether the offer was answered.
|
||||
bool isAnswered = false;
|
||||
|
||||
@override
|
||||
Future<bool> answered() async => isAnswered;
|
||||
|
||||
@override
|
||||
Future<void> answer() async => isAnswered = true;
|
||||
}
|
||||
Loading…
Reference in a new issue