Coder Social home page Coder Social logo

kumanu / contentful-rich-text-flutter Goto Github PK

View Code? Open in Web Editor NEW
46.0 46.0 29.0 152 KB

Rich Text renderer that parses Contentful Rich Text JSON object and returns a renderable Flutter widget

License: MIT License

Dart 97.32% Kotlin 0.17% Ruby 1.89% Swift 0.56% Objective-C 0.05%

contentful-rich-text-flutter's People

Contributors

czaefferer avatar hellocore avatar hoanle avatar jblough avatar jonas-zebari avatar localpcguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

contentful-rich-text-flutter's Issues

Question about the style of the text

Hello dear, thank you first for this amazing package. I want just to ask if we can modify the style of our text because I use the package and the color of the text is white and I don't know how to change it. thanks in advance.

Support additional tags

Thank you for the library!

Are you going to support tags:
EMBEDDED_ENTRY // not implemented yet
EMBEDDED_ASSET // not implemented yet
EMBEDDED_ENTRY (this is different from the BLOCKS.EMBEDDED_ENTRY) // not implemented yet
ENTRY_HYPERLINK // not implemented yet
ASSET_HYPERLINK // not implemented yet ?

Is new library update coming soon?

Click handler on hyperlink is not working

Hi, thank you for the awesome plugin.

I have data coming from contentful and some part of the data passed to Hyperlink class looks like this:
{nodeType: hyperlink, content: [{nodeType: text, value: This is a text, marks: [], data: {}}], data: {uri: https://www.domain.com}}

ISSUE

With current implementation on Hyperlink class,

  • When setting text in this line: it will always have empty value
  • Therefore the tap gesture recognizer in this line is not being "called", because its impossible to click on an empty text

SOLUTION

  • Change the implementation on this line to be text: (node['content'][0])['value']
  • Remove the need to put children, therefore deleting line since its duplicating the above suggestion

Do you have any other thoughts on this?

hyperlink not clickable

body: InkWell( child: Column( children: <Widget>[ ContentfulRichText(someVar) ] ) )

the text is displayed and everything is fine and the hyperlink is blue and underlined but when I click on it nothing happens

Support for tables

Hello! Thank you for your hard work on this very helpful package.

Will you be adding support for rich text tables any time soon?

Thank you.

Parser crashes on entry-hyperlinks

The readme says inline hyperlinks to entries are not supported (entry-hyperlinks/ENTRY_HYPERLINK), however the parser even crashes when it encounters these. Is it possible to have the parser just ignore these as it does with embedded assets for example?

Below is an example JSON generated by Contentful, my Dart file to parse the JSON (it contains the same JSON just encoded), and the log of the crash.

{
  "nodeType": "document",
  "data": {},
  "content": [
    {
      "nodeType": "paragraph",
      "content": [
        {
          "nodeType": "text",
          "value": "text before",
          "marks": [],
          "data": {}
        }
      ],
      "data": {}
    },
    {
      "nodeType": "paragraph",
      "content": [
        {
          "nodeType": "text",
          "value": "",
          "marks": [],
          "data": {}
        },
        {
          "nodeType": "entry-hyperlink",
          "content": [
            {
              "nodeType": "text",
              "value": "my content link",
              "marks": [],
              "data": {}
            }
          ],
          "data": {
            "target": {
              "sys": {
                "id": "6eiOBFjSlQukBFMx4XtzE",
                "type": "Link",
                "linkType": "Entry"
              }
            }
          }
        },
        {
          "nodeType": "text",
          "value": "",
          "marks": [],
          "data": {}
        }
      ],
      "data": {}
    },
    {
      "nodeType": "paragraph",
      "content": [
        {
          "nodeType": "text",
          "value": "text after",
          "marks": [],
          "data": {}
        }
      ],
      "data": {}
    }
  ]
}
import 'dart:convert';

import 'package:contentful_rich_text/contentful_rich_text.dart';
import 'package:flutter/material.dart';

class LinkErrorScreen extends StatelessWidget {
  const LinkErrorScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    dynamic document = jsonDecode("{\r\n  \"nodeType\": \"document\",\r\n  \"data\": {},\r\n  \"content\": [\r\n    {\r\n      \"nodeType\": \"paragraph\",\r\n      \"content\": [\r\n        {\r\n          \"nodeType\": \"text\",\r\n          \"value\": \"text before\",\r\n          \"marks\": [],\r\n          \"data\": {}\r\n        }\r\n      ],\r\n      \"data\": {}\r\n    },\r\n    {\r\n      \"nodeType\": \"paragraph\",\r\n      \"content\": [\r\n        {\r\n          \"nodeType\": \"text\",\r\n          \"value\": \"\",\r\n          \"marks\": [],\r\n          \"data\": {}\r\n        },\r\n        {\r\n          \"nodeType\": \"entry-hyperlink\",\r\n          \"content\": [\r\n            {\r\n              \"nodeType\": \"text\",\r\n              \"value\": \"my content link\",\r\n              \"marks\": [],\r\n              \"data\": {}\r\n            }\r\n          ],\r\n          \"data\": {\r\n            \"target\": {\r\n              \"sys\": {\r\n                \"id\": \"6eiOBFjSlQukBFMx4XtzE\",\r\n                \"type\": \"Link\",\r\n                \"linkType\": \"Entry\"\r\n              }\r\n            }\r\n          }\r\n        },\r\n        {\r\n          \"nodeType\": \"text\",\r\n          \"value\": \"\",\r\n          \"marks\": [],\r\n          \"data\": {}\r\n        }\r\n      ],\r\n      \"data\": {}\r\n    },\r\n    {\r\n      \"nodeType\": \"paragraph\",\r\n      \"content\": [\r\n        {\r\n          \"nodeType\": \"text\",\r\n          \"value\": \"text after\",\r\n          \"marks\": [],\r\n          \"data\": {}\r\n        }\r\n      ],\r\n      \"data\": {}\r\n    }\r\n  ]\r\n}\r\n");
    return ContentfulRichText(document).documentToWidgetTree;
  }
}
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building Paragraph(dirty):
The method 'contains' was called on null.
Receiver: null
Tried calling: contains("&")
The relevant error-causing widget was:
  LinkErrorScreen                                                                   lib/pages/home.dart
When the exception was thrown, this was the stack:
#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:51:5)
#1      HtmlUnescapeBase.convert                                                    package:html_unescape/src/base.dart
#2      ContentfulRichText._processInlineNode                                       package:contentful_rich_text/contentful_rich_text.dart
#3      ContentfulRichText.nodeToWidget.<anonymous closure>.<anonymous closure>     package:contentful_rich_text/contentful_rich_text.dart
#4      MappedListIterable.elementAt  (dart:_internal/iterable.dart:417:31)
#5      ListIterator.moveNext  (dart:_internal/iterable.dart:343:26)
#6      new List.from  (dart:core-patch/array_patch.dart:57:19)
#7      ContentfulRichText.nodeToWidget.<anonymous closure>                         package:contentful_rich_text/contentful_rich_text.dart
#8      Paragraph.build                                                             package:contentful_rich_text/widgets/paragraph.dart
#9      StatelessElement.build                                                      package:flutter/…/widgets/framework.dart
#10     ComponentElement.performRebuild                                             package:flutter/…/widgets/framework.dart
#11     Element.rebuild                                                             package:flutter/…/widgets/framework.dart
#12     ComponentElement._firstBuild                                                package:flutter/…/widgets/framework.dart
#13     ComponentElement.mount                                                      package:flutter/…/widgets/framework.dart
#14     Element.inflateWidget                                                       package:flutter/…/widgets/framework.dart
#15     MultiChildRenderObjectElement.mount                                         package:flutter/…/widgets/framework.dart
...     Normal element mounting (45 frames)
#60     Element.inflateWidget                                                       package:flutter/…/widgets/framework.dart
#61     Element.updateChild                                                         package:flutter/…/widgets/framework.dart
#62     SliverMultiBoxAdaptorElement.updateChild                                    package:flutter/…/widgets/sliver.dart
#63     SliverMultiBoxAdaptorElement.createChild.<anonymous closure>                package:flutter/…/widgets/sliver.dart
#64     BuildOwner.buildScope                                                       package:flutter/…/widgets/framework.dart
#65     SliverMultiBoxAdaptorElement.createChild                                    package:flutter/…/widgets/sliver.dart
#66     RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure>        package:flutter/…/rendering/sliver_multi_box_adaptor.dart
#67     RenderObject.invokeLayoutCallback.<anonymous closure>                       package:flutter/…/rendering/object.dart
#68     PipelineOwner._enableMutationsToDirtySubtrees                               package:flutter/…/rendering/object.dart
#69     RenderObject.invokeLayoutCallback                                           package:flutter/…/rendering/object.dart
#70     RenderSliverMultiBoxAdaptor._createOrObtainChild                            package:flutter/…/rendering/sliver_multi_box_adaptor.dart
#71     RenderSliverMultiBoxAdaptor.addInitialChild                                 package:flutter/…/rendering/sliver_multi_box_adaptor.dart
#72     RenderSliverFixedExtentBoxAdaptor.performLayout                             package:flutter/…/rendering/sliver_fixed_extent_list.dart
#73     RenderObject.layout                                                         package:flutter/…/rendering/object.dart
#74     RenderSliverEdgeInsetsPadding.performLayout                                 package:flutter/…/rendering/sliver_padding.dart
#75     _RenderSliverFractionalPadding.performLayout                                package:flutter/…/widgets/sliver_fill.dart
#76     RenderObject.layout                                                         package:flutter/…/rendering/object.dart
#77     RenderViewportBase.layoutChildSequence                                      package:flutter/…/rendering/viewport.dart
#78     RenderViewport._attemptLayout                                               package:flutter/…/rendering/viewport.dart
#79     RenderViewport.performLayout                                                package:flutter/…/rendering/viewport.dart
#80     RenderObject._layoutWithoutResize                                           package:flutter/…/rendering/object.dart
#81     PipelineOwner.flushLayout                                                   package:flutter/…/rendering/object.dart
#82     RendererBinding.drawFrame                                                   package:flutter/…/rendering/binding.dart
#83     WidgetsBinding.drawFrame                                                    package:flutter/…/widgets/binding.dart
#84     RendererBinding._handlePersistentFrameCallback                              package:flutter/…/rendering/binding.dart
#85     SchedulerBinding._invokeFrameCallback                                       package:flutter/…/scheduler/binding.dart
#86     SchedulerBinding.handleDrawFrame                                            package:flutter/…/scheduler/binding.dart
#87     SchedulerBinding._handleDrawFrame                                           package:flutter/…/scheduler/binding.dart
#91     _invoke  (dart:ui/hooks.dart:253:10)
#92     _drawFrame  (dart:ui/hooks.dart:211:3)
(elided 3 frames from dart:async)
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building Paragraph(dirty):
The method 'contains' was called on null.
Receiver: null
Tried calling: contains("&")

The relevant error-causing widget was
    LinkErrorScreen                                                                 lib/pages/home.dart
When the exception was thrown, this was the stack
#0      Object.noSuchMethod  (dart:core-patch/object_patch.dart:51:5)
#1      HtmlUnescapeBase.convert                                                    package:html_unescape/src/base.dart
#2      ContentfulRichText._processInlineNode                                       package:contentful_rich_text/contentful_rich_text.dart
#3      ContentfulRichText.nodeToWidget.<anonymous closure>.<anonymous closure>     package:contentful_rich_text/contentful_rich_text.dart
#4      MappedListIterable.elementAt  (dart:_internal/iterable.dart:417:31)
...
════════════════════════════════════════════════════════════════════════════════

Not sufficient space between paragraphs

Problem

Text appears different on Contentful compared to Flutter. To be more precise, the space between the paragraphs/headings is missing.

Contentful

Screenshot 2020-05-12 at 11 50 28

Flutter

Screenshot 2020-05-12 at 12 43 52

Workaround

Do double line breaks after each paragraph/heading.

RenderMark and RenderNode are not working

Hi, I used bellow code for making my widget:

class RowMagazineTextItemWidget extends RowMagazineItemFactory {
  const RowMagazineTextItemWidget({super.key, required super.rowItem});

  @override
  Widget build(BuildContext context) {
    final item = rowItem as MagazineRowTextModule;
    RenderMark renderMark = RenderMark({
      [MARKS.BOLD.value]:
          Theme.of(context).textTheme.titleLarge!.copyWith(color: Colors.amber)
    });
    RenderNode renderNode = RenderNode({
      [BLOCKS.PARAGRAPH.value]: (node, next) => ParagraphWidget(
            next: next,
            node: node,
          ),
      [BLOCKS.DOCUMENT.value]: (node, next) => ParagraphWidget(
            next: next,
            node: node,
          ),
      [BLOCKS.HEADING_1.value]: (node, next) => ParagraphWidget(
            next: next,
            node: node,
          ),
    });
    var options = Options(
      renderMark: renderMark,
      renderNode: renderNode,
    );
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: normalPadding),
      child: ContentfulRichText(item.richTextJson, options: options)
          .documentToWidgetTree,
    );
  }
}

class ParagraphWidget extends StatelessWidget {
  final dynamic node;
  final Next next;
  const ParagraphWidget({
    super.key,
    required this.node,
    required this.next,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: 2.0, bottom: 15.0),
      child: Text.rich(
        TextSpan(
          text: '',
          children: next(node['content']),
        ),
        style: const TextStyle(fontSize: 48, color: Colors.red),
      ),
    );
  }
}

It stil using the default theme and dont use my changes.

support transfer to plain text

Thanks for your library, it helps us a lot parsing the contentful data.

Will this package support transfer contentful raw data to raw text like this npm package in the future?

looking forward for your reply. Thanks 😸

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.