Skip to content
82 changes: 46 additions & 36 deletions lib/pages/editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ class EditorState extends State<Editor> {
}

final savingState = ValueNotifier(SavingState.savedWithThumbnail);
Timer? _delayedSaveTimer;
@visibleForTesting
Timer? delayedSaveTimer;

// used to prevent accidentally drawing when pinch zooming
int lastSeenPointerCount = 0;
Expand Down Expand Up @@ -321,12 +322,12 @@ class EditorState extends State<Editor> {
late final topOfLastPage = -CanvasGestureDetector.getTopOfPage(
pageIndex: coreInfo.pages.length - 1,
pages: coreInfo.pages,
screenWidth: MediaQuery.sizeOf(context).width,
screenWidth: _mediaQuery.size.width,
);
final bottomOfLastPage = -CanvasGestureDetector.getTopOfPage(
pageIndex: coreInfo.pages.length,
pages: coreInfo.pages,
screenWidth: MediaQuery.sizeOf(context).width,
screenWidth: _mediaQuery.size.width,
);

if (scrollY < bottomOfLastPage) {
Expand Down Expand Up @@ -803,9 +804,9 @@ class EditorState extends State<Editor> {

void autosaveAfterDelay() {
savingState.value = SavingState.waitingToSave;
_delayedSaveTimer?.cancel();
delayedSaveTimer?.cancel();
if (Prefs.autosaveDelay.value < 0) return;
_delayedSaveTimer =
delayedSaveTimer =
Timer(Duration(milliseconds: Prefs.autosaveDelay.value), () {
saveToFile(createThumbnail: false);
});
Expand All @@ -830,7 +831,7 @@ class EditorState extends State<Editor> {
return;
case SavingState.waitingToSave:
// continue
_delayedSaveTimer?.cancel();
delayedSaveTimer?.cancel();
savingState.value = SavingState.saving;
}

Expand Down Expand Up @@ -871,10 +872,7 @@ class EditorState extends State<Editor> {
return;
}

if (!mounted) return;
if (createThumbnail) {
createThumbnailPreview();
}
if (createThumbnail) await createThumbnailPreview();
}

/// create thumbnail of note
Expand All @@ -890,31 +888,37 @@ class EditorState extends State<Editor> {
);
final thumbnailSize = Size(720, 720 * previewHeight / page.size.width);
final thumbnail = await screenshotter.captureFromWidget(
Theme(
data: ThemeData(
brightness: Brightness.light,
colorScheme: const ColorScheme.light(
primary: EditorExporter.primaryColor,
secondary: EditorExporter.secondaryColor,
Comment thread
QubaB marked this conversation as resolved.
TranslationProvider(
child: MaterialApp(
theme: ThemeData(
brightness: Brightness.light,
colorScheme: const ColorScheme.light(
primary: EditorExporter.primaryColor,
secondary: EditorExporter.secondaryColor,
),
),
),
child: Localizations.override(
context: context,
child: SizedBox(
width: thumbnailSize.width,
height: thumbnailSize.height,
child: FittedBox(
child: pagePreviewBuilder(
context,
pageIndex: 0,
previewHeight: previewHeight,
home: MediaQuery(
data: MediaQueryData(
size: thumbnailSize,
devicePixelRatio: 1,
),
child: SizedBox(
width: thumbnailSize.width,
height: thumbnailSize.height,
child: FittedBox(
child: Builder(
builder: (context) => pagePreviewBuilder(
context,
pageIndex: 0,
previewHeight: previewHeight,
),
),
),
),
),
),
),
pixelRatio: 1,
context: context,
targetSize: thumbnailSize,
);
await FileManager.writeFile(
Expand Down Expand Up @@ -1302,6 +1306,14 @@ class EditorState extends State<Editor> {
));
}

late MediaQueryData _mediaQuery = const MediaQueryData();

@override
void didChangeDependencies() {
super.didChangeDependencies();
_mediaQuery = MediaQuery.of(context);
}

@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
Expand Down Expand Up @@ -1630,7 +1642,7 @@ class EditorState extends State<Editor> {
CanvasGestureDetector.scrollToPage(
pageIndex: currentPageIndex + 1,
pages: coreInfo.pages,
screenWidth: MediaQuery.sizeOf(context).width,
screenWidth: _mediaQuery.size.width,
transformationController: _transformationController,
);
}),
Expand Down Expand Up @@ -1943,11 +1955,9 @@ class EditorState extends State<Editor> {
int get currentPageIndex {
if (!mounted) return _lastCurrentPageIndex;

final screenWidth = MediaQuery.sizeOf(context).width;

return _lastCurrentPageIndex = getPageIndexFromScrollPosition(
scrollY: -scrollY,
screenWidth: screenWidth,
screenWidth: _mediaQuery.size.width,
pages: coreInfo.pages,
);
}
Expand All @@ -1974,7 +1984,10 @@ class EditorState extends State<Editor> {
}

@override
void dispose() {
void dispose() async {
delayedSaveTimer?.cancel();
_lastSeenPointerCountTimer?.cancel();

(() async {
if (_renameTimer?.isActive ?? false) {
_renameTimer!.cancel();
Expand All @@ -1986,9 +1999,6 @@ class EditorState extends State<Editor> {

DynamicMaterialApp.removeFullscreenListener(_setState);

_delayedSaveTimer?.cancel();
_lastSeenPointerCountTimer?.cancel();

_removeKeybindings();

coreInfo.dispose();
Expand Down
13 changes: 5 additions & 8 deletions test/editor_undo_redo_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ void main() {
reason: 'Editor is still read-only');
printOnFailure('Editor core info is loaded');

addTearDown(() async {
editorState.delayedSaveTimer?.cancel();
await FileManager.deleteFile(filePath + Editor.extension);
});

IconButton getUndoBtn() => tester.widget<IconButton>(find.ancestor(
of: find.byIcon(Icons.undo),
matching: find.byType(IconButton),
Expand Down Expand Up @@ -108,14 +113,6 @@ void main() {
reason: 'Undo button should be enabled after undo and draw');
expect(getRedoBtn().onPressed, isNull,
reason: 'Redo button should be disabled after undo and draw');

// save file now to supersede the save timer (which would run after the test is finished)
printOnFailure('Saving file: $filePath${Editor.extension}');
await tester.runAsync(() async {
await editorState.saveToFile(createThumbnail: false);
await Future.delayed(const Duration(milliseconds: 100));
await FileManager.deleteFile(filePath + Editor.extension);
});
});
}

Expand Down