pull/1566/head
Ellet 2 years ago
parent 59ada7fb34
commit 879202546d
No known key found for this signature in database
GPG Key ID: C488CC70BBCEF0D1
  1. 6
      example/lib/presentation/quill/samples/quill_images_sample.dart
  2. 1
      flutter_quill_extensions/CHANGELOG.md
  3. 5
      flutter_quill_extensions/lib/embeds/image/editor/image_embed.dart
  4. 5
      flutter_quill_extensions/lib/embeds/video/editor/video_embed.dart
  5. 73
      flutter_quill_extensions/lib/utils/element_utils/element_shared_utils.dart
  6. 23
      flutter_quill_extensions/lib/utils/element_utils/element_utils.dart
  7. 9
      flutter_quill_extensions/lib/utils/utils.dart

@ -5,11 +5,7 @@ final quillImagesSample = [
{'insert': '\n'}, {'insert': '\n'},
{ {
'insert': {'image': Assets.images.screenshot1.path}, 'insert': {'image': Assets.images.screenshot1.path},
'attributes': { 'attributes': {'style': 'width: 40vh; height:350px; margin: 20px;'}
'width': '200',
'height': '500',
'style': 'width:500px; height:350px; margin: 20px;'
}
}, },
{'insert': '\n'}, {'insert': '\n'},
{'insert': 'Here is a network image: \n'}, {'insert': 'Here is a network image: \n'},

@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
* Fix a bug in the example when inserting an image from url * Fix a bug in the example when inserting an image from url
* Flutter Quill Extensions: * Flutter Quill Extensions:
* Add support for copying the image to the system cliboard * Add support for copying the image to the system cliboard
* Add support for other CSS units like (vh, vw) and more
## 9.0.0-dev-2 ## 9.0.0-dev-2
* An attemp to fix CI automated publishing * An attemp to fix CI automated publishing

@ -32,7 +32,10 @@ class QuillEditorImageEmbedBuilder extends EmbedBuilder {
// assert(!kIsWeb, 'Please provide image EmbedBuilder for Web'); // assert(!kIsWeb, 'Please provide image EmbedBuilder for Web');
final imageSource = standardizeImageUrl(node.value.data); final imageSource = standardizeImageUrl(node.value.data);
final ((imageSize), margin, alignment) = getElementAttributes(node); final ((imageSize), margin, alignment) = getElementAttributes(
node,
context,
);
final width = imageSize.width; final width = imageSize.width;
final height = imageSize.height; final height = imageSize.height;

@ -37,7 +37,10 @@ class QuillEditorVideoEmbedBuilder extends EmbedBuilder {
readOnly: readOnly, readOnly: readOnly,
); );
} }
final ((elementSize), margin, alignment) = getElementAttributes(node); final ((elementSize), margin, alignment) = getElementAttributes(
node,
context,
);
final width = elementSize.width; final width = elementSize.width;
final height = elementSize.height; final height = elementSize.height;

@ -1,3 +1,5 @@
import 'package:flutter/widgets.dart' show BuildContext, MediaQuery;
Map<String, String> parseCssString(String cssString) { Map<String, String> parseCssString(String cssString) {
final result = <String, String>{}; final result = <String, String>{};
final declarations = cssString.split(';'); final declarations = cssString.split(';');
@ -14,16 +16,71 @@ Map<String, String> parseCssString(String cssString) {
return result; return result;
} }
double? parseCssPropertyAsDouble(String value) { enum _CssUnit {
px('px'),
percentage('%'),
viewportWidth('vw'),
viewportHeight('vh'),
em('em'),
rem('rem'),
invalid('invalid');
const _CssUnit(this.cssName);
final String cssName;
}
double? parseCssPropertyAsDouble(
String value, {
required BuildContext context,
}) {
if (value.trim().isEmpty) { if (value.trim().isEmpty) {
return null; return null;
} }
final list = [
'px', // Try to parse it in case it's a valid double already
// '%', 'vw', 'vh', 'em', 'rem' var doubleValue = double.tryParse(value);
];
for (final element in list) { if (doubleValue != null) {
value = value.replaceFirst(element, ''); return doubleValue;
}
// If not then if it's a css numberic value then we will try to parse it
final unit = _CssUnit.values
.where((element) => value.endsWith(element.cssName))
.firstOrNull;
if (unit == null) {
return null;
}
value = value.replaceFirst(unit.cssName, '');
doubleValue = double.tryParse(value);
if (doubleValue != null) {
switch (unit) {
case _CssUnit.px:
// Do nothing
break;
case _CssUnit.percentage:
// Not supported yet
doubleValue = null;
break;
case _CssUnit.viewportWidth:
doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).width;
break;
case _CssUnit.viewportHeight:
doubleValue = (doubleValue / 100) * MediaQuery.sizeOf(context).height;
break;
case _CssUnit.em:
doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue);
break;
case _CssUnit.rem:
// Not fully supported yet
doubleValue = MediaQuery.textScalerOf(context).scale(doubleValue);
break;
case _CssUnit.invalid:
// Ignore
doubleValue = null;
break;
}
} }
return double.tryParse(value); return doubleValue;
} }

@ -1,5 +1,5 @@
import 'package:flutter/foundation.dart' show immutable; import 'package:flutter/foundation.dart' show immutable;
import 'package:flutter/widgets.dart' show Alignment; import 'package:flutter/widgets.dart' show Alignment, BuildContext;
import 'package:flutter_quill/extensions.dart'; import 'package:flutter_quill/extensions.dart';
import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node; import 'package:flutter_quill/flutter_quill.dart' show Attribute, Node;
@ -18,15 +18,20 @@ enum ExtraElementProperties {
Alignment alignment, Alignment alignment,
) getElementAttributes( ) getElementAttributes(
Node node, Node node,
BuildContext context,
) { ) {
var elementSize = const ElementSize(null, null); var elementSize = const ElementSize(null, null);
var elementAlignment = Alignment.center; var elementAlignment = Alignment.center;
double? elementMargin; double? elementMargin;
final heightValue = parseCssPropertyAsDouble( final heightValue = parseCssPropertyAsDouble(
node.style.attributes[Attribute.height.key]?.value.toString() ?? ''); node.style.attributes[Attribute.height.key]?.value.toString() ?? '',
context: context,
);
final widthValue = parseCssPropertyAsDouble( final widthValue = parseCssPropertyAsDouble(
node.style.attributes[Attribute.width.key]?.value.toString() ?? ''); node.style.attributes[Attribute.width.key]?.value.toString() ?? '',
context: context,
);
if (heightValue != null) { if (heightValue != null) {
elementSize = elementSize.copyWith( elementSize = elementSize.copyWith(
@ -47,10 +52,14 @@ enum ExtraElementProperties {
final cssAttrs = parseCssString(cssStyle.value.toString()); final cssAttrs = parseCssString(cssStyle.value.toString());
// todo: This could be improved much better // todo: This could be improved much better
final cssHeightValue = final cssHeightValue = parseCssPropertyAsDouble(
parseCssPropertyAsDouble((cssAttrs[Attribute.height.key]) ?? ''); (cssAttrs[Attribute.height.key]) ?? '',
final cssWidthValue = context: context,
parseCssPropertyAsDouble((cssAttrs[Attribute.width.key]) ?? ''); );
final cssWidthValue = parseCssPropertyAsDouble(
(cssAttrs[Attribute.width.key]) ?? '',
context: context,
);
// cssHeightValue != null && elementSize.height == null // cssHeightValue != null && elementSize.height == null
if (cssHeightValue != null) { if (cssHeightValue != null) {

@ -58,8 +58,13 @@ Future<Uint8List?> convertImageToUint8List(String image) async {
} }
return null; return null;
} }
final file = XFile(image); // TODO: Add support for all image providers like AssetImage
return await file.readAsBytes(); try {
final file = XFile(image);
return await file.readAsBytes();
} catch (e) {
return null;
}
} }
Future<SaveImageResult> saveImage({ Future<SaveImageResult> saveImage({

Loading…
Cancel
Save