Skip to content
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,6 @@ You can insert an image into the input using [setImage](docs/API_REFERENCE.md#se

The image will be put into a single line in the input and will affect the line's height as well as input's height. Keep in mind, that image will replace currently selected text or insert into the cursor position if there is no text selection.

> [!NOTE]
> The iOS doesn't support inline images just yet, but it's planned in the near future!

Comment thread
szydlovsky marked this conversation as resolved.
## Style Detection

All of the above styles can be detected with the use of [onChangeState](docs/API_REFERENCE.md#onchangestate) event payload.
Expand Down
9 changes: 8 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Text,
type NativeSyntheticEvent,
ScrollView,
Platform,
} from 'react-native';
import {
EnrichedTextInput,
Expand Down Expand Up @@ -202,7 +203,13 @@ export default function App() {
selectionLimit: 1,
});

const imageUri = response.assets?.[0]?.originalPath;
let imageUri;
if (Platform.OS === 'android') {
imageUri = response.assets?.[0]?.originalPath;
} else {
imageUri = response.assets?.[0]?.uri;
}
Comment thread
kacperzolkiewski marked this conversation as resolved.
Outdated

if (!imageUri) return;

ref.current?.setImage(imageUri);
Expand Down
41 changes: 34 additions & 7 deletions ios/EnrichedTextInputView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,42 @@ - (void)setDefaults {
@([H3Style getStyleType]): [[H3Style alloc] initWithInput:self],
@([UnorderedListStyle getStyleType]): [[UnorderedListStyle alloc] initWithInput:self],
@([OrderedListStyle getStyleType]): [[OrderedListStyle alloc] initWithInput:self],
@([BlockQuoteStyle getStyleType]): [[BlockQuoteStyle alloc] initWithInput:self]
@([BlockQuoteStyle getStyleType]): [[BlockQuoteStyle alloc] initWithInput:self],
@([ImageStyle getStyleType]): [[ImageStyle alloc] initWithInput:self]
};

_conflictingStyles = @{
@([BoldStyle getStyleType]) : @[],
@([ItalicStyle getStyleType]) : @[],
@([UnderlineStyle getStyleType]) : @[],
@([StrikethroughStyle getStyleType]) : @[],
@([InlineCodeStyle getStyleType]) : @[@([LinkStyle getStyleType]), @([MentionStyle getStyleType])],
@([InlineCodeStyle getStyleType]) : @[@([LinkStyle getStyleType]), @([MentionStyle getStyleType]), @([ImageStyle getStyleType])],
Comment thread
szydlovsky marked this conversation as resolved.
Outdated
@([LinkStyle getStyleType]): @[@([InlineCodeStyle getStyleType]), @([LinkStyle getStyleType]), @([MentionStyle getStyleType])],
@([MentionStyle getStyleType]): @[@([InlineCodeStyle getStyleType]), @([LinkStyle getStyleType])],
@([H1Style getStyleType]): @[@([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([H2Style getStyleType]): @[@([H1Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([H3Style getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([UnorderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([OrderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([OrderedListStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([BlockQuoteStyle getStyleType])],
@([BlockQuoteStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType])]
@([BlockQuoteStyle getStyleType]): @[@([H1Style getStyleType]), @([H2Style getStyleType]), @([H3Style getStyleType]), @([UnorderedListStyle getStyleType]), @([OrderedListStyle getStyleType])],
Comment thread
kacperzolkiewski marked this conversation as resolved.
Outdated
@([ImageStyle getStyleType]) : @[@([LinkStyle getStyleType]), @([MentionStyle getStyleType])]
};

_blockingStyles = @{
@([BoldStyle getStyleType]) : @[],
@([ItalicStyle getStyleType]) : @[],
@([UnderlineStyle getStyleType]) : @[],
@([StrikethroughStyle getStyleType]) : @[],
@([InlineCodeStyle getStyleType]) : @[],
@([LinkStyle getStyleType]): @[],
@([MentionStyle getStyleType]): @[],
@([InlineCodeStyle getStyleType]) : @[@([ImageStyle getStyleType])],
@([LinkStyle getStyleType]): @[@([ImageStyle getStyleType])],
@([MentionStyle getStyleType]): @[@([ImageStyle getStyleType])],
Comment thread
szydlovsky marked this conversation as resolved.
Outdated
@([H1Style getStyleType]): @[],
@([H2Style getStyleType]): @[],
@([H3Style getStyleType]): @[],
@([UnorderedListStyle getStyleType]): @[],
@([OrderedListStyle getStyleType]): @[],
@([BlockQuoteStyle getStyleType]): @[],
@([ImageStyle getStyleType]) : @[@([InlineCodeStyle getStyleType])]
};

parser = [[InputParser alloc] initWithInput:self];
Expand Down Expand Up @@ -347,6 +350,16 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
}
}

if(newViewProps.htmlStyle.img.width != oldViewProps.htmlStyle.img.width) {
[newConfig setImageWidth:newViewProps.htmlStyle.img.width];
stylePropChanged = YES;
}

if(newViewProps.htmlStyle.img.height != oldViewProps.htmlStyle.img.height) {
[newConfig setImageHeight:newViewProps.htmlStyle.img.height];
stylePropChanged = YES;
}

if(newViewProps.htmlStyle.a.textDecorationLine != oldViewProps.htmlStyle.a.textDecorationLine) {
NSString *objcString = [NSString fromCppString:newViewProps.htmlStyle.a.textDecorationLine];
if([objcString isEqualToString:DecorationUnderline]) {
Expand Down Expand Up @@ -703,7 +716,7 @@ - (void)tryUpdatingActiveStyles {
.isOrderedList = [_activeStyles containsObject: @([OrderedListStyle getStyleType])],
.isBlockQuote = [_activeStyles containsObject: @([BlockQuoteStyle getStyleType])],
.isCodeBlock = NO, // [_activeStyles containsObject: @([CodeBlockStyle getStyleType])],
.isImage = NO // [_activeStyles containsObject: @([ImageStyle getStyleType]])],
.isImage = [_activeStyles containsObject: @([ImageStyle getStyleType])],
});
}
}
Expand Down Expand Up @@ -771,6 +784,9 @@ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args {
[self toggleParagraphStyle:[OrderedListStyle getStyleType]];
} else if([commandName isEqualToString:@"toggleBlockQuote"]) {
[self toggleParagraphStyle:[BlockQuoteStyle getStyleType]];
} else if([commandName isEqualToString:@"addImage"]) {
NSString *uri = (NSString *)args[0];
[self addImage:uri];
}
}

Expand Down Expand Up @@ -917,6 +933,17 @@ - (void)addMention:(NSString *)indicator text:(NSString *)text attributes:(NSStr
}
}

- (void)addImage:(NSString *)uri
Comment thread
szydlovsky marked this conversation as resolved.
{
ImageStyle *imageStyleClass = (ImageStyle *)stylesDict[@([ImageStyle getStyleType])];
if(imageStyleClass == nullptr) { return; }

if([self handleStyleBlocksAndConflicts:[ImageStyle getStyleType] range:textView.selectedRange]) {
[imageStyleClass addImage:uri];
[self anyTextMayHaveBeenModified];
}
}

- (void)startMentionWithIndicator:(NSString *)indicator {
MentionStyle *mentionStyleClass = (MentionStyle *)stylesDict[@([MentionStyle getStyleType])];
if(mentionStyleClass == nullptr) { return; }
Expand Down
4 changes: 4 additions & 0 deletions ios/config/InputConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@
- (void)setLinkDecorationLine:(TextDecorationLineEnum)newValue;
- (void)setMentionStyleProps:(NSDictionary *)newValue;
- (MentionStyleProps *)mentionStylePropsForIndicator:(NSString *)indicator;
- (void)setImageWidth:(CGFloat)newValue;
- (CGFloat)imageWidth;
- (void)setImageHeight:(CGFloat)newValue;
- (CGFloat)imageHeight;
@end
20 changes: 20 additions & 0 deletions ios/config/InputConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ @implementation InputConfig {
UIColor *_linkColor;
TextDecorationLineEnum _linkDecorationLine;
NSDictionary *_mentionProperties;
CGFloat _imageWidth;
CGFloat _imageHeight;
}

- (instancetype) init {
Expand Down Expand Up @@ -79,6 +81,8 @@ - (id)copyWithZone:(NSZone *)zone {
copy->_linkColor = [_linkColor copy];
copy->_linkDecorationLine = [_linkDecorationLine copy];
copy->_mentionProperties = [_mentionProperties mutableCopy];
copy->_imageWidth = _imageWidth;
copy->_imageHeight = _imageHeight;
return copy;
}

Expand Down Expand Up @@ -379,4 +383,20 @@ - (MentionStyleProps *)mentionStylePropsForIndicator:(NSString *)indicator {
return fallbackProps;
}

- (CGFloat)imageWidth {
return _imageWidth;
}

- (void)setImageWidth:(CGFloat)newValue {
_imageWidth = newValue;
}

- (CGFloat)imageHeight {
return _imageHeight;
}

- (void)setImageHeight:(CGFloat)newValue {
_imageHeight = newValue;
}

@end
36 changes: 35 additions & 1 deletion ios/inputParser/InputParser.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ - (NSString *)parseToHtmlFromRange:(NSRange)range {

// append closing tags
for(NSNumber *style in sortedEndedStyles) {
if ([style isEqualToNumber: @([ImageStyle getStyleType])]) {
continue;
}
NSString *tagContent = [self tagContentForStyle:style openingTag:NO location:currentRange.location];
[result appendString: [NSString stringWithFormat:@"</%@>", tagContent]];
}
Expand Down Expand Up @@ -189,6 +192,9 @@ - (NSString *)parseToHtmlFromRange:(NSRange)range {

// append closing tags
for(NSNumber *style in sortedEndedStyles) {
if ([style isEqualToNumber: @([ImageStyle getStyleType])]) {
continue;
}
NSString *tagContent = [self tagContentForStyle:style openingTag:NO location:currentRange.location];
[result appendString: [NSString stringWithFormat:@"</%@>", tagContent]];
}
Expand All @@ -202,7 +208,11 @@ - (NSString *)parseToHtmlFromRange:(NSRange)range {
// append opening tags
for(NSNumber *style in sortedNewStyles) {
NSString *tagContent = [self tagContentForStyle:style openingTag:YES location:currentRange.location];
[result appendString: [NSString stringWithFormat:@"<%@>", tagContent]];
if ([style isEqualToNumber: @([ImageStyle getStyleType])]) {
[result appendString: [NSString stringWithFormat:@"<%@/>", tagContent]];
} else {
[result appendString: [NSString stringWithFormat:@"<%@>", tagContent]];
}
}

// append the letter and escape it if needed
Expand All @@ -223,6 +233,9 @@ - (NSString *)parseToHtmlFromRange:(NSRange)range {

// append closing tags
for(NSNumber *style in sortedEndedStyles) {
if ([style isEqualToNumber: @([ImageStyle getStyleType])]) {
continue;
}
NSString *tagContent = [self tagContentForStyle:style openingTag:NO location:_input->textView.textStorage.string.length - 1];
[result appendString: [NSString stringWithFormat:@"</%@>", tagContent]];
}
Expand Down Expand Up @@ -273,6 +286,19 @@ - (NSString *)tagContentForStyle:(NSNumber *)style openingTag:(BOOL)openingTag l
return @"b";
} else if([style isEqualToNumber: @([ItalicStyle getStyleType])]) {
return @"i";
} else if ([style isEqualToNumber: @([ImageStyle getStyleType])]) {
if(openingTag) {
ImageStyle *imageStyle = (ImageStyle *)_input->stylesDict[@([ImageStyle getStyleType])];
if(imageStyle != nullptr) {
ImageData *data = [imageStyle getImageDataAt:location];
if(data != nullptr && data.uri != nullptr) {
return [NSString stringWithFormat:@"img src=\"%@\"", data.uri];
}
}
return @"img";
} else {
return @"";
}
} else if([style isEqualToNumber: @([UnderlineStyle getStyleType])]) {
return @"u";
} else if([style isEqualToNumber: @([StrikethroughStyle getStyleType])]) {
Expand Down Expand Up @@ -603,6 +629,14 @@ - (NSArray *)getTextAndStylesFromHtml:(NSString *)fixedHtml {
[styleArr addObject:@([BoldStyle getStyleType])];
} else if([tagName isEqualToString:@"i"]) {
[styleArr addObject:@([ItalicStyle getStyleType])];
} else if([tagName isEqualToString:@"img"]) {
[styleArr addObject:@([ImageStyle getStyleType])];
// cut only the uri from the src="..." string
NSString *uri = [params substringWithRange:NSMakeRange(5, params.length - 6)];
Comment thread
szydlovsky marked this conversation as resolved.
Outdated
ImageData *imageData = [[ImageData alloc] init];
imageData.uri = uri;

stylePair.styleValue = imageData;
} else if([tagName isEqualToString:@"u"]) {
[styleArr addObject:@([UnderlineStyle getStyleType])];
} else if([tagName isEqualToString:@"s"]) {
Expand Down
Loading
Loading