Initial implementation of quill in Action Taken
This commit is contained in:
parent
1478667bbf
commit
2aeb73d5de
|
|
@ -10,6 +10,7 @@ import '../../models/ticket_message.dart';
|
|||
import '../../providers/notifications_provider.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter_quill/flutter_quill.dart' as quill;
|
||||
import '../../providers/supabase_provider.dart';
|
||||
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||
import '../../providers/profile_provider.dart';
|
||||
|
|
@ -52,8 +53,8 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
final _requestedController = TextEditingController();
|
||||
final _notedController = TextEditingController();
|
||||
final _receivedController = TextEditingController();
|
||||
// Plain text controller for Action taken (fallback from rich editor)
|
||||
TextEditingController? _actionController;
|
||||
// Rich text editor for Action taken
|
||||
quill.QuillController? _actionController;
|
||||
Timer? _actionDebounce;
|
||||
Timer? _requestedDebounce;
|
||||
Timer? _notedDebounce;
|
||||
|
|
@ -99,7 +100,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
CurvedAnimation(parent: _saveAnimController, curve: Curves.easeInOut),
|
||||
);
|
||||
// create an empty action controller by default; will seed per-task later
|
||||
_actionController = TextEditingController();
|
||||
_actionController = quill.QuillController.basic();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -138,26 +139,6 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
}
|
||||
}
|
||||
|
||||
// Convert stored Quill delta JSON (or other simple structures) to plain text.
|
||||
String _deltaJsonToPlainText(dynamic json) {
|
||||
try {
|
||||
if (json is String) return json;
|
||||
if (json is List) {
|
||||
final buffer = StringBuffer();
|
||||
for (final item in json) {
|
||||
if (item is Map && item.containsKey('insert')) {
|
||||
final ins = item['insert'];
|
||||
if (ins is String) buffer.write(ins);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore and fallthrough
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final tasksAsync = ref.watch(tasksProvider);
|
||||
|
|
@ -228,18 +209,23 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
try {
|
||||
_actionDebounce?.cancel();
|
||||
_actionController?.dispose();
|
||||
_actionController = TextEditingController();
|
||||
if (task.actionTaken != null && task.actionTaken!.isNotEmpty) {
|
||||
try {
|
||||
final decoded = jsonDecode(task.actionTaken!);
|
||||
final plain = _deltaJsonToPlainText(decoded);
|
||||
_actionController!.text = plain;
|
||||
final docJson =
|
||||
jsonDecode(task.actionTaken!) as List<dynamic>;
|
||||
final doc = quill.Document.fromJson(docJson);
|
||||
_actionController = quill.QuillController(
|
||||
document: doc,
|
||||
selection: const TextSelection.collapsed(offset: 0),
|
||||
);
|
||||
} catch (_) {
|
||||
_actionController!.text = task.actionTaken!;
|
||||
_actionController = quill.QuillController.basic();
|
||||
}
|
||||
} else {
|
||||
_actionController = quill.QuillController.basic();
|
||||
}
|
||||
} catch (_) {
|
||||
_actionController = TextEditingController();
|
||||
_actionController = quill.QuillController.basic();
|
||||
}
|
||||
|
||||
// Attach auto-save listener for action taken (debounced)
|
||||
|
|
@ -248,15 +234,19 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
_actionDebounce = Timer(
|
||||
const Duration(milliseconds: 700),
|
||||
() async {
|
||||
final plain = _actionController?.text.trim() ?? '';
|
||||
final plain =
|
||||
_actionController?.document.toPlainText().trim() ?? '';
|
||||
setState(() {
|
||||
_actionSaving = true;
|
||||
_actionSaved = false;
|
||||
});
|
||||
try {
|
||||
final deltaJson = jsonEncode(
|
||||
_actionController?.document.toDelta().toJson(),
|
||||
);
|
||||
await ref
|
||||
.read(tasksControllerProvider)
|
||||
.updateTask(taskId: task.id, actionTaken: plain);
|
||||
.updateTask(taskId: task.id, actionTaken: deltaJson);
|
||||
setState(() {
|
||||
_actionSaved = plain.isNotEmpty;
|
||||
});
|
||||
|
|
@ -1363,19 +1353,86 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
|
|||
children: [
|
||||
Column(
|
||||
children: [
|
||||
// Plain multiline editor for Action taken
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
tooltip: 'Bold',
|
||||
icon: const Icon(
|
||||
Icons.format_bold,
|
||||
),
|
||||
onPressed: () =>
|
||||
_actionController
|
||||
?.formatSelection(
|
||||
quill
|
||||
.Attribute
|
||||
.bold,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Italic',
|
||||
icon: const Icon(
|
||||
Icons.format_italic,
|
||||
),
|
||||
onPressed: () =>
|
||||
_actionController
|
||||
?.formatSelection(
|
||||
quill
|
||||
.Attribute
|
||||
.italic,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Underline',
|
||||
icon: const Icon(
|
||||
Icons.format_underlined,
|
||||
),
|
||||
onPressed: () =>
|
||||
_actionController
|
||||
?.formatSelection(
|
||||
quill
|
||||
.Attribute
|
||||
.underline,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Bullet list',
|
||||
icon: const Icon(
|
||||
Icons
|
||||
.format_list_bulleted,
|
||||
),
|
||||
onPressed: () =>
|
||||
_actionController
|
||||
?.formatSelection(
|
||||
quill
|
||||
.Attribute
|
||||
.ul,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Numbered list',
|
||||
icon: const Icon(
|
||||
Icons
|
||||
.format_list_numbered,
|
||||
),
|
||||
onPressed: () =>
|
||||
_actionController
|
||||
?.formatSelection(
|
||||
quill
|
||||
.Attribute
|
||||
.ol,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
child: MouseRegion(
|
||||
cursor:
|
||||
SystemMouseCursors.text,
|
||||
child:
|
||||
quill.QuillEditor.basic(
|
||||
controller:
|
||||
_actionController,
|
||||
readOnly: !canUpdateStatus,
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
decoration:
|
||||
const InputDecoration.collapsed(
|
||||
hintText:
|
||||
'Describe the action taken...',
|
||||
_actionController!,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
199
pubspec.lock
199
pubspec.lock
|
|
@ -133,7 +133,15 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
|
|
@ -185,6 +193,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.5+2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -193,6 +209,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
dart_earcut:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -217,6 +241,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
dart_quill_delta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_quill_delta
|
||||
sha256: bddb0b2948bd5b5a328f1651764486d162c59a8ccffd4c63e8b2c5e44be1dac4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.8.3"
|
||||
diff_match_patch:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: diff_match_patch
|
||||
sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
ed25519_edwards:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -245,10 +285,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
version: "6.1.4"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+5"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -262,6 +318,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_colorpicker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_colorpicker
|
||||
sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -302,6 +366,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
flutter_keyboard_visibility_temp_fork:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_keyboard_visibility_temp_fork
|
||||
sha256: e3d02900640fbc1129245540db16944a0898b8be81694f4bf04b6c985bed9048
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
flutter_keyboard_visibility_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -334,6 +406,11 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_localizations:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_map:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -342,6 +419,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.2"
|
||||
flutter_quill:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_quill
|
||||
sha256: b96bb8525afdeaaea52f5d02f525e05cc34acd176467ab6d6f35d434cf14fde2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.5.0"
|
||||
flutter_quill_delta_from_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_quill_delta_from_html
|
||||
sha256: "0eb801ea8dd498cadc057507af5da794d4c9599ce58b2569cb3d4bb53ba8bed2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
flutter_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -480,6 +573,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.6"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -592,22 +693,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: markdown
|
||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
version: "0.12.18"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -776,6 +885,70 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
quill_native_bridge:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge
|
||||
sha256: "76a16512e398e84216f3f659f7cb18a89ec1e141ea908e954652b4ce6cf15b18"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.1.0"
|
||||
quill_native_bridge_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_android
|
||||
sha256: b75c7e6ede362a7007f545118e756b1f19053994144ec9eda932ce5e54a57569
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
quill_native_bridge_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_ios
|
||||
sha256: d23de3cd7724d482fe2b514617f8eedc8f296e120fb297368917ac3b59d8099f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.1"
|
||||
quill_native_bridge_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_macos
|
||||
sha256: "1c0631bd1e2eee765a8b06017c5286a4e829778f4585736e048eb67c97af8a77"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.1"
|
||||
quill_native_bridge_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_platform_interface
|
||||
sha256: "8264a2bdb8a294c31377a27b46c0f8717fa9f968cf113f7dc52d332ed9c84526"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2+1"
|
||||
quill_native_bridge_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_web
|
||||
sha256: "7c723f6824b0250d7f33e8b6c23f2f8eb0103fe48ee7ebf47ab6786b64d5c05d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
quill_native_bridge_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quill_native_bridge_windows
|
||||
sha256: "3f96ced19e3206ddf4f6f7dde3eb16bdd05e10294964009ea3a806d995aa7caa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
realtime_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -953,10 +1126,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
version: "0.7.9"
|
||||
timezone:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -1093,6 +1266,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.15.0"
|
||||
wkt_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ dependencies:
|
|||
flutter_map: ^8.2.2
|
||||
latlong2: ^0.9.0
|
||||
flutter_typeahead: ^4.1.0
|
||||
flutter_quill: ^11.5.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user