Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix wrong custom embed key #962

Merged
merged 1 commit into from
Sep 27, 2022

Conversation

theachoem
Copy link
Contributor

@theachoem theachoem commented Sep 27, 2022

_node.value.type & node.value.type has different value in custom embed case which lead to error, should always use node.value.type.

See how it error In editor.dart:

if (builders != null) {
  var _node = node;

  // Creates correct node for custom embed
  if (node.value.type == BlockEmbed.customType) {
    _node = Embed(CustomBlockEmbed.fromJsonString(node.value.data));
  }

  // error here since it can't find that key
  for (final builder in builders) {
    if (builder.key == _node.value.type) {
      return builder.build(context, controller, _node, readOnly);
    }
  }
}

throw UnimplementedError(
  'Embeddable type "${node.value.type}" is not supported by supplied '
  'embed builders. You must pass your own builder function to '
  'embedBuilders property of QuillEditor or QuillField widgets.',
);

@singerdmx singerdmx merged commit f314dbf into singerdmx:master Sep 27, 2022
@theachoem theachoem deleted the wrong-custom-embed-key branch September 27, 2022 13:14
@Jon-Salmon
Copy link
Collaborator

@singerdmx I do not believe this fix is correct and I think it should be reverted.

@theachoem What was the motivation for this change? In the original code, multiple custom builders can be provided, each corresponding to a custom type. After this change, a single builder has to be used to handle any type that isn't image, video or function.

As all the nodes of custom builders are stored in the following form, it has to be decoded before the type can be compared with the builders.

custom: "{custom_type: data}"

@singerdmx
Copy link
Owner

I can see _node is being changed during the loop

@singerdmx
Copy link
Owner

@Jon-Salmon could you submit a PR to revert it please?

Jon-Salmon added a commit to Jon-Salmon/flutter-quill that referenced this pull request Sep 27, 2022
@Jon-Salmon Jon-Salmon mentioned this pull request Sep 27, 2022
singerdmx pushed a commit that referenced this pull request Sep 27, 2022
@theachoem
Copy link
Contributor Author

theachoem commented Sep 28, 2022

@Jon-Salmon @singerdmx

In block embed, we have image, fomula, video & custom. If user decide to custom, we can do in that custom widget. It will not mix up between custom & original block embed. Revert changes break the previous user data. I will send sample data later.

Here is how I handle it.

QuillEditor(
  embedBuilders: [
    QuillImageRenderer(),
    QuillCustomRenderer(),
  ],
  ...
}
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' as quill;
import 'package:spooky/views/detail/quill_renderer/custom_date_block_renderer.dart';
import 'package:spooky/views/detail/quill_renderer/quill_unsupported_renderer.dart';
import 'package:spooky/views/detail/quill_renderer_helper/date_block_embed.dart';

class QuillCustomRenderer extends quill.EmbedBuilder {
  @override
  String get key => quill.BlockEmbed.customType;

  @override
  Widget build(BuildContext context, quill.QuillController controller, quill.Embed node, bool readOnly) {
    quill.Embeddable block = node.value;

    switch (block.type) {
      case DateBlockEmbed.blockType:
        return CustomDateBlockRenderer(
          block: block as quill.CustomBlockEmbed,
          readOnly: readOnly,
          controller: controller,
        );
      default:
        return const QuillUnsupportedRenderer();
    }
  }
}

@theachoem
Copy link
Contributor Author

In lib/src/models/documents/nodes/embeddable.dart.

@theachoem
Copy link
Contributor Author

image

We can just do builder.key == _node.value.type || builder.key == node.value.type instead. But it will make some inconsistency on data.

@theachoem
Copy link
Contributor Author

theachoem commented Sep 28, 2022

Data sample:

[
  { "insert": "Journey!\n\n" },
  {
    "insert": {
      "custom": "{\"date\":\"[{\\\"insert\\\":\\\"2022-09-28T07:51:20.595740\\\\n\\\"}]\"}"
    }
  },
  { "insert": "\n\n" },
  {
    "insert": {
      "image": "~/Library/Developer/CoreSimulator/Devices/B5F51001-AAA2-4155-8033-62F671A24B66/data/Containers/Data/Application/42C2A551-F56E-4864-9535-8B91C0FA4F83/tmp/image_picker_6A40603C-3BD4-4F07-B7E1-8F72FD5072D9-10323-000001C059405FC3.jpg"
    }
  },
  { "insert": "\n" }
]

image

@singerdmx
Copy link
Owner

@Jon-Salmon Your thought?

@Jon-Salmon
Copy link
Collaborator

@theachoem this doesn't break existing user data, instead your custom builder should look like:

class QuillCustomRenderer extends quill.EmbedBuilder {
  @override
  String get key => DateBlockEmbed.blockType;

  @override
  Widget build(BuildContext context, quill.QuillController controller, quill.Embed node, bool readOnly) {
    quill.Embeddable block = node.value;

    return CustomDateBlockRenderer(
        block: block as quill.CustomBlockEmbed,
        readOnly: readOnly,
        controller: controller,
      );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants