Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into brtqkr/add-playwright…
Browse files Browse the repository at this point in the history
…-tests
  • Loading branch information
BrtqKr committed Apr 28, 2024
2 parents 690ddc1 + 31d7790 commit ac548f7
Show file tree
Hide file tree
Showing 30 changed files with 214 additions and 524 deletions.
12 changes: 10 additions & 2 deletions .github/workflows/build-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ jobs:
build:
if: github.repository == 'Expensify/react-native-live-markdown'
runs-on: ubuntu-latest
strategy:
matrix:
react-native-architecture: ['Paper', 'Fabric']
fail-fast: false
concurrency:
group: build-android-${{ github.ref }}
group: build-android-${{ matrix.react-native-architecture }}-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Check out Git repository
Expand All @@ -42,6 +46,10 @@ jobs:
- name: Install node_modules
run: yarn install --immutable

- name: Apply patches
working-directory: example
run: yarn patch-package

- name: Build app
working-directory: example/android
run: ./gradlew assembleDebug --build-cache -PreactNativeArchitectures=arm64-v8a
run: ./gradlew assembleDebug --build-cache -PreactNativeArchitectures=arm64-v8a -PnewArchEnabled=${{ matrix.react-native-architecture == 'Fabric' && 'true' || 'false' }}
20 changes: 13 additions & 7 deletions .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ jobs:
build:
if: github.repository == 'Expensify/react-native-live-markdown'
runs-on: macos-13
strategy:
matrix:
react-native-architecture: ['Paper', 'Fabric']
fail-fast: false
concurrency:
group: build-ios-${{ github.ref }}
group: build-ios-${{ matrix.react-native-architecture }}-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Check out Git repository
Expand All @@ -39,8 +43,8 @@ jobs:
path: |
node_modules
example/node_modules
key: build-ios-node-modules-${{ hashFiles('yarn.lock') }}
restore-keys: build-ios-node-modules-
key: build-ios-node-modules-${{ matrix.react-native-architecture }}-${{ hashFiles('yarn.lock') }}
restore-keys: build-ios-node-modules-${{ matrix.react-native-architecture }}-

- name: Install node_modules
run: yarn install --immutable
Expand All @@ -52,11 +56,13 @@ jobs:
example/ios/Pods
~/Library/Caches/CocoaPods
~/.cocoapods
key: build-ios-pods-${{ hashFiles('example/node_modules/react-native/package.json') }}
restore-keys: build-ios-pods-
key: build-ios-pods-${{ matrix.react-native-architecture }}-${{ hashFiles('example/node_modules/react-native/package.json') }}
restore-keys: build-ios-pods-${{ matrix.react-native-architecture }}-

- name: Install Pods
working-directory: example/ios
env:
RCT_NEW_ARCH_ENABLED: ${{ matrix.react-native-architecture == 'Fabric' && '1' || '0' }}
run: |
bundler install
bundler exec pod install
Expand All @@ -69,8 +75,8 @@ jobs:
uses: actions/cache@v4
with:
path: ~/Library/Developer/Xcode/DerivedData
key: build-ios-derived-data-${{ hashFiles('example/node_modules/react-native/package.json') }}
restore-keys: build-ios-derived-data-
key: build-ios-derived-data-${{ matrix.react-native-architecture }}-${{ hashFiles('example/node_modules/react-native/package.json') }}
restore-keys: build-ios-derived-data-${{ matrix.react-native-architecture }}-

- name: Build app
working-directory: example
Expand Down
1 change: 0 additions & 1 deletion RNLiveMarkdown.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,5 @@ Pod::Spec.new do |s|
s.subspec "common" do |ss|
ss.source_files = "cpp/**/*.{cpp,h}"
ss.header_dir = "RNLiveMarkdown"
ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/cpp\"" }
end
end
4 changes: 4 additions & 0 deletions WebExample/tests/styles.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ test.describe('markdown content styling', () => {
await testMarkdownContentStyle({styleName: 'mentionUser', style: CONSTANTS.MARKDOWN_STYLE_DEFINITIONS.mentionUser.style, page});
});

test('roomMention', async ({page}) => {
await testMarkdownContentStyle({styleName: 'roomMention', style: CONSTANTS.MARKDOWN_STYLE_DEFINITIONS.roomMention.style, page});
});

test('blockquote', async ({page, browserName}) => {
const blockquoteStyle = CONSTANTS.MARKDOWN_STYLE_DEFINITIONS.blockquote.style;
// Firefox border properties are serialized slightly differently
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public class MarkdownStyle {
@ColorInt
private final int mMentionUserBackgroundColor;

@ColorInt
private final int mMentionReportColor;

@ColorInt
private final int mMentionReportBackgroundColor;

public MarkdownStyle(@NonNull ReadableMap map, @NonNull Context context) {
mSyntaxColor = parseColor(map, "syntax", "color", context);
mLinkColor = parseColor(map, "link", "color", context);
Expand All @@ -85,6 +91,8 @@ public MarkdownStyle(@NonNull ReadableMap map, @NonNull Context context) {
mMentionHereBackgroundColor = parseColor(map, "mentionHere", "backgroundColor", context);
mMentionUserColor = parseColor(map, "mentionUser", "color", context);
mMentionUserBackgroundColor = parseColor(map, "mentionUser", "backgroundColor", context);
mMentionReportColor = parseColor(map, "mentionReport", "color", context);
mMentionReportBackgroundColor = parseColor(map, "mentionReport", "backgroundColor", context);
}

private static int parseColor(@NonNull ReadableMap map, @NonNull String key, @NonNull String prop, @NonNull Context context) {
Expand Down Expand Up @@ -204,4 +212,14 @@ public int getMentionUserColor() {
public int getMentionUserBackgroundColor() {
return mMentionUserBackgroundColor;
}

@ColorInt
public int getMentionReportColor() {
return mMentionReportColor;
}

@ColorInt
public int getMentionReportBackgroundColor() {
return mMentionReportBackgroundColor;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ protected void setMarkdownStyle(MarkdownStyle markdownStyle) {
mMarkdownUtils.setMarkdownStyle(mMarkdownStyle);
}
if (mReactEditText != null) {
int selectionStart = mReactEditText.getSelectionStart();
int selectionEnd = mReactEditText.getSelectionEnd();
mReactEditText.setText(mReactEditText.getText()); // trigger update
mReactEditText.setSelection(selectionStart, selectionEnd);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ private void applyRange(SpannableStringBuilder ssb, String type, int start, int
setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getMentionUserColor()), start, end);
setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getMentionUserBackgroundColor()), start, end);
break;
case "mention-report":
setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getMentionReportColor()), start, end);
setSpan(ssb, new MarkdownBackgroundColorSpan(mMarkdownStyle.getMentionReportBackgroundColor()), start, end);
break;
case "syntax":
setSpan(ssb, new MarkdownForegroundColorSpan(mMarkdownStyle.getSyntaxColor()), start, end);
break;
Expand Down
9 changes: 9 additions & 0 deletions android/src/main/new_arch/MarkdownCommitHook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ RootShadowNode::Unshared MarkdownCommitHook::shadowTreeWillCommit(
// force measurement of a map buffer
newStateData->cachedAttributedStringId = 0;

// setting -1 as the event counter makes sure that the update will be ignored by the java
// part of the code, which is what we want as we don't change the attributed string here
if (previousEventCount_.contains(nodes.textInput->getTag()) &&
previousEventCount_[nodes.textInput->getTag()] == stateData.mostRecentEventCount) {
newStateData->mostRecentEventCount = -1;
} else {
previousEventCount_[nodes.textInput->getTag()] = stateData.mostRecentEventCount;
}

// clone the text input with the new state
auto newNode = node.clone({
.state =
Expand Down
2 changes: 2 additions & 0 deletions android/src/main/new_arch/MarkdownCommitHook.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class MarkdownCommitHook : public UIManagerCommitHook {
textLayoutManagers_;
std::unordered_map<facebook::react::Tag, folly::dynamic>
previousDecoratorProps_;
std::unordered_map<facebook::react::Tag, int64_t>
previousEventCount_;
};

} // namespace livemarkdown
4 changes: 4 additions & 0 deletions constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const MARKDOWN_STYLE_DEFINITIONS = {
wrapContent: (content: string) => `> ${content}`,
style: 'border-color: gray; border-width: 6px; margin-left: 6px; padding-left: 6px; border-left-style: solid; display: inline-block; max-width: 100%; box-sizing: border-box;',
},
roomMention: {
wrapContent: (content: string) => `#${content}`,
style: 'color: red; background-color: pink;',
},
} as const satisfies Record<string, MarkdownStyleDefiniton>;

const EXAMPLE_CONTENT = Object.entries(MARKDOWN_STYLE_DEFINITIONS)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#if defined(RCT_NEW_ARCH_ENABLED) || defined(ANDROID)

#include <react/renderer/core/ShadowNodeFamily.h>

Expand Down Expand Up @@ -32,3 +33,5 @@ class JSI_EXPORT MarkdownTextInputDecoratorState final {

} // namespace react
} // namespace facebook

#endif
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#if defined(RCT_NEW_ARCH_ENABLED) || defined(ANDROID)

#include "MarkdownTextInputDecoratorShadowNode.h"
#include <react/debug/react_native_assert.h>
Expand All @@ -15,3 +16,5 @@ class MarkdownTextInputDecoratorViewComponentDescriptor final

} // namespace react
} // namespace facebook

#endif
File renamed without changes.
2 changes: 2 additions & 0 deletions ios/RCTMarkdownStyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) UIColor *mentionHereBackgroundColor;
@property (nonatomic) UIColor *mentionUserColor;
@property (nonatomic) UIColor *mentionUserBackgroundColor;
@property (nonatomic) UIColor *mentionReportColor;
@property (nonatomic) UIColor *mentionReportBackgroundColor;

#ifdef RCT_NEW_ARCH_ENABLED
- (instancetype)initWithStruct:(const facebook::react::MarkdownTextInputDecoratorViewMarkdownStyleStruct &)style;
Expand Down
6 changes: 6 additions & 0 deletions ios/RCTMarkdownStyle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ - (instancetype)initWithStruct:(const facebook::react::MarkdownTextInputDecorato

_mentionUserColor = RCTUIColorFromSharedColor(style.mentionUser.color);
_mentionUserBackgroundColor = RCTUIColorFromSharedColor(style.mentionUser.backgroundColor);

_mentionReportColor = RCTUIColorFromSharedColor(style.mentionReport.color);
_mentionReportBackgroundColor = RCTUIColorFromSharedColor(style.mentionReport.backgroundColor);
}

return self;
Expand Down Expand Up @@ -79,6 +82,9 @@ - (instancetype)initWithDictionary:(NSDictionary *)json

_mentionUserColor = [RCTConvert UIColor:json[@"mentionUser"][@"color"]];
_mentionUserBackgroundColor = [RCTConvert UIColor:json[@"mentionUser"][@"backgroundColor"]];

_mentionReportColor = [RCTConvert UIColor:json[@"mentionReport"][@"color"]];
_mentionReportBackgroundColor = [RCTConvert UIColor:json[@"mentionReport"][@"backgroundColor"]];
}

return self;
Expand Down
3 changes: 3 additions & 0 deletions ios/RCTMarkdownUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input withA
// TODO: change mention color when it mentions current user
[attributedString addAttribute:NSForegroundColorAttributeName value:_markdownStyle.mentionUserColor range:range];
[attributedString addAttribute:NSBackgroundColorAttributeName value:_markdownStyle.mentionUserBackgroundColor range:range];
} else if ([type isEqualToString:@"mention-report"]) {
[attributedString addAttribute:NSForegroundColorAttributeName value:_markdownStyle.mentionReportColor range:range];
[attributedString addAttribute:NSBackgroundColorAttributeName value:_markdownStyle.mentionReportBackgroundColor range:range];
} else if ([type isEqualToString:@"link"]) {
[attributedString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:range];
[attributedString addAttribute:NSForegroundColorAttributeName value:_markdownStyle.linkColor range:range];
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@expensify/react-native-live-markdown",
"version": "0.1.59",
"version": "0.1.69",
"description": "Drop-in replacement for React Native's TextInput component with Markdown formatting.",
"main": "lib/commonjs/index",
"module": "lib/module/index",
Expand Down
22 changes: 22 additions & 0 deletions parser/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,3 +516,25 @@ describe('inline image', () => {
]);
});
});

describe('report mentions', () => {
test('simple report mention', () => {
expect('#report-name').toBeParsedAs([{type: 'mention-report', start: 0, length: 12}]);
});

test('report mention in tense', () => {
expect('reported #report-name should be highlighted').toBeParsedAs([{type: 'mention-report', start: 9, length: 12}]);
});

test('report mention with markdown', () => {
expect('reported #`report-name` should be highlighted').toBeParsedAs([
{type: 'syntax', start: 10, length: 1},
{type: 'code', start: 11, length: 11},
{type: 'syntax', start: 22, length: 1},
]);
});

test('report mention with punctuation', () => {
expect('reported #report-name!').toBeParsedAs([{type: 'mention-report', start: 9, length: 12}]);
});
});
4 changes: 3 additions & 1 deletion parser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import {ExpensiMark} from 'expensify-common/lib/ExpensiMark';
import _ from 'underscore';

type MarkdownType = 'bold' | 'italic' | 'strikethrough' | 'emoji' | 'mention-here' | 'mention-user' | 'link' | 'code' | 'pre' | 'blockquote' | 'h1' | 'syntax';
type MarkdownType = 'bold' | 'italic' | 'strikethrough' | 'emoji' | 'mention-here' | 'mention-user' | 'mention-report' | 'link' | 'code' | 'pre' | 'blockquote' | 'h1' | 'syntax';
type Range = {
type: MarkdownType;
start: number;
Expand Down Expand Up @@ -140,6 +140,8 @@ function parseTreeToTextAndRanges(tree: StackItem): [string, Range[]] {
addChildrenWithStyle(node, 'mention-here');
} else if (node.tag === '<mention-user>') {
addChildrenWithStyle(node, 'mention-user');
} else if (node.tag === '<mention-report>') {
addChildrenWithStyle(node, 'mention-report');
} else if (node.tag === '<blockquote>') {
appendSyntax('>');
addChildrenWithStyle(node, 'blockquote');
Expand Down
2 changes: 1 addition & 1 deletion parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"typescript": "^5.3.3"
},
"dependencies": {
"expensify-common": "Expensify/expensify-common#4e020cfa13ffabde14313c92b341285aeb919f29",
"expensify-common": "Expensify/expensify-common#9a68635cdcef4c81593c0f816a007bc9c707d46a",
"patch-package": "^8.0.0",
"underscore": "^1.13.6"
}
Expand Down
Loading

0 comments on commit ac548f7

Please sign in to comment.