Giter VIP home page Giter VIP logo

Comments (8)

iamacup avatar iamacup commented on June 8, 2024 2

Here is an example which works just how i expected when i replied the first time ;-) remember the render rules are not set in stone, you can just rewrite them if you need to. If you dont want to provide style props to the fit image you will need to work out a better way / use another library or read the image meta data to work out the width / height and work it out etc. etc. etc. - lots of options!

the changes i made are:

  1. add a new value to the allowedImageHandlers prop with value localimage:// so the render rule does not just reject the image straight up
  2. add an is/else clause to the render rule to handle the case where an image starts with localimage://

note i did a small release to export fit image from this package so it can be easier to modify the image rule

import React from 'react';
import { SafeAreaView, ScrollView, StatusBar, Text, StyleSheet } from 'react-native';

import Markdown, { FitImage } from 'react-native-markdown-display';

const copy = `
# Show a local image!
![MyImage](localimage://${require('./img.jpg')})

# Show a remote version of the same image!
![MyImage](https://i.imgur.com/D25S0Fy.jpg)
`;

var FIStyles = StyleSheet.create({
  fitImageWithSize: {
    height: 300,
    width: '100%',
  },
});

const rules = {
  image: (
    node,
    children,
    parent,
    styles,
    allowedImageHandlers,
    defaultImageHandler,
  ) => {
    const {src, alt} = node.attributes;

    // we check that the source starts with at least one of the elements in allowedImageHandlers
    const show =
      allowedImageHandlers.filter((value) => {
        return src.toLowerCase().startsWith(value.toLowerCase());
      }).length > 0;

    if (show === false && defaultImageHandler === null) {
      return null;
    }

    if(src.startsWith('localimage://')) {
      // this could be anything, does not have to be fit image!! can be react native image or whatever!
      return <FitImage
        key={node.key}
        // we grab the resource identifier provided by require and convert it back to an int
        source={Number.parseInt(src.replace('localimage://', ''), 10)}
        style={FIStyles.fitImageWithSize}
      />
    } else {
      const imageProps = {
        indicator: true,
        key: node.key,
        style: styles._VIEW_SAFE_image,
        source: {
          uri: show === true ? src : `${defaultImageHandler}${src}`,
        },
      };

      if (alt) {
        imageProps.accessible = true;
        imageProps.accessibilityLabel = alt;
      }

      return <FitImage {...imageProps} />;
    }
  },
}

const App: () => React$Node = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <ScrollView
          contentInsetAdjustmentBehavior="automatic"
          style={{height: '100%'}}
        >
            <Markdown
              rules={rules}
              allowedImageHandlers={['data:image/png;base64', 'data:image/gif;base64', 'data:image/jpeg;base64', 'https://', 'http://', 'localimage://']}
            >
              {copy}
            </Markdown>
        </ScrollView>
      </SafeAreaView>
    </>
  );
};

export default App;

Untitled 3

from react-native-markdown-display.

iamacup avatar iamacup commented on June 8, 2024

What markdown supports is this:

[STRING_NAME](STRING_LOCATION)

So when youo do something like

![MyImage](${require('./myImage.png')}) it will get converted to something like ![MyImage](73) because require statements, when inspected, reference the resources as integers.

This then gets passed to markdown, which passes MyImage and 73 to the image render code here.

Which will, after all the calculations and addition of defaultImageHandler, return something like this:

...
return <FitImage source={{uri: 'http://73'}} />;
...

which is obviously not going to work.

What you will need to do is probably pass something like this (ex 1):

![MyImage](LOCALIMAGE://${require('./myImage.png')})

or (ex 2)

![MyImage](LOCALIMAGE://./myImage.png)

and then change the render rule to handle the case where the url src starts with LOCALIMAGE to either do the require in the render rule (ex 2) or reference the src not as a URI with fitimage if the integer of the required resource is passed directly (ex 1).

There may be associated security concerns with this if you are letting users input the markdown.

from react-native-markdown-display.

andrekovac avatar andrekovac commented on June 8, 2024

Thanks for your fast reply and your thorough explanation!

I gave it a shot to implement ex1 (i.e. ![MyImage](LOCALIMAGE://${require('./myImage.png')})) but don't get it to work. This is the diff of my changes so far: andrekovac@64dd9ba

My most important change inside renderRules.js:

if (src.toLowerCase().startsWith('LOCALIMAGE://')) {
  imageProps.source = src.replace('LOCALIMAGE://', '');
} else {
  imageProps.source = {
    uri: show === true ? src : `${defaultImageHandler}${src}`,
  };
}

This is the branch I'm working on https://github.com/andrekovac/react-native-markdown-display/tree/add-local-image-support

I also tried (ex 2) (i.e. ![MyImage](LOCALIMAGE://./myImage.png)) and called require inside renderRules.js but that didn't work as well. Does it work for you?

from react-native-markdown-display.

andrekovac avatar andrekovac commented on June 8, 2024

I found the reason for it not working:

react-native-fit-image requires a style prop because it currently does not support responsive behavior for local images. 😞
In case of no style prop it doesn't display anything..

from react-native-markdown-display.

iamacup avatar iamacup commented on June 8, 2024

Congrats on geting it working :)

from react-native-markdown-display.

andrekovac avatar andrekovac commented on June 8, 2024

@iamacup Unfortunately I didn't get it to work. As I said react-native-fit-image requires a style prop in case of local images.

So this library does not support markdown images of local images. So in case of local images I unfortunately can't use markdown. Currently my solution for displaying local images properly involves a parent component which I use to retrieve the layout properties from so I right now don't know how to add it to your lib in a good way.

from react-native-markdown-display.

iamacup avatar iamacup commented on June 8, 2024

@iamacup Unfortunately I didn't get it to work. As I said react-native-fit-image requires a style prop in case of local images.

I don't know why fit image is causing this problem, if it needs the prop why can't you pass it? and if it does not work then can't you use a normal react native image instead?

from react-native-markdown-display.

andrekovac avatar andrekovac commented on June 8, 2024

Thanks @iamacup I used and adapted your solution to my needs! Thanks a lot for your effort and the very helpful example implementation! :-)

from react-native-markdown-display.

Related Issues (20)

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.