@@ -714,6 +714,9 @@ function () {
714714 } ] ;
715715 this . patterns . forEach ( function ( pattern ) {
716716 var newParts = [ ] ;
717+ var tmp = pattern . nonExhaustiveModeMaxMatchCount || 0 ;
718+ var numberOfMatchesPermitted = Math . min ( Math . max ( Number . isInteger ( tmp ) ? tmp : 0 , 0 ) || Number . POSITIVE_INFINITY , Number . POSITIVE_INFINITY ) ;
719+ var currentMatches = 0 ;
717720 parsedTexts . forEach ( function ( parsedText ) {
718721 // Only allow for now one parsing
719722 if ( parsedText . _matched ) {
@@ -723,20 +726,31 @@ function () {
723726
724727 var parts = [ ] ;
725728 var textLeft = parsedText . children ;
729+ var indexOfMatchedString = 0 ;
730+ /** @type {RegExpExecArray } */
726731
727- while ( textLeft ) {
728- var matches = pattern . pattern . exec ( textLeft ) ;
732+ var matches ; // Global RegExps are stateful, this makes it start at 0 if reused
733+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/ exec
729734
730- if ( ! matches ) {
735+ pattern . pattern . lastIndex = 0 ;
736+
737+ while ( textLeft && ( matches = pattern . pattern . exec ( textLeft ) ) ) {
738+ var previousText = textLeft . substr ( 0 , matches . index ) ;
739+ indexOfMatchedString = matches . index ;
740+
741+ if ( ++ currentMatches > numberOfMatchesPermitted ) {
742+ // Abort if we've exhausted our number of matches
731743 break ;
732744 }
733745
734- var previousText = textLeft . substr ( 0 , matches . index ) ;
735746 parts . push ( {
736747 children : previousText
737748 } ) ;
738- parts . push ( _this . getMatchedPart ( pattern , matches [ 0 ] , matches ) ) ;
749+ parts . push ( _this . getMatchedPart ( pattern , matches [ 0 ] , matches , indexOfMatchedString ) ) ;
739750 textLeft = textLeft . substr ( matches . index + matches [ 0 ] . length ) ;
751+ indexOfMatchedString += matches [ 0 ] . length - 1 ; // Global RegExps are stateful, this makes it operate on the "remainder" of the string
752+
753+ pattern . pattern . lastIndex = 0 ;
740754 }
741755
742756 parts . push ( {
@@ -797,6 +811,7 @@ function () {
797811} ( ) ;
798812
799813var PATTERNS = {
814+ mention : / ( ( .) \[ ( [ ^ [ ] * ) ] \( ( [ ^ ( ^ ) ] * ) \) ) / gi,
800815 url : / ( h t t p s ? : \/ \/ | w w w \. ) [ - a - z A - Z 0 - 9 @ : % . _ \+ ~ # = ] { 2 , 256 } \. [ a - z ] { 2 , 6 } \b ( [ - a - z A - Z 0 - 9 @ : % _ \+ . ~ # ? & \/ \/ = ] * ) / i,
801816 phone : / [ \+ ] ? [ ( ] ? [ 0 - 9 ] { 3 } [ ) ] ? [ - \s \. ] ? [ 0 - 9 ] { 3 } [ - \s \. ] ? [ 0 - 9 ] { 4 , 6 } / ,
802817 email : / \S + @ \S + \. \S + /
@@ -896,6 +911,28 @@ function (_React$Component) {
896911 _classCallCheck ( this , MessageText ) ;
897912
898913 _this = _possibleConstructorReturn ( this , _getPrototypeOf ( MessageText ) . call ( this , props ) ) ;
914+
915+ _this . renderText = function ( matchingString , matches ) {
916+ var _this$props = _this . props ,
917+ members = _this$props . members ,
918+ profile = _this$props . profile ;
919+ var name = matches [ 4 ] ;
920+
921+ if ( profile && profile . username == name ) {
922+ name = profile . name ;
923+ } else {
924+ var user = members . find ( function ( user ) {
925+ return user . id == matches [ 4 ] ;
926+ } ) ;
927+
928+ if ( user ) {
929+ name = user . display ;
930+ }
931+ }
932+
933+ return "" . concat ( matches [ 2 ] ) . concat ( name ) ;
934+ } ;
935+
899936 _this . onUrlPress = _this . onUrlPress . bind ( _assertThisInitialized ( _assertThisInitialized ( _this ) ) ) ;
900937 _this . onPhonePress = _this . onPhonePress . bind ( _assertThisInitialized ( _assertThisInitialized ( _this ) ) ) ;
901938 _this . onEmailPress = _this . onEmailPress . bind ( _assertThisInitialized ( _assertThisInitialized ( _this ) ) ) ;
@@ -928,20 +965,19 @@ function (_React$Component) {
928965 } , {
929966 key : "onPhonePress" ,
930967 value : function onPhonePress ( phone ) {
931- var options = [ 'Call' , 'Text' , 'Cancel' ] ;
932- var cancelButtonIndex = options . length - 1 ;
933- this . context . actionSheet ( ) . showActionSheetWithOptions ( {
934- options : options ,
935- cancelButtonIndex : cancelButtonIndex
936- } , function ( buttonIndex ) { // switch (buttonIndex) {
937- // case 0:
938- // Communications.phonecall(phone, true);
939- // break;
940- // case 1:
941- // Communications.text(phone);
942- // break;
943- // }
944- } ) ;
968+ // options,
969+ // cancelButtonIndex,
970+ // },
971+ // (buttonIndex) => {
972+ // // switch (buttonIndex) {
973+ // // case 0:
974+ // // Communications.phonecall(phone, true);
975+ // // break;
976+ // // case 1:
977+ // // Communications.text(phone);
978+ // // break;
979+ // // }
980+ // });
945981 }
946982 } , {
947983 key : "onEmailPress" ,
@@ -956,13 +992,18 @@ function (_React$Component) {
956992 } , React__default . createElement ( ParsedText , {
957993 style : [ styles$4 [ this . props . position ] . text , this . props . textStyle [ this . props . position ] , this . props . customTextStyle ] ,
958994 parse : _toConsumableArray ( this . props . parsePatterns ( linkStyle ) ) . concat ( [ {
995+ type : 'mention' ,
996+ style : linkStyle ,
997+ onPress : null ,
998+ renderText : this . renderText
999+ } , {
9591000 type : 'url' ,
9601001 style : linkStyle ,
9611002 onPress : this . onUrlPress
9621003 } , {
9631004 type : 'phone' ,
9641005 style : linkStyle ,
965- onPress : null
1006+ onPress : this . onPhonePress
9661007 } , {
9671008 type : 'email' ,
9681009 style : linkStyle ,
@@ -1461,7 +1502,7 @@ function (_React$Component) {
14611502 withoutFeedback : true ,
14621503 onLongPress : this . onLongPress ,
14631504 accessibilityTraits : "text"
1464- } , this . props . touchableProps ) , React__default . createElement ( ReactNative . View , null , this . renderMessageImage ( ) , this . renderMessageVideo ( ) , this . renderMessageText ( ) , this . renderCustomView ( ) , React__default . createElement ( ReactNative . View , {
1505+ } , this . props . touchableProps ) , React__default . createElement ( ReactNative . View , null , this . renderMessageImage ( ) , this . renderMessageVideo ( ) , this . renderMessageText ( ) , this . renderCustomView ( ) , React__default . createElement ( ReactNative . View , {
14651506 style : [ styles$8 [ this . props . position ] . bottom , this . props . bottomContainerStyle [ this . props . position ] ]
14661507 } , this . renderUsername ( ) , this . renderTime ( ) , this . renderTicks ( ) ) ) ) ) ) ;
14671508 }
0 commit comments