diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java
deleted file mode 100644
index 3ea19fa97b3831..00000000000000
--- a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.gutenberg;
-
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import androidx.appcompat.widget.Toolbar;
-import androidx.core.content.ContextCompat;
-
-import com.facebook.react.ReactActivity;
-import com.facebook.react.ReactInstanceManager;
-import com.facebook.react.ReactRootView;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.wordpress.mobile.WPAndroidGlue.GutenbergProps;
-
-import java.util.Locale;
-
-public class MainActivity extends ReactActivity {
-    private static MainActivity currentInstance;
-
-    private ReactRootView mReactRootView;
-    private Menu mMenu;
-
-    private static final String EXTRAS_INITIAL_PROPS = "initialProps";
-
-    private void openReactNativeDebugMenu() {
-        ReactInstanceManager devSettingsModule = getReactInstanceManager();
-        if (devSettingsModule != null) {
-            devSettingsModule.showDevOptionsDialog();
-        }
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        mMenu = menu;
-        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
-
-        // Set opacity for menu items
-        MenuItem undoItem = menu.findItem(R.id.menuUndo);
-        undoItem.getIcon().setAlpha(76);
-        undoItem.setEnabled(false);
-
-        MenuItem redoItem = menu.findItem(R.id.menuRedo);
-        redoItem.getIcon().setAlpha(76);
-        redoItem.setEnabled(false);
-        return true;
-    }
-
-    public void updateUndoItem(boolean isDisabled) {
-        if (mMenu != null) {
-            runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    MenuItem undoItem = mMenu.findItem(R.id.menuUndo);
-
-                    undoItem.setEnabled(!isDisabled);
-                    undoItem.getIcon().setAlpha(!isDisabled ? 255 : 76);
-                }
-            });
-        }
-    }
-
-    public void updateRedoItem(boolean isDisabled) {
-        if (mMenu != null) {
-            runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    MenuItem redoItem = mMenu.findItem(R.id.menuRedo);
-
-                    redoItem.setEnabled(!isDisabled);
-                    redoItem.getIcon().setAlpha(!isDisabled ? 255 : 76);
-                }
-            });
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        MainApplication mainApplication = (MainApplication) getApplication();
-
-        int itemId = item.getItemId();
-        if (itemId == R.id.menuUndo) {
-            mainApplication.toggleUndo();
-            return true;
-        }
-        if (itemId == R.id.menuRedo) {
-            mainApplication.toggleRedo();
-            return true;
-        }
-        if (itemId == R.id.menuButton) {
-            openReactNativeDebugMenu();
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    public static MainActivity getInstance() {
-        return currentInstance;
-    }
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        currentInstance = this;
-
-        // Create a LinearLayout that will hold both the toolbar and React Native content
-        LinearLayout linearLayout = new LinearLayout(this);
-        linearLayout.setOrientation(LinearLayout.VERTICAL);
-        linearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-        linearLayout.setFocusable(false);
-        linearLayout.setFocusableInTouchMode(true);
-
-        // Create a Toolbar instance
-        Toolbar toolbar = new Toolbar(this);
-
-        // Set toolbar properties (you can customize this as you want)
-        toolbar.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
-
-        // Set the toolbar as the Activity's action bar
-        setSupportActionBar(toolbar);
-
-        // Add the toolbar to the linear layout
-        linearLayout.addView(toolbar);
-
-        // Create a View to be used as the border
-        View borderView = new View(this);
-        borderView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
-        borderView.setBackgroundColor(ContextCompat.getColor(this, R.color.toolbarBorder));
-
-        // Add the border view to the linear layout
-        linearLayout.addView(borderView);
-
-        // Create a ReactRootView and assign it to mReactRootView
-        mReactRootView = new ReactRootView(this);
-        LinearLayout.LayoutParams reactViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1);
-        mReactRootView.setLayoutParams(reactViewParams);
-
-        // Add ReactView to the linear layout
-        linearLayout.addView(mReactRootView);
-
-        // Set the linear layout as the content view
-        setContentView(linearLayout);
-
-        // Load the React application
-        mReactRootView.startReactApplication(
-                ((MainApplication) getApplication()).getReactNativeHost().getReactInstanceManager(),
-                getMainComponentName(),
-                getAppOptions()
-        );
-    }
-
-    /**
-     * Returns the name of the main component registered from JavaScript.
-     * This is used to schedule rendering of the component.
-     */
-    @Override
-    protected String getMainComponentName() {
-        return "gutenberg";
-    }
-
-    private Bundle getAppOptions() {
-        Bundle bundle = new Bundle();
-
-        // Parse initial props from launch arguments
-        String initialTitle = null;
-        String initialData = null;
-        String rawStyles = null;
-        String rawFeatures = null;
-        Bundle extrasBundle = getIntent().getExtras();
-
-        if(extrasBundle != null) {
-            String initialProps = extrasBundle.getString(EXTRAS_INITIAL_PROPS, "{}");
-            try {
-                JSONObject jsonObject = new JSONObject(initialProps);
-                if (jsonObject.has(GutenbergProps.PROP_INITIAL_TITLE)) {
-                    initialTitle = jsonObject.getString(GutenbergProps.PROP_INITIAL_TITLE);
-                }
-                if (jsonObject.has(GutenbergProps.PROP_INITIAL_DATA)) {
-                    initialData = jsonObject.getString(GutenbergProps.PROP_INITIAL_DATA);
-                }
-                if (jsonObject.has(GutenbergProps.PROP_STYLES)) {
-                    rawStyles = jsonObject.getString(GutenbergProps.PROP_STYLES);
-                }
-                if (jsonObject.has(GutenbergProps.PROP_FEATURES)) {
-                    rawFeatures = jsonObject.getString(GutenbergProps.PROP_FEATURES);
-                }
-            } catch (final JSONException e) {
-                Log.e("MainActivity", "Json parsing error: " + e.getMessage());
-            }
-        }
-
-        // Add locale
-        String languageString = Locale.getDefault().toString();
-        String localeSlug = languageString.replace("_", "-").toLowerCase(Locale.ENGLISH);
-        bundle.putString(GutenbergProps.PROP_LOCALE, localeSlug);
-
-        // Add capabilities
-        Bundle capabilities = new Bundle();
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_MENTIONS, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_XPOSTS, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_REUSABLE_BLOCK, false);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_TILED_GALLERY_BLOCK, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_VIDEOPRESS_BLOCK, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_FACEBOOK_EMBED_BLOCK, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_INSTAGRAM_EMBED_BLOCK, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_LOOM_EMBED_BLOCK, true);
-        capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_SMARTFRAME_EMBED_BLOCK, true);
-        bundle.putBundle(GutenbergProps.PROP_CAPABILITIES, capabilities);
-
-        if(initialTitle != null) {
-            bundle.putString(GutenbergProps.PROP_INITIAL_TITLE, initialTitle);
-        }
-        if(initialData != null) {
-            bundle.putString(GutenbergProps.PROP_INITIAL_DATA, initialData);
-        }
-        if(rawStyles != null) {
-            bundle.putString(GutenbergProps.PROP_STYLES, rawStyles);
-        }
-        if(rawFeatures != null) {
-            bundle.putString(GutenbergProps.PROP_FEATURES, rawFeatures);
-        }
-
-        return bundle;
-    }
-}
diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.kt b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.kt
new file mode 100644
index 00000000000000..29b047bf01f7d7
--- /dev/null
+++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.kt
@@ -0,0 +1,207 @@
+package com.gutenberg
+
+import android.os.Bundle
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import androidx.appcompat.widget.Toolbar
+import androidx.core.content.ContextCompat
+import com.facebook.react.ReactActivity
+import com.facebook.react.ReactRootView
+import org.json.JSONException
+import org.json.JSONObject
+import org.wordpress.mobile.WPAndroidGlue.GutenbergProps
+import java.util.Locale
+
+class MainActivity : ReactActivity() {
+    private var mReactRootView: ReactRootView? = null
+    private var mMenu: Menu? = null
+    private fun openReactNativeDebugMenu() {
+        val devSettingsModule = reactInstanceManager
+        devSettingsModule?.showDevOptionsDialog()
+    }
+
+    override fun onCreateOptionsMenu(menu: Menu): Boolean {
+        mMenu = menu
+        menuInflater.inflate(R.menu.toolbar_menu, menu)
+
+        // Set opacity for menu items
+        val undoItem = menu.findItem(R.id.menuUndo)
+        undoItem.icon!!.alpha = 76
+        undoItem.setEnabled(false)
+        val redoItem = menu.findItem(R.id.menuRedo)
+        redoItem.icon!!.alpha = 76
+        redoItem.setEnabled(false)
+        return true
+    }
+
+    fun updateUndoItem(isDisabled: Boolean) {
+        if (mMenu != null) {
+            runOnUiThread {
+                val undoItem = mMenu!!.findItem(R.id.menuUndo)
+                undoItem.setEnabled(!isDisabled)
+                undoItem.icon!!.alpha = if (!isDisabled) 255 else 76
+            }
+        }
+    }
+
+    fun updateRedoItem(isDisabled: Boolean) {
+        if (mMenu != null) {
+            runOnUiThread {
+                val redoItem = mMenu!!.findItem(R.id.menuRedo)
+                redoItem.setEnabled(!isDisabled)
+                redoItem.icon!!.alpha = if (!isDisabled) 255 else 76
+            }
+        }
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean {
+        val mainApplication = application as MainApplication
+        val itemId = item.itemId
+        if (itemId == R.id.menuUndo) {
+            mainApplication.toggleUndo()
+            return true
+        }
+        if (itemId == R.id.menuRedo) {
+            mainApplication.toggleRedo()
+            return true
+        }
+        if (itemId == R.id.menuButton) {
+            openReactNativeDebugMenu()
+            return true
+        }
+        return super.onOptionsItemSelected(item)
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        instance = this
+
+        // Create a LinearLayout that will hold both the toolbar and React Native content
+        val linearLayout = LinearLayout(this)
+        linearLayout.orientation = LinearLayout.VERTICAL
+        linearLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+        linearLayout.isFocusable = false
+        linearLayout.isFocusableInTouchMode = true
+
+        // Create a Toolbar instance
+        val toolbar = Toolbar(this)
+
+        // Set toolbar properties (you can customize this as you want)
+        toolbar.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
+
+        // Set the toolbar as the Activity's action bar
+        setSupportActionBar(toolbar)
+
+        // Add the toolbar to the linear layout
+        linearLayout.addView(toolbar)
+
+        // Create a View to be used as the border
+        val borderView = View(this)
+        borderView.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1)
+        borderView.setBackgroundColor(ContextCompat.getColor(this, R.color.toolbarBorder))
+
+        // Add the border view to the linear layout
+        linearLayout.addView(borderView)
+
+        // Create a ReactRootView and assign it to mReactRootView
+        mReactRootView = ReactRootView(this)
+        val reactViewParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f)
+        mReactRootView!!.layoutParams = reactViewParams
+
+        // Add ReactView to the linear layout
+        linearLayout.addView(mReactRootView)
+
+        // Set the linear layout as the content view
+        setContentView(linearLayout)
+
+        // Load the React application
+        mReactRootView!!.startReactApplication(
+                (application as MainApplication).reactNativeHost.reactInstanceManager,
+                mainComponentName,
+                appOptions
+        )
+    }
+
+    /**
+     * Returns the name of the main component registered from JavaScript.
+     * This is used to schedule rendering of the component.
+     */
+    override fun getMainComponentName(): String {
+        return "gutenberg"
+    }
+
+    private val appOptions: Bundle
+        get() {
+            val bundle = Bundle()
+
+            // Parse initial props from launch arguments
+            var initialTitle: String? = null
+            var initialData: String? = null
+            var rawStyles: String? = null
+            var rawFeatures: String? = null
+            val extrasBundle = intent.extras
+            if (extrasBundle != null) {
+                val initialProps = extrasBundle.getString(EXTRAS_INITIAL_PROPS, "{}")
+                try {
+                    val jsonObject = JSONObject(initialProps)
+                    if (jsonObject.has(GutenbergProps.PROP_INITIAL_TITLE)) {
+                        initialTitle = jsonObject.getString(GutenbergProps.PROP_INITIAL_TITLE)
+                    }
+                    if (jsonObject.has(GutenbergProps.PROP_INITIAL_DATA)) {
+                        initialData = jsonObject.getString(GutenbergProps.PROP_INITIAL_DATA)
+                    }
+                    if (jsonObject.has(GutenbergProps.PROP_STYLES)) {
+                        rawStyles = jsonObject.getString(GutenbergProps.PROP_STYLES)
+                    }
+                    if (jsonObject.has(GutenbergProps.PROP_FEATURES)) {
+                        rawFeatures = jsonObject.getString(GutenbergProps.PROP_FEATURES)
+                    }
+                } catch (e: JSONException) {
+                    Log.e("MainActivity", "Json parsing error: " + e.message)
+                }
+            }
+
+            // Add locale
+            val languageString = Locale.getDefault().toString()
+            val localeSlug = languageString.replace("_", "-").lowercase()
+            bundle.putString(GutenbergProps.PROP_LOCALE, localeSlug)
+
+            // Add capabilities
+            val capabilities = Bundle()
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_MENTIONS, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_XPOSTS, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_UNSUPPORTED_BLOCK_EDITOR, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_REUSABLE_BLOCK, false)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_IS_AUDIO_BLOCK_MEDIA_UPLOAD_ENABLED, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_TILED_GALLERY_BLOCK, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_VIDEOPRESS_BLOCK, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_FACEBOOK_EMBED_BLOCK, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_INSTAGRAM_EMBED_BLOCK, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_LOOM_EMBED_BLOCK, true)
+            capabilities.putBoolean(GutenbergProps.PROP_CAPABILITIES_SMARTFRAME_EMBED_BLOCK, true)
+            bundle.putBundle(GutenbergProps.PROP_CAPABILITIES, capabilities)
+            if (initialTitle != null) {
+                bundle.putString(GutenbergProps.PROP_INITIAL_TITLE, initialTitle)
+            }
+            if (initialData != null) {
+                bundle.putString(GutenbergProps.PROP_INITIAL_DATA, initialData)
+            }
+            if (rawStyles != null) {
+                bundle.putString(GutenbergProps.PROP_STYLES, rawStyles)
+            }
+            if (rawFeatures != null) {
+                bundle.putString(GutenbergProps.PROP_FEATURES, rawFeatures)
+            }
+            return bundle
+        }
+
+    companion object {
+        var instance: MainActivity? = null
+            private set
+        private const val EXTRAS_INITIAL_PROPS = "initialProps"
+    }
+}
diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java
deleted file mode 100644
index 4477f1cc1d9f35..00000000000000
--- a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java
+++ /dev/null
@@ -1,433 +0,0 @@
-package com.gutenberg;
-
-import android.app.Application;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.Toast;
-
-import androidx.core.util.Consumer;
-
-import com.facebook.react.ReactApplication;
-import com.BV.LinearGradient.LinearGradientPackage;
-import com.facebook.react.bridge.Arguments;
-import com.facebook.react.bridge.ReadableMap;
-import com.facebook.react.bridge.WritableNativeMap;
-import com.reactnativecommunity.clipboard.ClipboardPackage;
-import com.reactnativecommunity.slider.ReactSliderPackage;
-import com.brentvatne.react.ReactVideoPackage;
-import com.facebook.react.bridge.ReadableArray;
-import com.facebook.react.devsupport.interfaces.DevOptionHandler;
-import com.facebook.react.devsupport.interfaces.DevSupportManager;
-import com.horcrux.svg.SvgPackage;
-import org.linusu.RNGetRandomValuesPackage;
-import com.dylanvann.fastimage.FastImageViewPackage;
-
-import org.wordpress.mobile.ReactNativeAztec.ReactAztecPackage;
-import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeInterface;
-import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent;
-import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergWebViewActivity;
-import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia;
-import org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgePackage;
-
-import com.facebook.react.ReactNativeHost;
-import com.facebook.react.ReactPackage;
-import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
-import com.facebook.react.defaults.DefaultReactNativeHost;
-import com.facebook.react.shell.MainReactPackage;
-import com.facebook.soloader.SoLoader;
-import com.reactnativecommunity.webview.RNCWebViewPackage;
-import com.swmansion.gesturehandler.RNGestureHandlerPackage;
-import com.swmansion.reanimated.ReanimatedPackage;
-import com.swmansion.rnscreens.RNScreensPackage;
-import com.th3rdwave.safeareacontext.SafeAreaContextPackage;
-import org.reactnative.maskedview.RNCMaskedViewPackage;
-import org.wordpress.mobile.WPAndroidGlue.Media;
-import org.wordpress.mobile.WPAndroidGlue.MediaOption;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.ArrayList;
-
-public class MainApplication extends Application implements ReactApplication, GutenbergBridgeInterface {
-
-    private static final String TAG = "MainApplication";
-
-    private ReactNativeHost mReactNativeHost;
-    private RNReactNativeGutenbergBridgePackage mRnReactNativeGutenbergBridgePackage;
-    private GutenbergBridgeJS2Parent.ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback;
-
-    private ReactNativeHost createReactNativeHost() {
-        mRnReactNativeGutenbergBridgePackage = new RNReactNativeGutenbergBridgePackage(new GutenbergBridgeJS2Parent() {
-            @Override
-            public void responseHtml(String title, String html, boolean changed, ReadableMap contentInfo) {
-            }
-
-            @Override
-            public void requestMediaImport(String url, MediaSelectedCallback mediaSelectedCallback) {
-            }
-
-            @Override
-            public void requestMediaPickerFromDeviceCamera(MediaSelectedCallback mediaSelectedCallback, MediaType mediaType) {
-            }
-
-            @Override
-            public void requestMediaPickFromDeviceLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) {
-            }
-
-            @Override
-            public void requestMediaPickFromMediaLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) {
-                List<RNMedia> rnMediaList = new ArrayList<>();
-                WritableNativeMap emptyMetadata = new WritableNativeMap();
-
-                switch (mediaType) {
-                    case IMAGE:
-                        Media image = new Media(1, "https://cldup.com/cXyG__fTLN.jpg", "image", "Mountain", "", "A snow-capped mountain top in a cloudy sky with red-leafed trees in the foreground", emptyMetadata);
-                        rnMediaList.add(image);
-                        break;
-                    case VIDEO:
-                        WritableNativeMap metadata = new WritableNativeMap();
-                        metadata.putString("extraID", "AbCdE");
-                        Media video = new Media(2, "https://i.cloudup.com/YtZFJbuQCE.mov", "video", "Cloudup", "", "", metadata);
-                        rnMediaList.add(video);
-                        break;
-                    case ANY:
-                    case OTHER:
-                        Media other = new Media(3, "https://wordpress.org/latest.zip", "zip", "WordPress latest version", "WordPress.zip", "", emptyMetadata);
-                        rnMediaList.add(other);
-                        break;
-                    case AUDIO:
-                        Media audio = new Media(5, "https://cldup.com/59IrU0WJtq.mp3", "audio", "Summer presto", "", "", emptyMetadata);
-                        rnMediaList.add(audio);
-                        break;
-                }
-                mediaSelectedCallback.onMediaFileSelected(rnMediaList);
-            }
-
-
-            @Override
-            public void mediaUploadSync(MediaSelectedCallback mediaSelectedCallback) {
-            }
-
-            @Override
-            public void mediaSaveSync(MediaSelectedCallback mediaSelectedCallback) {
-            }
-
-            @Override
-            public void requestImageFailedRetryDialog(int mediaId) {
-            }
-
-            @Override
-            public void requestImageUploadCancelDialog(int mediaId) {
-            }
-
-            @Override
-            public void requestImageUploadCancel(int mediaId) {
-            }
-
-            @Override
-            public void setFeaturedImage(int mediaId) {
-            }
-
-            @Override
-            public void editorDidMount(ReadableArray unsupportedBlockNames) {
-            }
-
-            @Override
-            public void editorDidAutosave() {
-            }
-
-            @Override
-            public void getOtherMediaPickerOptions(OtherMediaOptionsReceivedCallback otherMediaOptionsReceivedCallback, MediaType mediaType) {
-                if (mediaType == MediaType.ANY) {
-                    ArrayList<MediaOption> mediaOptions = new ArrayList<>();
-                    mediaOptions.add(new MediaOption("1", "Choose from device"));
-                    otherMediaOptionsReceivedCallback.onOtherMediaOptionsReceived(mediaOptions);
-                }
-            }
-
-            @Override
-            public void requestMediaPickFrom(String mediaSource, MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection) {
-                if (mediaSource.equals("1")) {
-                    List<RNMedia> rnMediaList = new ArrayList<>();
-                    Media pdf = new Media(1, "https://grad.illinois.edu/sites/default/files/pdfs/cvsamples.pdf", "other", "","cvsamples.pdf", "", new WritableNativeMap());
-                    rnMediaList.add(pdf);
-                    mediaSelectedCallback.onMediaFileSelected(rnMediaList);
-                }
-            }
-
-            @Override
-            public void requestImageFullscreenPreview(String mediaUrl) {
-
-            }
-
-            @Override
-            public void requestEmbedFullscreenPreview(String content, String title) {
-
-            }
-
-            @Override
-            public void requestMediaEditor(MediaSelectedCallback mediaSelectedCallback, String mediaUrl) {
-
-            }
-
-            @Override
-            public void setFocalPointPickerTooltipShown(boolean tooltipShown) {
-            }
-
-            @Override
-            public void requestFocalPointPickerTooltipShown(FocalPointPickerTooltipShownCallback focalPointPickerTooltipShownCallback) {
-                focalPointPickerTooltipShownCallback.onRequestFocalPointPickerTooltipShown(false);
-            }
-
-            @Override
-            public void editorDidEmitLog(String message, LogLevel logLevel) {
-                switch (logLevel) {
-                    case TRACE:
-                        Log.d(TAG, message);
-                        break;
-                    case INFO:
-                        Log.i(TAG, message);
-                        break;
-                    case WARN:
-                        Log.w(TAG, message);
-                        break;
-                    case ERROR:
-                        Log.e(TAG, message);
-                        break;
-                }
-            }
-
-            @Override
-            public void performGetRequest(String path, boolean enableCaching, Consumer<String> onSuccess, Consumer<Bundle> onError) {}
-
-            @Override
-            public void performPostRequest(String path, ReadableMap data, Consumer<String> onSuccess, Consumer<Bundle> onError) {}
-
-            @Override
-            public void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback replaceUnsupportedBlockCallback,
-                                                                    String content,
-                                                                    String blockId,
-                                                                    String blockName,
-                                                                    String blockTitle) {
-                mReplaceUnsupportedBlockCallback = replaceUnsupportedBlockCallback;
-                openGutenbergWebView(content, blockId, blockTitle);
-            }
-
-            @Override
-            public void onShowUserSuggestions(Consumer<String> onResult) {
-                onResult.accept("matt");
-            }
-
-            @Override
-            public void onShowXpostSuggestions(Consumer<String> onResult) {
-                onResult.accept("ma.tt");
-            }
-
-            @Override
-            public void requestMediaFilesEditorLoad(
-                    ReadableArray mediaFiles,
-                    String blockId
-            ) {
-                Toast.makeText(MainApplication.this, "requestMediaFilesEditorLoad called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void requestMediaFilesFailedRetryDialog(ReadableArray mediaFiles) {
-                Toast.makeText(MainApplication.this, "requestMediaFilesFailedRetryDialog called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void requestMediaFilesUploadCancelDialog(ReadableArray mediaFiles) {
-                Toast.makeText(MainApplication.this, "requestMediaFilesUploadCancelDialog called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void requestMediaFilesSaveCancelDialog(ReadableArray mediaFiles) {
-                Toast.makeText(MainApplication.this, "requestMediaFilesSaveCancelDialog called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void mediaFilesBlockReplaceSync(
-                    ReadableArray mediaFiles,
-                    String blockId
-            ) {
-                Toast.makeText(MainApplication.this, "mediaFilesBlockReplaceSync called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void gutenbergDidSendButtonPressedAction(String buttonType) {
-
-            }
-
-            @Override
-            public void requestPreview() {
-                Toast.makeText(MainApplication.this, "requestPreview called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void requestBlockTypeImpressions(BlockTypeImpressionsCallback blockTypeImpressionsCallback) {
-                ReadableMap impressions = Arguments.createMap();
-                blockTypeImpressionsCallback.onRequestBlockTypeImpressions(impressions);
-            }
-
-            @Override
-            public void setBlockTypeImpressions(ReadableMap impressions) {
-                Log.d("BlockTypeImpressions", String.format("Gutenberg requested setting block type impression to %s.", impressions));
-            }
-
-            @Override
-            public void requestContactCustomerSupport() {
-                Toast.makeText(MainApplication.this, "requestContactCustomerSupport called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void requestGotoCustomerSupportOptions() {
-                Toast.makeText(MainApplication.this, "requestGotoCustomerSupportOptions called", Toast.LENGTH_SHORT).show();
-            }
-
-            @Override
-            public void sendEventToHost(final String eventName, final ReadableMap properties) {
-                Log.d("SendEventToHost", String.format("Gutenberg requested sending '%s' event to host with properties: %s", eventName, properties));
-            }
-
-            @Override
-            public void toggleUndoButton(boolean isDisabled) {
-                MainActivity mainActivity = MainActivity.getInstance();
-                if (mainActivity != null) {
-                    mainActivity.updateUndoItem(isDisabled);
-                }
-            }
-
-            @Override
-            public void toggleRedoButton(boolean isDisabled) {
-                MainActivity mainActivity = MainActivity.getInstance();
-                if (mainActivity != null) {
-                    mainActivity.updateRedoItem(isDisabled);
-                }
-            }
-
-            @Override
-            public void requestConnectionStatus(ConnectionStatusCallback connectionStatusCallback) {
-                connectionStatusCallback.onRequestConnectionStatus(true);
-            }
-        }, isDarkMode());
-
-        return new DefaultReactNativeHost(this) {
-            @Override
-            public boolean getUseDeveloperSupport() {
-                return BuildConfig.DEBUG;
-            }
-
-            @Override
-            protected List<ReactPackage> getPackages() {
-                return Arrays.asList(
-                        new MainReactPackage(),
-                        new ReactSliderPackage(),
-                        new ReactVideoPackage(),
-                        new SvgPackage(),
-                        // passing null because we do not need log handlers in the demo app
-                        new ReactAztecPackage(null, null),
-                        new LinearGradientPackage(),
-                        new RNGetRandomValuesPackage(),
-                        new RNCMaskedViewPackage(),
-                        new RNGestureHandlerPackage(),
-                        new ReanimatedPackage(),
-                        new SafeAreaContextPackage(),
-                        new RNScreensPackage(),
-                        new RNCWebViewPackage(),
-                        new ClipboardPackage(),
-                        new FastImageViewPackage(),
-                        mRnReactNativeGutenbergBridgePackage);
-            }
-
-            @Override
-            protected String getJSMainModuleName() {
-                return "index";
-            }
-
-            @Override
-            protected boolean isNewArchEnabled() {
-                return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
-            }
-            @Override
-            protected Boolean isHermesEnabled() {
-                return BuildConfig.IS_HERMES_ENABLED;
-            }
-        };
-    }
-
-    private boolean isDarkMode() {
-        Configuration configuration = getResources().getConfiguration();
-        int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
-
-        return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
-    }
-
-    public void toggleUndo() {
-        mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().onUndoPressed();
-    }
-
-    public void toggleRedo() {
-        mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().onRedoPressed();
-    }
-
-    private void openGutenbergWebView(String content,
-                                      String blockId,
-                                      String blockName) {
-        Intent intent = new Intent(this, GutenbergWebViewActivity.class);
-        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_CONTENT, content);
-        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_ID, blockId);
-        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_NAME, blockName);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        startActivity(intent);
-    }
-
-    @Override
-    public ReactNativeHost getReactNativeHost() {
-        if (mReactNativeHost == null) {
-            mReactNativeHost = createReactNativeHost();
-            createCustomDevOptions(mReactNativeHost);
-        }
-
-        return mReactNativeHost;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        SoLoader.init(this, /* native exopackage */ false);
-        if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
-            // If you opted-in for the New Architecture, we load the native entry point for this app.
-            DefaultNewArchitectureEntryPoint.load();
-        }
-        ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
-    }
-
-    private void createCustomDevOptions(ReactNativeHost reactNativeHost) {
-        DevSupportManager devSupportManager = reactNativeHost.getReactInstanceManager().getDevSupportManager();
-
-        devSupportManager.addCustomDevOption("Show html", new DevOptionHandler() {
-            @Override
-            public void onOptionSelected() {
-                mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().toggleEditorMode();
-            }
-        });
-
-        devSupportManager.addCustomDevOption("Help", new DevOptionHandler() {
-            @Override
-            public void onOptionSelected() {
-                mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().showEditorHelp();
-            }
-        });
-    }
-
-    @Override
-    public void saveContent(String content, String blockId) {
-        if (mReplaceUnsupportedBlockCallback != null) {
-            mReplaceUnsupportedBlockCallback.replaceUnsupportedBlock(content, blockId);
-        }
-    }
-}
diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.kt b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.kt
new file mode 100644
index 00000000000000..f1a86917b23867
--- /dev/null
+++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.kt
@@ -0,0 +1,309 @@
+package com.gutenberg
+
+import android.app.Application
+import android.content.Intent
+import android.content.res.Configuration
+import android.os.Bundle
+import android.util.Log
+import android.widget.Toast
+import androidx.core.util.Consumer
+import com.BV.LinearGradient.LinearGradientPackage
+import com.brentvatne.react.ReactVideoPackage
+import com.dylanvann.fastimage.FastImageViewPackage
+import com.facebook.react.ReactApplication
+import com.facebook.react.ReactNativeHost
+import com.facebook.react.ReactPackage
+import com.facebook.react.PackageList
+import com.facebook.react.ReactHost
+import com.facebook.react.bridge.Arguments
+import com.facebook.react.bridge.ReadableArray
+import com.facebook.react.bridge.ReadableMap
+import com.facebook.react.bridge.WritableNativeMap
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
+import com.facebook.react.defaults.DefaultReactHost
+import com.facebook.react.defaults.DefaultReactNativeHost
+import com.facebook.react.flipper.ReactNativeFlipper
+import com.facebook.soloader.SoLoader
+import com.horcrux.svg.SvgPackage
+import com.reactnativecommunity.clipboard.ClipboardPackage
+import com.reactnativecommunity.slider.ReactSliderPackage
+import com.reactnativecommunity.webview.RNCWebViewPackage
+import com.swmansion.gesturehandler.RNGestureHandlerPackage
+import com.swmansion.reanimated.ReanimatedPackage
+import com.swmansion.rnscreens.RNScreensPackage
+import com.th3rdwave.safeareacontext.SafeAreaContextPackage
+import org.linusu.RNGetRandomValuesPackage
+import org.reactnative.maskedview.RNCMaskedViewPackage
+import org.wordpress.mobile.ReactNativeAztec.ReactAztecPackage
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeInterface
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.BlockTypeImpressionsCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.ConnectionStatusCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.FocalPointPickerTooltipShownCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaSelectedCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.OtherMediaOptionsReceivedCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.ReplaceUnsupportedBlockCallback
+import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergWebViewActivity
+import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia
+import org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgePackage
+import org.wordpress.mobile.WPAndroidGlue.Media
+import org.wordpress.mobile.WPAndroidGlue.MediaOption
+
+class MainApplication : Application(), ReactApplication, GutenbergBridgeInterface {
+    private var mRnReactNativeGutenbergBridgePackage: RNReactNativeGutenbergBridgePackage? = null
+    private var mReplaceUnsupportedBlockCallback: ReplaceUnsupportedBlockCallback? = null
+
+    override val reactNativeHost: ReactNativeHost =
+        object : DefaultReactNativeHost(this) {
+            override fun getPackages(): List<ReactPackage> =
+                PackageList(this).packages.apply {
+                    add(ReactSliderPackage())
+                    add(ReactVideoPackage())
+                    add(SvgPackage()) // passing null because we do not need log handlers in the demo ap)p
+                    add(ReactAztecPackage(null, null))
+                    add(LinearGradientPackage())
+                    add(RNGetRandomValuesPackage())
+                    add(RNCMaskedViewPackage())
+                    add(RNGestureHandlerPackage())
+                    add(ReanimatedPackage())
+                    add(SafeAreaContextPackage())
+                    add(RNScreensPackage())
+                    add(RNCWebViewPackage())
+                    add(ClipboardPackage())
+                    add(FastImageViewPackage())
+                    add(mRnReactNativeGutenbergBridgePackage)
+                }
+
+            override fun getJSMainModuleName(): String {
+                return "index"
+            }
+
+            override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
+
+            override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
+            override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
+        }
+
+    private fun initializeGutenbergBridge() {
+        mRnReactNativeGutenbergBridgePackage = RNReactNativeGutenbergBridgePackage(object : GutenbergBridgeJS2Parent {
+            override fun responseHtml(title: String, html: String, changed: Boolean, contentInfo: ReadableMap) {}
+            override fun requestMediaImport(url: String, mediaSelectedCallback: MediaSelectedCallback) {}
+            override fun requestMediaPickerFromDeviceCamera(mediaSelectedCallback: MediaSelectedCallback, mediaType: GutenbergBridgeJS2Parent.MediaType) {}
+            override fun requestMediaPickFromDeviceLibrary(mediaSelectedCallback: MediaSelectedCallback, allowMultipleSelection: Boolean, mediaType: GutenbergBridgeJS2Parent.MediaType) {}
+            override fun requestMediaPickFromMediaLibrary(mediaSelectedCallback: MediaSelectedCallback, allowMultipleSelection: Boolean, mediaType: GutenbergBridgeJS2Parent.MediaType) {
+                val rnMediaList: MutableList<RNMedia> = ArrayList()
+                val emptyMetadata = WritableNativeMap()
+                when (mediaType) {
+                    GutenbergBridgeJS2Parent.MediaType.IMAGE -> {
+                        val image = Media(1, "https://cldup.com/cXyG__fTLN.jpg", "image", "Mountain", "", "A snow-capped mountain top in a cloudy sky with red-leafed trees in the foreground", emptyMetadata)
+                        rnMediaList.add(image)
+                    }
+
+                    GutenbergBridgeJS2Parent.MediaType.VIDEO -> {
+                        val metadata = WritableNativeMap()
+                        metadata.putString("extraID", "AbCdE")
+                        val video = Media(2, "https://i.cloudup.com/YtZFJbuQCE.mov", "video", "Cloudup", "", "", metadata)
+                        rnMediaList.add(video)
+                    }
+
+                    GutenbergBridgeJS2Parent.MediaType.ANY, GutenbergBridgeJS2Parent.MediaType.OTHER -> {
+                        val other = Media(3, "https://wordpress.org/latest.zip", "zip", "WordPress latest version", "WordPress.zip", "", emptyMetadata)
+                        rnMediaList.add(other)
+                    }
+
+                    GutenbergBridgeJS2Parent.MediaType.AUDIO -> {
+                        val audio = Media(5, "https://cldup.com/59IrU0WJtq.mp3", "audio", "Summer presto", "", "", emptyMetadata)
+                        rnMediaList.add(audio)
+                    }
+
+                    else -> {}
+                }
+                mediaSelectedCallback.onMediaFileSelected(rnMediaList)
+            }
+
+            override fun mediaUploadSync(mediaSelectedCallback: MediaSelectedCallback) {}
+            override fun mediaSaveSync(mediaSelectedCallback: MediaSelectedCallback) {}
+            override fun requestImageFailedRetryDialog(mediaId: Int) {}
+            override fun requestImageUploadCancelDialog(mediaId: Int) {}
+            override fun requestImageUploadCancel(mediaId: Int) {}
+            override fun setFeaturedImage(mediaId: Int) {}
+            override fun editorDidMount(unsupportedBlockNames: ReadableArray) {}
+            override fun editorDidAutosave() {}
+            override fun getOtherMediaPickerOptions(otherMediaOptionsReceivedCallback: OtherMediaOptionsReceivedCallback, mediaType: GutenbergBridgeJS2Parent.MediaType) {
+                if (mediaType == GutenbergBridgeJS2Parent.MediaType.ANY) {
+                    val mediaOptions = ArrayList<MediaOption>()
+                    mediaOptions.add(MediaOption("1", "Choose from device"))
+                    otherMediaOptionsReceivedCallback.onOtherMediaOptionsReceived(mediaOptions)
+                }
+            }
+
+            override fun requestMediaPickFrom(mediaSource: String, mediaSelectedCallback: MediaSelectedCallback, allowMultipleSelection: Boolean) {
+                if (mediaSource == "1") {
+                    val rnMediaList: MutableList<RNMedia> = ArrayList()
+                    val pdf = Media(1, "https://grad.illinois.edu/sites/default/files/pdfs/cvsamples.pdf", "other", "", "cvsamples.pdf", "", WritableNativeMap())
+                    rnMediaList.add(pdf)
+                    mediaSelectedCallback.onMediaFileSelected(rnMediaList)
+                }
+            }
+
+            override fun requestImageFullscreenPreview(mediaUrl: String) {}
+            override fun requestEmbedFullscreenPreview(content: String, title: String) {}
+            override fun requestMediaEditor(mediaSelectedCallback: MediaSelectedCallback, mediaUrl: String) {}
+            override fun setFocalPointPickerTooltipShown(tooltipShown: Boolean) {}
+            override fun requestFocalPointPickerTooltipShown(focalPointPickerTooltipShownCallback: FocalPointPickerTooltipShownCallback) {
+                focalPointPickerTooltipShownCallback.onRequestFocalPointPickerTooltipShown(false)
+            }
+
+            override fun editorDidEmitLog(message: String, logLevel: GutenbergBridgeJS2Parent.LogLevel) {
+                when (logLevel) {
+                    GutenbergBridgeJS2Parent.LogLevel.TRACE -> Log.d(TAG, message)
+                    GutenbergBridgeJS2Parent.LogLevel.INFO -> Log.i(TAG, message)
+                    GutenbergBridgeJS2Parent.LogLevel.WARN -> Log.w(TAG, message)
+                    GutenbergBridgeJS2Parent.LogLevel.ERROR -> Log.e(TAG, message)
+                }
+            }
+
+            override fun performGetRequest(path: String, enableCaching: Boolean, onSuccess: Consumer<String>, onError: Consumer<Bundle>) {}
+            override fun performPostRequest(path: String, data: ReadableMap, onSuccess: Consumer<String>, onError: Consumer<Bundle>) {}
+            override fun gutenbergDidRequestUnsupportedBlockFallback(replaceUnsupportedBlockCallback: ReplaceUnsupportedBlockCallback,
+                                                                     content: String,
+                                                                     blockId: String,
+                                                                     blockName: String,
+                                                                     blockTitle: String) {
+                mReplaceUnsupportedBlockCallback = replaceUnsupportedBlockCallback
+                openGutenbergWebView(content, blockId, blockTitle)
+            }
+
+            override fun onShowUserSuggestions(onResult: Consumer<String>) {
+                onResult.accept("matt")
+            }
+
+            override fun onShowXpostSuggestions(onResult: Consumer<String>) {
+                onResult.accept("ma.tt")
+            }
+
+            override fun requestMediaFilesEditorLoad(
+                mediaFiles: ReadableArray,
+                blockId: String
+            ) {
+                Toast.makeText(this@MainApplication, "requestMediaFilesEditorLoad called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun requestMediaFilesFailedRetryDialog(mediaFiles: ReadableArray) {
+                Toast.makeText(this@MainApplication, "requestMediaFilesFailedRetryDialog called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun requestMediaFilesUploadCancelDialog(mediaFiles: ReadableArray) {
+                Toast.makeText(this@MainApplication, "requestMediaFilesUploadCancelDialog called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun requestMediaFilesSaveCancelDialog(mediaFiles: ReadableArray) {
+                Toast.makeText(this@MainApplication, "requestMediaFilesSaveCancelDialog called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun mediaFilesBlockReplaceSync(
+                mediaFiles: ReadableArray,
+                blockId: String
+            ) {
+                Toast.makeText(this@MainApplication, "mediaFilesBlockReplaceSync called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun gutenbergDidSendButtonPressedAction(buttonType: String) {}
+            override fun requestPreview() {
+                Toast.makeText(this@MainApplication, "requestPreview called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun requestBlockTypeImpressions(blockTypeImpressionsCallback: BlockTypeImpressionsCallback) {
+                val impressions: ReadableMap = Arguments.createMap()
+                blockTypeImpressionsCallback.onRequestBlockTypeImpressions(impressions)
+            }
+
+            override fun setBlockTypeImpressions(impressions: ReadableMap) {
+                Log.d("BlockTypeImpressions", String.format("Gutenberg requested setting block type impression to %s.", impressions))
+            }
+
+            override fun requestContactCustomerSupport() {
+                Toast.makeText(this@MainApplication, "requestContactCustomerSupport called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun requestGotoCustomerSupportOptions() {
+                Toast.makeText(this@MainApplication, "requestGotoCustomerSupportOptions called", Toast.LENGTH_SHORT).show()
+            }
+
+            override fun sendEventToHost(eventName: String, properties: ReadableMap) {
+                Log.d("SendEventToHost", String.format("Gutenberg requested sending '%s' event to host with properties: %s", eventName, properties))
+            }
+
+            override fun toggleUndoButton(isDisabled: Boolean) {
+                MainActivity.instance?.updateUndoItem(isDisabled)
+            }
+
+            override fun toggleRedoButton(isDisabled: Boolean) {
+                MainActivity.instance?.updateRedoItem(isDisabled)
+            }
+
+            override fun requestConnectionStatus(connectionStatusCallback: ConnectionStatusCallback) {
+                connectionStatusCallback.onRequestConnectionStatus(true)
+            }
+        }, isDarkMode)
+    }
+
+    private val isDarkMode: Boolean
+        get() {
+            val configuration = resources.configuration
+            val currentNightMode = configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
+            return currentNightMode == Configuration.UI_MODE_NIGHT_YES
+        }
+
+    fun toggleUndo() {
+        mRnReactNativeGutenbergBridgePackage!!.rnReactNativeGutenbergBridgeModule.onUndoPressed()
+    }
+
+    fun toggleRedo() {
+        mRnReactNativeGutenbergBridgePackage!!.rnReactNativeGutenbergBridgeModule.onRedoPressed()
+    }
+
+    private fun openGutenbergWebView(content: String,
+                                     blockId: String,
+                                     blockName: String) {
+        val intent = Intent(this, GutenbergWebViewActivity::class.java)
+        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_CONTENT, content)
+        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_ID, blockId)
+        intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_NAME, blockName)
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        startActivity(intent)
+    }
+
+    override val reactHost: ReactHost
+        get() = DefaultReactHost.getDefaultReactHost(this.applicationContext, reactNativeHost)
+
+    override fun onCreate() {
+        super.onCreate()
+        SoLoader.init(this,  /* native exopackage */false)
+
+        initializeGutenbergBridge()
+
+        if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+            // If you opted-in for the New Architecture, we load the native entry point for this app.
+            load()
+        }
+        ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager)
+        createCustomDevOptions(reactNativeHost)
+    }
+
+    private fun createCustomDevOptions(reactNativeHost: ReactNativeHost?) {
+        val devSupportManager = reactNativeHost!!.reactInstanceManager.devSupportManager
+        devSupportManager.addCustomDevOption("Show html") { mRnReactNativeGutenbergBridgePackage!!.rnReactNativeGutenbergBridgeModule.toggleEditorMode() }
+        devSupportManager.addCustomDevOption("Help") { mRnReactNativeGutenbergBridgePackage!!.rnReactNativeGutenbergBridgeModule.showEditorHelp() }
+    }
+
+    override fun saveContent(content: String, blockId: String) {
+        if (mReplaceUnsupportedBlockCallback != null) {
+            mReplaceUnsupportedBlockCallback!!.replaceUnsupportedBlock(content, blockId)
+        }
+    }
+
+    companion object {
+        private const val TAG = "MainApplication"
+    }
+}