Skip to content

Commit

Permalink
[RNMobile] Add embed webview for Android (#50440)
Browse files Browse the repository at this point in the history
* Add Gutenberg Embed WebView

* Clean up

* Rename method

Fix renaming

--ammend

* Remove commented out code

* Removed unused method

* Remove unused menu layout

* Update load and get title methods

These are no longer overriden in the main Android app

---------

Co-authored-by: jhnstn <jhnstn@pm.me>
  • Loading branch information
jhnstn and jhnstn authored May 10, 2023
1 parent 5dc04cf commit c30e6d8
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<activity
android:name=".GutenbergWebViewActivity"
android:theme="@style/Base.GutenbergWebView" />
<activity
android:name=".GutenbergEmbedWebViewActivity"
android:theme="@style/Base.GutenbergWebView" />
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback
String blockName,
String blockTitle);

void requestEmbedFullscreenPreview(String content, String title);

void gutenbergDidSendButtonPressedAction(String buttonType);

void onShowUserSuggestions(Consumer<String> onResult);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package org.wordpress.mobile.ReactNativeGutenbergBridge;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import java.util.concurrent.atomic.AtomicBoolean;

public class GutenbergEmbedWebViewActivity extends AppCompatActivity {
public static final String ARG_CONTENT = "content";
public static final String ARG_TITLE = "title";
private static final String JAVA_SCRIPT_INTERFACE_NAME = "wpwebkit";

protected WebView mWebView;

private ProgressBar mProgressBar;
private AtomicBoolean mIsWebPageLoaded = new AtomicBoolean(false);
private final Handler mWebPageLoadedHandler = new Handler();
private final Runnable mWebPageLoadedRunnable = new Runnable() {
@Override public void run() {
if (!mIsWebPageLoaded.getAndSet(true)) {
mProgressBar.setVisibility(View.GONE);
}
}
};

@SuppressLint("SetJavaScriptEnabled")
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gutenberg_embed_web_view);

setupToolbar();

mWebView = findViewById(R.id.embed_web_view);

mProgressBar = findViewById(R.id.progress_bar);

// Set settings
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);

// Setup WebView client
setupWebViewClient();

// Setup Web Chrome client
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int progress) {
if (progress == 100) {
mWebPageLoadedHandler.removeCallbacks(mWebPageLoadedRunnable);
mWebPageLoadedHandler.postDelayed(mWebPageLoadedRunnable, 1500);
} else {
mIsWebPageLoaded.compareAndSet(true, false);
if (mProgressBar.getVisibility() == View.GONE) {
mProgressBar.setVisibility(View.VISIBLE);
}
mProgressBar.setProgress(progress);
}
}
});

load();
}

protected void load() {
String content = getIntent().getExtras().getString(ARG_CONTENT);
mWebView.loadData(content, "text/html", "UTF-8");
}

private void setupToolbar() {
setTitle("");

Toolbar toolbar = findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);

ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_close_24px);
actionBar.setSubtitle("");
actionBar.setTitle(getToolbarTitle());
}
}
}

protected String getToolbarTitle() {
return getIntent().getExtras().getString(ARG_TITLE);
}

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
if (mWebView == null) {
return false;
}

int itemID = item.getItemId();

if (itemID == android.R.id.home) {
finish();
}

return super.onOptionsItemSelected(item);
}

private void setupWebViewClient() {
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// Center the embed with a black background;
String css = "body{margin:0;background:#000;display:flex;align-items:center;}";
String js = String.format("(()=>{const c='%s';const s=document.createElement('style');s.textContent=c;document.head.append(s);})()", css);
view.evaluateJavascript(js, null);
super.onPageStarted(view, url, favicon);
}
});
}

@Override
public void onBackPressed() {
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
super.onBackPressed();
}
}

@Override
public void finish() {
runOnUiThread(() -> {
mWebView.removeJavascriptInterface(JAVA_SCRIPT_INTERFACE_NAME);
mWebView.clearHistory();
mWebView.clearFormData();
mWebView.clearCache(true);
mWebView.clearSslPreferences();
});

super.finish();
}

@Override
protected void onDestroy() {
mWebPageLoadedHandler.removeCallbacks(mWebPageLoadedRunnable);
super.onDestroy();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,11 @@ public void requestUnsupportedBlockFallback(String content, String blockId, Stri
replaceBlock(savedContent, savedBlockId), content, blockId, blockName, blockTitle);
}

@ReactMethod
public void requestEmbedFullscreenPreview(String content, String title) {
mGutenbergBridgeJS2Parent.requestEmbedFullscreenPreview(content,title);
}

@ReactMethod
public void actionButtonPressed(String buttonType) {
mGutenbergBridgeJS2Parent.gutenbergDidSendButtonPressedAction(buttonType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public class WPAndroidGlueCode {
private OnImageFullscreenPreviewListener mOnImageFullscreenPreviewListener;
private OnMediaEditorListener mOnMediaEditorListener;
private OnGutenbergDidRequestUnsupportedBlockFallbackListener mOnGutenbergDidRequestUnsupportedBlockFallbackListener;
private OnGutenbergDidRequestEmbedFullscreenPreviewListener mOnGutenbergDidRequestEmbedFullscreenPreviewListener;
private OnGutenbergDidSendButtonPressedActionListener mOnGutenbergDidSendButtonPressedActionListener;
private ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback;
private OnMediaFilesCollectionBasedBlockEditorListener mOnMediaFilesCollectionBasedBlockEditorListener;
Expand Down Expand Up @@ -210,6 +211,10 @@ public interface OnGutenbergDidRequestUnsupportedBlockFallbackListener {
void gutenbergDidRequestUnsupportedBlockFallback(UnsupportedBlock unsupportedBlock);
}

public interface OnGutenbergDidRequestEmbedFullscreenPreviewListener {
void gutenbergDidRequestEmbedFullscreenPreview(String html, String title);
}

public interface OnGutenbergDidSendButtonPressedActionListener {
void gutenbergDidSendButtonPressedAction(String buttonType);
}
Expand Down Expand Up @@ -462,6 +467,11 @@ public void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockC
gutenbergDidRequestUnsupportedBlockFallback(new UnsupportedBlock(blockId, blockName, blockTitle, content));
}

public void requestEmbedFullscreenPreview(String html, String title) {
mOnGutenbergDidRequestEmbedFullscreenPreviewListener.
gutenbergDidRequestEmbedFullscreenPreview(html, title);
}

@Override
public void gutenbergDidSendButtonPressedAction(String buttonType) {
mOnGutenbergDidSendButtonPressedActionListener.gutenbergDidSendButtonPressedAction(buttonType);
Expand Down Expand Up @@ -647,6 +657,7 @@ public void attachToContainer(ViewGroup viewGroup,
OnImageFullscreenPreviewListener onImageFullscreenPreviewListener,
OnMediaEditorListener onMediaEditorListener,
OnGutenbergDidRequestUnsupportedBlockFallbackListener onGutenbergDidRequestUnsupportedBlockFallbackListener,
OnGutenbergDidRequestEmbedFullscreenPreviewListener onGutenbergDidRequestEmbedFullscreenPreviewListener,
OnGutenbergDidSendButtonPressedActionListener onGutenbergDidSendButtonPressedActionListener,
ShowSuggestionsUtil showSuggestionsUtil,
OnMediaFilesCollectionBasedBlockEditorListener onMediaFilesCollectionBasedBlockEditorListener,
Expand All @@ -669,6 +680,7 @@ public void attachToContainer(ViewGroup viewGroup,
mOnImageFullscreenPreviewListener = onImageFullscreenPreviewListener;
mOnMediaEditorListener = onMediaEditorListener;
mOnGutenbergDidRequestUnsupportedBlockFallbackListener = onGutenbergDidRequestUnsupportedBlockFallbackListener;
mOnGutenbergDidRequestEmbedFullscreenPreviewListener = onGutenbergDidRequestEmbedFullscreenPreviewListener;
mOnGutenbergDidSendButtonPressedActionListener = onGutenbergDidSendButtonPressedActionListener;
mShowSuggestionsUtil = showSuggestionsUtil;
mOnMediaFilesCollectionBasedBlockEditorListener = onMediaFilesCollectionBasedBlockEditorListener;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/status_bar_color"
app:titleTextColor="@android:color/white"
app:contentInsetEnd="@dimen/toolbar_content_offset_end"
app:contentInsetLeft="@dimen/toolbar_content_offset"
app:contentInsetRight="@dimen/toolbar_content_offset_end"
app:contentInsetStart="@dimen/toolbar_content_offset" />

</com.google.android.material.appbar.AppBarLayout>

<WebView
android:id="@+id/embed_web_view"
android:layout_below="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"/>

<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="@dimen/progress_bar_height"
android:layout_alignTop="@+id/embed_web_view"
android:indeterminate="false"
android:progressDrawable="@drawable/progressbar_horizontal"/>

</RelativeLayout>
14 changes: 13 additions & 1 deletion packages/react-native-bridge/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export function requestMediaPicker( source, filter, multiple, callback ) {
}

/**
* Request to render an unsuported block.
* Request to render an unsupported block.
*
* A way to show unsupported blocks to the user is to render it on a web view.
*
Expand Down Expand Up @@ -290,6 +290,18 @@ export function requestImageFullscreenPreview(
);
}

export function requestEmbedFullscreenPreview( content, title ) {
if ( isIOS ) {
/* eslint-disable-next-line no-console */
console.warn( 'requestEmbedFullscreenPreview is not supported on iOS' );
return;
}
return RNReactNativeGutenbergBridge.requestEmbedFullscreenPreview(
content,
title
);
}

export function requestMediaEditor( mediaUrl, callback ) {
return RNReactNativeGutenbergBridge.requestMediaEditor(
mediaUrl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ public void requestImageFullscreenPreview(String mediaUrl) {

}

@Override
public void requestEmbedFullscreenPreview(String content, String title) {

}

@Override
public void requestMediaEditor(MediaSelectedCallback mediaSelectedCallback, String mediaUrl) {

Expand Down

0 comments on commit c30e6d8

Please sign in to comment.