Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RNMobile] Add embed webview for Android #50440

Merged
merged 8 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,173 @@
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);
//CookieManager cookieManager = CookieManager.getInstance();
//cookieManager.setAcceptThirdPartyCookies(mWebView, 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() {
mWebView.loadUrl("https://wordpress.org/gutenberg/");
}

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 "";
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_gutenberg_embed_webview, menu);
fluiddot marked this conversation as resolved.
Show resolved Hide resolved
return true;
}

@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;}";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fullscreen preview on iOS has a black background by default so there is no need to check the user theme preference .

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 @@ -178,6 +179,10 @@ public interface OnImageFullscreenPreviewListener {
void onImageFullscreenPreviewClicked(String mediaUrl);
}

public interface OnEmbedFullscreenPreviewListener {
void onEmbedFullscreenPreviewClicked(String html, String title);
}

fluiddot marked this conversation as resolved.
Show resolved Hide resolved
public interface OnReattachMediaUploadQueryListener {
void onQueryCurrentProgressForUploadingMedia();
}
Expand Down Expand Up @@ -210,6 +215,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 +471,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 +661,7 @@ public void attachToContainer(ViewGroup viewGroup,
OnImageFullscreenPreviewListener onImageFullscreenPreviewListener,
OnMediaEditorListener onMediaEditorListener,
OnGutenbergDidRequestUnsupportedBlockFallbackListener onGutenbergDidRequestUnsupportedBlockFallbackListener,
OnGutenbergDidRequestEmbedFullscreenPreviewListener onGutenbergDidRequestEmbedFullscreenPreviewListener,
OnGutenbergDidSendButtonPressedActionListener onGutenbergDidSendButtonPressedActionListener,
ShowSuggestionsUtil showSuggestionsUtil,
OnMediaFilesCollectionBasedBlockEditorListener onMediaFilesCollectionBasedBlockEditorListener,
Expand All @@ -669,6 +684,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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
</menu>
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