Repository navigation
Added visual cue for rich text submit action #3430
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,45 +6,44 @@ | |
| // | ||
|
|
||
| #import "ACRRichTextBlockRenderer.h" | ||
| #import "ACRContentHoldingUIView.h" | ||
| #import "RichTextBlock.h" | ||
| #import "TextRun.h" | ||
| #import "ACRAggregateTarget.h" | ||
| #import "HostConfig.h" | ||
| #import "MarkDownParser.h" | ||
| #import "ACRView.h" | ||
| #import "ACOHostConfigPrivate.h" | ||
| #import "ACOBaseCardElementPrivate.h" | ||
| #import "ACOBaseActionElementPrivate.h" | ||
| #import "ACOBaseCardElementPrivate.h" | ||
| #import "ACOHostConfigPrivate.h" | ||
| #import "ACRAggregateTarget.h" | ||
| #import "ACRContentHoldingUIView.h" | ||
| #import "ACRLongPressGestureRecognizerFactory.h" | ||
| #import "ACRUILabel.h" | ||
| #import "ACRView.h" | ||
| #import "DateTimePreparsedToken.h" | ||
| #import "DateTimePreparser.h" | ||
| #import "HostConfig.h" | ||
| #import "MarkDownParser.h" | ||
| #import "RichTextBlock.h" | ||
| #import "TextRun.h" | ||
| #import "UtiliOS.h" | ||
| #import "ACRLongPressGestureRecognizerFactory.h" | ||
|
|
||
| @implementation ACRRichTextBlockRenderer | ||
|
|
||
| + (ACRRichTextBlockRenderer *)getInstance | ||
| { | ||
| + (ACRRichTextBlockRenderer *)getInstance { | ||
| static ACRRichTextBlockRenderer *singletonInstance = [[self alloc] init]; | ||
| return singletonInstance; | ||
| } | ||
|
|
||
| + (ACRCardElementType)elemType | ||
| { | ||
| + (ACRCardElementType)elemType { | ||
| return ACRRichTextBlock; | ||
| } | ||
|
|
||
| - (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup | ||
| rootView:(ACRView *)rootView | ||
| inputs:(NSMutableArray *)inputs | ||
| baseCardElement:(ACOBaseCardElement *)acoElem | ||
| hostConfig:(ACOHostConfig *)acoConfig; | ||
| rootView:(ACRView *)rootView | ||
| inputs:(NSMutableArray *)inputs | ||
| baseCardElement:(ACOBaseCardElement *)acoElem | ||
| hostConfig:(ACOHostConfig *)acoConfig; | ||
| { | ||
| std::shared_ptr<HostConfig> config = [acoConfig getHostConfig]; | ||
| std::shared_ptr<BaseCardElement> elem = [acoElem element]; | ||
| std::shared_ptr<RichTextBlock> rTxtBlck = std::dynamic_pointer_cast<RichTextBlock>(elem); | ||
| ACRUILabel *lab = [[ACRUILabel alloc] initWithFrame:CGRectMake(0,0,viewGroup.frame.size.width, 0)]; | ||
| ACRUILabel *lab = | ||
| [[ACRUILabel alloc] initWithFrame:CGRectMake(0, 0, viewGroup.frame.size.width, 0)]; | ||
| lab.backgroundColor = [UIColor clearColor]; | ||
| lab.style = [viewGroup style]; | ||
| lab.editable = NO; | ||
|
|
@@ -53,15 +52,16 @@ - (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup | |
| lab.layoutManager.usesFontLeading = false; | ||
|
|
||
| NSMutableAttributedString *content = [[NSMutableAttributedString alloc] init]; | ||
| if(rootView){ | ||
| if (rootView) { | ||
| NSMutableDictionary *textMap = [rootView getTextMap]; | ||
|
|
||
| for(const auto &inlineText : rTxtBlck->GetInlines()) { | ||
| for (const auto &inlineText : rTxtBlck->GetInlines()) { | ||
| std::shared_ptr<TextRun> textRun = std::static_pointer_cast<TextRun>(inlineText); | ||
| if (textRun) { | ||
| NSNumber *number = [NSNumber numberWithUnsignedLongLong:(unsigned long long)textRun.get()]; | ||
| NSNumber *number = | ||
| [NSNumber numberWithUnsignedLongLong:(unsigned long long)textRun.get()]; | ||
| NSString *key = [number stringValue]; | ||
| NSDictionary* data = textMap[key]; | ||
| NSDictionary *data = textMap[key]; | ||
| NSData *htmlData = nil; | ||
| NSDictionary *options = nil; | ||
| NSDictionary *descriptor = nil; | ||
|
|
@@ -75,55 +75,91 @@ - (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup | |
|
|
||
| NSMutableAttributedString *textRunContent = nil; | ||
| // Initializing NSMutableAttributedString for HTML rendering is very slow | ||
| if(htmlData) { | ||
| textRunContent = [[NSMutableAttributedString alloc] initWithData:htmlData options:options documentAttributes:nil error:nil]; | ||
| if (htmlData) { | ||
| textRunContent = [[NSMutableAttributedString alloc] initWithData:htmlData | ||
| options:options | ||
| documentAttributes:nil | ||
| error:nil]; | ||
| lab.selectable = YES; | ||
| lab.dataDetectorTypes = UIDataDetectorTypeLink; | ||
| lab.userInteractionEnabled = YES; | ||
| } else { | ||
| textRunContent = [[NSMutableAttributedString alloc] initWithString:text attributes:descriptor]; | ||
| textRunContent = [[NSMutableAttributedString alloc] initWithString:text | ||
| attributes:descriptor]; | ||
| // text is preprocessed by markdown parser, and will wrapped by <p></P> | ||
| // lines below remove the p tags | ||
| [textRunContent deleteCharactersInRange:NSMakeRange(0, 3)]; | ||
| [textRunContent deleteCharactersInRange:NSMakeRange([textRunContent length] -4, 4)]; | ||
| [textRunContent | ||
| deleteCharactersInRange:NSMakeRange([textRunContent length] - 4, 4)]; | ||
| } | ||
| // Set paragraph style such as line break mode and alignment | ||
| NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; | ||
| paragraphStyle.alignment = [ACOHostConfig getTextBlockAlignment:rTxtBlck->GetHorizontalAlignment()]; | ||
| paragraphStyle.alignment = | ||
| [ACOHostConfig getTextBlockAlignment:rTxtBlck->GetHorizontalAlignment()]; | ||
|
|
||
| // Obtain text color to apply to the attributed string | ||
| ACRContainerStyle style = lab.style; | ||
| auto foregroundColor = [acoConfig getTextBlockColor:style textColor:textRun->GetTextColor() subtleOption:textRun->GetIsSubtle()]; | ||
| auto foregroundColor = [acoConfig getTextBlockColor:style | ||
| textColor:textRun->GetTextColor() | ||
| subtleOption:textRun->GetIsSubtle()]; | ||
|
|
||
| // Config and add Select Action | ||
| std::shared_ptr<BaseActionElement> baseAction = textRun->GetSelectAction(); | ||
| if(baseAction) { | ||
| NSObject* target; | ||
| if (ACRRenderingStatus::ACROk == buildTarget([rootView getSelectActionsTargetBuilderDirector], baseAction, &target)) { | ||
| [textRunContent addAttribute:@"SelectAction" value:target range:NSMakeRange(0, textRunContent.length - 1)]; | ||
| [ACRLongPressGestureRecognizerFactory addTapGestureRecognizerToUITextView:lab target:(NSObject<ACRSelectActionDelegate> *)target rootView:rootView hostConfig:acoConfig]; | ||
| if (baseAction) { | ||
| NSObject *target; | ||
| if (ACRRenderingStatus::ACROk == | ||
| buildTarget([rootView getSelectActionsTargetBuilderDirector], baseAction, | ||
| &target)) { | ||
| NSRange selectActionRange = NSMakeRange(0, textRunContent.length - 1); | ||
|
|
||
| [textRunContent addAttribute:@"SelectAction" | ||
| value:target | ||
| range:selectActionRange]; | ||
| [ACRLongPressGestureRecognizerFactory | ||
| addTapGestureRecognizerToUITextView:lab | ||
| target:(NSObject<ACRSelectActionDelegate> | ||
| *)target | ||
| rootView:rootView | ||
| hostConfig:acoConfig]; | ||
|
|
||
| [textRunContent addAttribute:NSUnderlineStyleAttributeName | ||
| value:[NSNumber numberWithInt:NSUnderlineStyleSingle] | ||
| range:selectActionRange]; | ||
| [textRunContent addAttribute:NSUnderlineColorAttributeName | ||
| value:foregroundColor | ||
| range:selectActionRange]; | ||
| } | ||
| } | ||
|
|
||
| // apply hightlight to textrun | ||
| if(textRun->GetHighlight()) { | ||
| if (textRun->GetHighlight()) { | ||
| UIColor *highlightColor = [acoConfig getHighlightColor:style | ||
| foregroundColor:textRun->GetTextColor() | ||
| subtleOption:textRun->GetIsSubtle()]; | ||
| [textRunContent addAttribute:NSBackgroundColorAttributeName value:highlightColor range:NSMakeRange(0,textRunContent.length)]; | ||
| [textRunContent addAttribute:NSBackgroundColorAttributeName | ||
| value:highlightColor | ||
| range:NSMakeRange(0, textRunContent.length)]; | ||
| } | ||
|
|
||
| if(textRun->GetStrikethrough()) { | ||
| [textRunContent addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, textRunContent.length)]; | ||
|
|
||
| if (textRun->GetStrikethrough()) { | ||
| [textRunContent addAttribute:NSStrikethroughStyleAttributeName | ||
| value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] | ||
| range:NSMakeRange(0, textRunContent.length)]; | ||
| } | ||
|
|
||
| if(textRun->GetUnderline()) | ||
| { | ||
| [textRunContent addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, textRunContent.length)]; | ||
|
|
||
| if (textRun->GetUnderline()) { | ||
| [textRunContent addAttribute:NSUnderlineStyleAttributeName | ||
| value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] | ||
| range:NSMakeRange(0, textRunContent.length)]; | ||
| } | ||
|
|
||
| // Add paragraph style, text color, text weight as attributes to a NSMutableAttributedString, content. | ||
| [textRunContent addAttributes:@{NSParagraphStyleAttributeName:paragraphStyle, NSForegroundColorAttributeName:foregroundColor,} range:NSMakeRange(0, textRunContent.length - 1)]; | ||
| // Add paragraph style, text color, text weight as attributes to a | ||
| // NSMutableAttributedString, content. | ||
| [textRunContent addAttributes:@{ | ||
| NSParagraphStyleAttributeName : paragraphStyle, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
nit: also here the ':' are not aligned #WontFix
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, it's the result of running clang format. In reply to: 322860767 [](ancestors = 322860767) |
||
| NSForegroundColorAttributeName : foregroundColor, | ||
| } | ||
| range:NSMakeRange(0, textRunContent.length - 1)]; | ||
|
|
||
| [content appendAttributedString:textRunContent]; | ||
| } | ||
|
|
@@ -134,37 +170,72 @@ - (UIView *)render:(UIView<ACRIContentHoldingView> *)viewGroup | |
| lab.attributedText = content; | ||
| lab.area = lab.frame.size.width * lab.frame.size.height; | ||
|
|
||
| ACRContentHoldingUIView *wrappingview = [[ACRContentHoldingUIView alloc] initWithFrame:lab.frame]; | ||
| ACRContentHoldingUIView *wrappingview = | ||
| [[ACRContentHoldingUIView alloc] initWithFrame:lab.frame]; | ||
| wrappingview.translatesAutoresizingMaskIntoConstraints = NO; | ||
| lab.translatesAutoresizingMaskIntoConstraints = NO; | ||
|
|
||
| [viewGroup addArrangedSubview:wrappingview]; | ||
| [wrappingview addSubview:lab]; | ||
|
|
||
| NSLayoutAttribute horizontalAlignment = NSLayoutAttributeLeading; | ||
| if(rTxtBlck->GetHorizontalAlignment() == HorizontalAlignment::Right) { | ||
| if (rTxtBlck->GetHorizontalAlignment() == HorizontalAlignment::Right) { | ||
| horizontalAlignment = NSLayoutAttributeTrailing; | ||
| } else if (rTxtBlck->GetHorizontalAlignment() == HorizontalAlignment::Center) { | ||
| horizontalAlignment = NSLayoutAttributeCenterX; | ||
| } | ||
|
|
||
| [NSLayoutConstraint constraintWithItem:lab attribute:horizontalAlignment relatedBy:NSLayoutRelationEqual toItem:wrappingview attribute:horizontalAlignment multiplier:1.0 constant:0].active = YES; | ||
| [NSLayoutConstraint constraintWithItem:lab attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:wrappingview attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES; | ||
| [NSLayoutConstraint constraintWithItem:lab attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:wrappingview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES; | ||
| [NSLayoutConstraint constraintWithItem:lab | ||
| attribute:horizontalAlignment | ||
| relatedBy:NSLayoutRelationEqual | ||
| toItem:wrappingview | ||
| attribute:horizontalAlignment | ||
| multiplier:1.0 | ||
| constant:0] | ||
| .active = YES; | ||
| [NSLayoutConstraint constraintWithItem:lab | ||
| attribute:NSLayoutAttributeBottom | ||
| relatedBy:NSLayoutRelationEqual | ||
| toItem:wrappingview | ||
| attribute:NSLayoutAttributeBottom | ||
| multiplier:1.0 | ||
| constant:0] | ||
| .active = YES; | ||
| [NSLayoutConstraint constraintWithItem:lab | ||
| attribute:NSLayoutAttributeTop | ||
| relatedBy:NSLayoutRelationEqual | ||
| toItem:wrappingview | ||
| attribute:NSLayoutAttributeTop | ||
| multiplier:1.0 | ||
| constant:0] | ||
| .active = YES; | ||
|
|
||
| lab.textContainer.maximumNumberOfLines = 0; | ||
|
|
||
| if(rTxtBlck->GetHeight() == HeightType::Auto){ | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; | ||
| [wrappingview setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisVertical]; | ||
| if (rTxtBlck->GetHeight() == HeightType::Auto) { | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired | ||
| forAxis:UILayoutConstraintAxisVertical]; | ||
| [wrappingview setContentHuggingPriority:UILayoutPriorityDefaultHigh | ||
| forAxis:UILayoutConstraintAxisVertical]; | ||
| } else { | ||
| [wrappingview setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical]; | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; | ||
| [wrappingview setContentHuggingPriority:UILayoutPriorityDefaultLow | ||
| forAxis:UILayoutConstraintAxisVertical]; | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired | ||
| forAxis:UILayoutConstraintAxisVertical]; | ||
| } | ||
|
|
||
| [NSLayoutConstraint constraintWithItem:wrappingview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:lab attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0].active = YES; | ||
| [lab setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; | ||
| [NSLayoutConstraint constraintWithItem:wrappingview | ||
| attribute:NSLayoutAttributeWidth | ||
| relatedBy:NSLayoutRelationGreaterThanOrEqual | ||
| toItem:lab | ||
| attribute:NSLayoutAttributeWidth | ||
| multiplier:1.0 | ||
| constant:0] | ||
| .active = YES; | ||
| [lab setContentCompressionResistancePriority:UILayoutPriorityRequired | ||
| forAxis:UILayoutConstraintAxisHorizontal]; | ||
| [wrappingview setContentCompressionResistancePriority:UILayoutPriorityRequired | ||
| forAxis:UILayoutConstraintAxisHorizontal]; | ||
|
|
||
| configVisibility(wrappingview, elem); | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra spaces here make the ':' not to be aligned #WontFix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nesalang, hopefully we can get the clang-formatting solution in for iOS as well? What was teh plan of action here for stylistic policies/applcations to iOS again? Are we looking at clang?
In reply to: 322855682 [](ancestors = 322855682)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shalini Joshi (@shalinijoshi19) clang format is essentially ready. i closed the previous clang format pr because review wasn't completed fast enough to avoid merge conflicts with changes that are merged. So i will reopen the branch with clang format changes today.
the plan for stylistic polices is we are following apple's ios objective-c coding guide line.
In reply to: 322900079 [](ancestors = 322900079,322855682)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
almedina-ms, this is result of running clang format which follows apple's coding style. so it would keep it as it.
In reply to: 322855682 [](ancestors = 322855682)