From c2b3b9e3fc57d018c58be71ed19533ce3ae71782 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Tue, 15 Dec 2020 19:02:09 -0800 Subject: [PATCH] Add utils diff_delta --- app/android/gradle.properties | 1 + lib/utils/diff_delta.dart | 73 +++++++++++++++++++++++++++++++++++ pubspec.lock | 14 +++++++ pubspec.yaml | 1 + 4 files changed, 89 insertions(+) create mode 100644 lib/utils/diff_delta.dart diff --git a/app/android/gradle.properties b/app/android/gradle.properties index 94adc3a3..a6738207 100644 --- a/app/android/gradle.properties +++ b/app/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true +android.enableR8=true diff --git a/lib/utils/diff_delta.dart b/lib/utils/diff_delta.dart new file mode 100644 index 00000000..e4f4379a --- /dev/null +++ b/lib/utils/diff_delta.dart @@ -0,0 +1,73 @@ +import 'dart:math' as math; + +import 'package:quill_delta/quill_delta.dart'; + +// Diff between two texts - old text and new text +class Diff { + // Start index in old text at which changes begin. + final int start; + + /// The deleted text + final String deleted; + + // The inserted text + final String inserted; + + Diff(this.start, this.deleted, this.inserted); + + @override + String toString() { + return 'Diff[$start, "$deleted", "$inserted"]'; + } +} + +/* Get diff operation between old text and new text */ +Diff getDiff(String oldText, String newText, int cursorPosition) { + int end = oldText.length; + int delta = newText.length - end; + for (int limit = math.max(0, cursorPosition - delta); + end > limit && oldText[end - 1] == newText[end + delta - 1]; + end--) {} + int start = 0; + for (int startLimit = cursorPosition - math.max(0, delta); + start < startLimit && oldText[start] == newText[start]; + start++) {} + String deleted = (start >= end) ? '' : oldText.substring(start, end); + String inserted = newText.substring(start, end + delta); + return Diff(start, deleted, inserted); +} + +int getPositionDelta(Delta user, Delta actual) { + DeltaIterator userItr = DeltaIterator(user); + DeltaIterator actualItr = DeltaIterator(actual); + int diff = 0; + while (userItr.hasNext || actualItr.hasNext) { + int length = math.min(userItr.peekLength(), actualItr.peekLength()); + Operation userOperation = userItr.next(length); + Operation actualOperation = actualItr.next(length); + if (userOperation.length != actualOperation.length) { + throw ('userOp ' + + userOperation.length.toString() + + ' does not match ' + + ' actualOp ' + + actualOperation.length.toString()); + } + if (userOperation.key == actualOperation.key) { + continue; + } else if (userOperation.isInsert && actualOperation.isRetain) { + diff -= userOperation.length; + } else if (userOperation.isDelete && actualOperation.isRetain) { + diff += userOperation.length; + } else if (userOperation.isRetain && actualOperation.isInsert) { + String operationTxt = ''; + if (actualOperation.data is String) { + operationTxt = actualOperation.data as String; + } + if (operationTxt.startsWith('\n')) { + continue; + } + diff += actualOperation.length; + } + } + return diff; +} diff --git a/pubspec.lock b/pubspec.lock index 58937f95..35d1060d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -81,6 +81,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0-nullsafety.1" + quill_delta: + dependency: "direct main" + description: + name: quill_delta + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + quiver_hashcode: + dependency: transitive + description: + name: quiver_hashcode + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 2410fceb..3110f34b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,6 +12,7 @@ environment: dependencies: flutter: sdk: flutter + quill_delta: ^2.0.0 dev_dependencies: flutter_test: