Skip to content

Commit

Permalink
Android works better
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekzaw committed Dec 1, 2023
1 parent 60602b9 commit a8f65ca
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 13 deletions.
32 changes: 27 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,16 @@ android {
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()

externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared", "-DANDROID_TOOLCHAIN=clang"
}
}
}

buildFeatures {
buildConfig true
prefab true
}

buildTypes {
Expand Down Expand Up @@ -88,6 +93,25 @@ android {
}
}
}

externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.22.1'
}
}

packagingOptions {
doNotStrip '**/**/*.so'
excludes = [
"META-INF",
"META-INF/**",
"**/libc++_shared.so",
"**/libfbjni.so",
"**/libjsi.so",
"**/libreactnativejni.so",
]
}
}

repositories {
Expand All @@ -97,10 +121,8 @@ repositories {


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

if (isNewArchitectureEnabled()) {
Expand Down
23 changes: 23 additions & 0 deletions android/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
project("markdowntextinput")

cmake_minimum_required(VERSION 3.13)

set(CMAKE_VERBOSE_MAKEFILE on)

add_compile_options(-fvisibility=hidden -fexceptions -frtti)

file(GLOB markdowntextinput_SRC CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

add_library(${CMAKE_PROJECT_NAME} SHARED ${markdowntextinput_SRC})

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})

find_package(fbjni REQUIRED CONFIG)
find_package(ReactAndroid REQUIRED CONFIG)
find_package(hermes-engine REQUIRED CONFIG)

target_link_libraries(${CMAKE_PROJECT_NAME}
fbjni::fbjni
ReactAndroid::jsi
ReactAndroid::reactnativejni
hermes-engine::libhermes)
82 changes: 82 additions & 0 deletions android/src/main/cpp/MarkdownUtils.cpp

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions android/src/main/cpp/MarkdownUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <fbjni/fbjni.h>
#include <jsi/jsi.h>

using namespace facebook;

namespace markdowntextinput {

class MarkdownUtils : public jni::HybridClass<MarkdownUtils>,
public jsi::HostObject {
public:
static constexpr auto kJavaDescriptor =
"Lcom/markdowntextinput/MarkdownUtils;";

static jni::local_ref<jni::JString> nativeParseMarkdown(
jni::alias_ref<jhybridobject> jThis,
jni::alias_ref<jni::JString> input);

static void registerNatives();

private:
friend HybridBase;
};

} // namespace markdowntextinput
8 changes: 8 additions & 0 deletions android/src/main/cpp/OnLoad.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <fbjni/fbjni.h>

#include "MarkdownUtils.h"

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
return facebook::jni::initialize(
vm, [] { markdowntextinput::MarkdownUtils::registerNatives(); });
}
82 changes: 74 additions & 8 deletions android/src/main/java/com/markdowntextinput/MarkdownUtils.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,86 @@
package com.markdowntextinput;

import android.graphics.Color;
import android.graphics.Typeface;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;

import com.facebook.soloader.SoLoader;

import org.json.JSONArray;
import org.json.JSONException;

public class MarkdownUtils {
public static void applyMarkdownFormatting(SpannableStringBuilder ssb) {
String text = ssb.toString();
ssb.clear();
ssb.append(text);
static {
SoLoader.loadLibrary("markdowntextinput");
}

// TODO: parse Markdown here
private static native String nativeParseMarkdown(String input);

// TODO: apply formatting here
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
ssb.setSpan(new StyleSpan(Typeface.BOLD), 0, Math.min(5, text.length()), flag);
public static void applyMarkdownFormatting(SpannableStringBuilder ssb) {
String input = ssb.toString();
String output = nativeParseMarkdown(input);
try {
JSONArray array = new JSONArray(output);
String text = array.getString(0);
ssb.clear();
ssb.append(text);
JSONArray ranges = array.getJSONArray(1);
for (int i = 0; i < ranges.length(); i++) {
JSONArray range = ranges.getJSONArray(i);
String type = range.getString(0);
int start = range.getInt(1);
int end = start + range.getInt(2);
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
switch (type) {
case "bold":
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
break;
case "italic":
ssb.setSpan(new StyleSpan(Typeface.ITALIC), start, end, flag);
break;
case "strikethrough":
ssb.setSpan(new StrikethroughSpan(), start, end, flag);
break;
case "mention":
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
ssb.setSpan(new BackgroundColorSpan(Color.rgb(252, 232, 142)), start, end, flag);
break;
case "syntax":
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
ssb.setSpan(new ForegroundColorSpan(Color.GRAY), start, end, flag);
break;
case "link":
ssb.setSpan(new UnderlineSpan(), start, end, flag);
ssb.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, flag);
break;
case "code":
case "pre":
ssb.setSpan(new TypefaceSpan("monospace"), start, end, flag);
ssb.setSpan(new ForegroundColorSpan(Color.rgb(6, 25, 109)), start, end, flag);
ssb.setSpan(new BackgroundColorSpan(Color.LTGRAY), start, end, flag);
break;
case "h1":
ssb.setSpan(new AbsoluteSizeSpan(25, true), start, end, flag);
ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, flag);
break;
case "blockquote":
ssb.setSpan(new LeadingMarginSpan.Standard(20), start, end, flag);
break;
default:
throw new IllegalStateException("Unsupported type: " + type);
}
}
} catch (JSONException e) {
// Do nothing
}
}
}

0 comments on commit a8f65ca

Please sign in to comment.