Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a8f65ca

Browse files
committedDec 1, 2023
Android works better
1 parent 60602b9 commit a8f65ca

File tree

6 files changed

+247
-13
lines changed

6 files changed

+247
-13
lines changed
 

‎android/build.gradle

+27-5
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,16 @@ android {
5353
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
5454
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
5555
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
56-
56+
externalNativeBuild {
57+
cmake {
58+
arguments "-DANDROID_STL=c++_shared", "-DANDROID_TOOLCHAIN=clang"
59+
}
60+
}
5761
}
5862

5963
buildFeatures {
6064
buildConfig true
65+
prefab true
6166
}
6267

6368
buildTypes {
@@ -88,6 +93,25 @@ android {
8893
}
8994
}
9095
}
96+
97+
externalNativeBuild {
98+
cmake {
99+
path file('src/main/cpp/CMakeLists.txt')
100+
version '3.22.1'
101+
}
102+
}
103+
104+
packagingOptions {
105+
doNotStrip '**/**/*.so'
106+
excludes = [
107+
"META-INF",
108+
"META-INF/**",
109+
"**/libc++_shared.so",
110+
"**/libfbjni.so",
111+
"**/libjsi.so",
112+
"**/libreactnativejni.so",
113+
]
114+
}
91115
}
92116

93117
repositories {
@@ -97,10 +121,8 @@ repositories {
97121

98122

99123
dependencies {
100-
// For < 0.71, this will be from the local maven repo
101-
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
102-
//noinspection GradleDynamicVersion
103-
implementation "com.facebook.react:react-native:+"
124+
implementation "com.facebook.react:react-android" // version substituted by RNGP
125+
implementation "com.facebook.react:hermes-android" // version substituted by RNGP
104126
}
105127

106128
if (isNewArchitectureEnabled()) {

‎android/src/main/cpp/CMakeLists.txt

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
project("markdowntextinput")
2+
3+
cmake_minimum_required(VERSION 3.13)
4+
5+
set(CMAKE_VERBOSE_MAKEFILE on)
6+
7+
add_compile_options(-fvisibility=hidden -fexceptions -frtti)
8+
9+
file(GLOB markdowntextinput_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
10+
11+
add_library(${CMAKE_PROJECT_NAME} SHARED ${markdowntextinput_SRC})
12+
13+
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
14+
15+
find_package(fbjni REQUIRED CONFIG)
16+
find_package(ReactAndroid REQUIRED CONFIG)
17+
find_package(hermes-engine REQUIRED CONFIG)
18+
19+
target_link_libraries(${CMAKE_PROJECT_NAME}
20+
fbjni::fbjni
21+
ReactAndroid::jsi
22+
ReactAndroid::reactnativejni
23+
hermes-engine::libhermes)

‎android/src/main/cpp/MarkdownUtils.cpp

+82
Large diffs are not rendered by default.

‎android/src/main/cpp/MarkdownUtils.h

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#pragma once
9+
10+
#include <fbjni/fbjni.h>
11+
#include <jsi/jsi.h>
12+
13+
using namespace facebook;
14+
15+
namespace markdowntextinput {
16+
17+
class MarkdownUtils : public jni::HybridClass<MarkdownUtils>,
18+
public jsi::HostObject {
19+
public:
20+
static constexpr auto kJavaDescriptor =
21+
"Lcom/markdowntextinput/MarkdownUtils;";
22+
23+
static jni::local_ref<jni::JString> nativeParseMarkdown(
24+
jni::alias_ref<jhybridobject> jThis,
25+
jni::alias_ref<jni::JString> input);
26+
27+
static void registerNatives();
28+
29+
private:
30+
friend HybridBase;
31+
};
32+
33+
} // namespace markdowntextinput

‎android/src/main/cpp/OnLoad.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <fbjni/fbjni.h>
2+
3+
#include "MarkdownUtils.h"
4+
5+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
6+
return facebook::jni::initialize(
7+
vm, [] { markdowntextinput::MarkdownUtils::registerNatives(); });
8+
}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,86 @@
11
package com.markdowntextinput;
22

3+
import android.graphics.Color;
34
import android.graphics.Typeface;
45
import android.text.SpannableStringBuilder;
56
import android.text.Spanned;
7+
import android.text.style.AbsoluteSizeSpan;
8+
import android.text.style.BackgroundColorSpan;
9+
import android.text.style.ForegroundColorSpan;
10+
import android.text.style.LeadingMarginSpan;
11+
import android.text.style.StrikethroughSpan;
612
import android.text.style.StyleSpan;
13+
import android.text.style.TypefaceSpan;
14+
import android.text.style.UnderlineSpan;
15+
16+
import com.facebook.soloader.SoLoader;
17+
18+
import org.json.JSONArray;
19+
import org.json.JSONException;
720

821
public class MarkdownUtils {
9-
public static void applyMarkdownFormatting(SpannableStringBuilder ssb) {
10-
String text = ssb.toString();
11-
ssb.clear();
12-
ssb.append(text);
22+
static {
23+
SoLoader.loadLibrary("markdowntextinput");
24+
}
1325

14-
// TODO: parse Markdown here
26+
private static native String nativeParseMarkdown(String input);
1527

16-
// TODO: apply formatting here
17-
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
18-
ssb.setSpan(new StyleSpan(Typeface.BOLD), 0, Math.min(5, text.length()), flag);
28+
public static void applyMarkdownFormatting(SpannableStringBuilder ssb) {
29+
String input = ssb.toString();
30+
String output = nativeParseMarkdown(input);
31+
try {
32+
JSONArray array = new JSONArray(output);
33+
String text = array.getString(0);
34+
ssb.clear();
35+
ssb.append(text);
36+
JSONArray ranges = array.getJSONArray(1);
37+
for (int i = 0; i < ranges.length(); i++) {
38+
JSONArray range = ranges.getJSONArray(i);
39+
String type = range.getString(0);
40+
int start = range.getInt(1);
41+
int end = start + range.getInt(2);
42+
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
43+
switch (type) {
44+
case "bold":
45+
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
46+
break;
47+
case "italic":
48+
ssb.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flag);
49+
break;
50+
case "strikethrough":
51+
ssb.setSpan(new StrikethroughSpan(), start, end, flag);
52+
break;
53+
case "mention":
54+
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
55+
ssb.setSpan(new BackgroundColorSpan(Color.rgb(252, 232, 142)), start, end, flag);
56+
break;
57+
case "syntax":
58+
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
59+
ssb.setSpan(new ForegroundColorSpan(Color.GRAY), start, end, flag);
60+
break;
61+
case "link":
62+
ssb.setSpan(new UnderlineSpan(), start, end, flag);
63+
ssb.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, flag);
64+
break;
65+
case "code":
66+
case "pre":
67+
ssb.setSpan(new TypefaceSpan("monospace"), start, end, flag);
68+
ssb.setSpan(new ForegroundColorSpan(Color.rgb(6, 25, 109)), start, end, flag);
69+
ssb.setSpan(new BackgroundColorSpan(Color.LTGRAY), start, end, flag);
70+
break;
71+
case "h1":
72+
ssb.setSpan(new AbsoluteSizeSpan(25, true), start, end, flag);
73+
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
74+
break;
75+
case "blockquote":
76+
ssb.setSpan(new LeadingMarginSpan.Standard(20), start, end, flag);
77+
break;
78+
default:
79+
throw new IllegalStateException("Unsupported type: " + type);
80+
}
81+
}
82+
} catch (JSONException e) {
83+
// Do nothing
84+
}
1985
}
2086
}

0 commit comments

Comments
 (0)
Failed to load comments.