file_caption_widget.dart 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import 'package:flutter/material.dart';
  2. import 'package:photos/models/file.dart';
  3. import 'package:photos/theme/ente_theme.dart';
  4. import 'package:photos/utils/magic_util.dart';
  5. class FileCaptionWidget extends StatefulWidget {
  6. final File file;
  7. const FileCaptionWidget({required this.file, super.key});
  8. @override
  9. State<FileCaptionWidget> createState() => _FileCaptionWidgetState();
  10. }
  11. class _FileCaptionWidgetState extends State<FileCaptionWidget> {
  12. int maxLength = 280;
  13. int currentLength = 0;
  14. final _textController = TextEditingController();
  15. final _focusNode = FocusNode();
  16. String? editedCaption;
  17. String? hintText = "Add a description...";
  18. @override
  19. void initState() {
  20. _focusNode.addListener(() {
  21. final caption = widget.file.caption;
  22. if (_focusNode.hasFocus && caption != null) {
  23. _textController.text = caption;
  24. editedCaption = caption;
  25. }
  26. });
  27. editedCaption = widget.file.caption;
  28. if (editedCaption != null && editedCaption!.isNotEmpty) {
  29. hintText = editedCaption;
  30. }
  31. super.initState();
  32. }
  33. @override
  34. void dispose() {
  35. if (editedCaption != null) {
  36. editFileCaption(null, widget.file, editedCaption);
  37. }
  38. _textController.dispose();
  39. _focusNode.removeListener(() {});
  40. super.dispose();
  41. }
  42. @override
  43. Widget build(BuildContext context) {
  44. final colorScheme = getEnteColorScheme(context);
  45. final textTheme = getEnteTextTheme(context);
  46. return TextField(
  47. onEditingComplete: () async {
  48. if (editedCaption != null) {
  49. await editFileCaption(context, widget.file, editedCaption);
  50. if (mounted) {
  51. setState(() {});
  52. }
  53. }
  54. _focusNode.unfocus();
  55. },
  56. controller: _textController,
  57. focusNode: _focusNode,
  58. decoration: InputDecoration(
  59. counterStyle: textTheme.mini.copyWith(color: colorScheme.textMuted),
  60. counterText: currentLength > 99
  61. ? currentLength.toString() + " / " + maxLength.toString()
  62. : "",
  63. contentPadding: const EdgeInsets.all(16),
  64. border: InputBorder.none,
  65. focusedBorder: InputBorder.none,
  66. filled: true,
  67. fillColor: colorScheme.fillFaint,
  68. hintText: hintText,
  69. hintStyle: getEnteTextTheme(context)
  70. .small
  71. .copyWith(color: colorScheme.textMuted),
  72. ),
  73. style: getEnteTextTheme(context).small,
  74. cursorWidth: 1.5,
  75. maxLength: maxLength,
  76. minLines: 1,
  77. maxLines: 6,
  78. keyboardType: TextInputType.text,
  79. onChanged: (value) {
  80. setState(() {
  81. hintText = "Add a description...";
  82. currentLength = value.length;
  83. editedCaption = value;
  84. });
  85. },
  86. );
  87. }
  88. }