merge navigation and tab menu into bottom sheet

This commit is contained in:
Fabian Freund
2026-02-28 18:37:35 +01:00
parent 9be77d00e5
commit b7edd95093
19 changed files with 2095 additions and 536 deletions
@@ -9,15 +9,21 @@ package eu.weblibre.flutter_mozilla_components.api
import android.content.Context
import android.content.Intent
import eu.weblibre.flutter_mozilla_components.GlobalComponents
import eu.weblibre.flutter_mozilla_components.addons.AddonInternalSettingsActivity
import eu.weblibre.flutter_mozilla_components.addons.AddonsActivity
import eu.weblibre.flutter_mozilla_components.pigeons.GeckoAddonsApi
import eu.weblibre.flutter_mozilla_components.pigeons.WebExtensionActionType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import mozilla.components.concept.engine.webextension.InstallationMethod
class GeckoAddonsApiImpl(private val context: Context) : GeckoAddonsApi {
private val components by lazy {
requireNotNull(GlobalComponents.components) { "Components not initialized" }
}
private val scope = CoroutineScope(Dispatchers.IO)
override fun startAddonManagerActivity() {
val intent = Intent(context, AddonsActivity::class.java)
@@ -25,6 +31,55 @@ class GeckoAddonsApiImpl(private val context: Context) : GeckoAddonsApi {
context.startActivity(intent)
}
override fun startAddonSettingsActivity(extensionId: String) {
scope.launch {
val addon = runCatching {
components.core.addonManager.getAddons()
.find { it.id == extensionId }
}.getOrNull()
if (addon == null) {
withContext(Dispatchers.Main) {
startAddonManagerActivity()
}
return@launch
}
val optionsPageUrl = addon.installedState?.optionsPageUrl
if (optionsPageUrl.isNullOrEmpty()) {
withContext(Dispatchers.Main) {
startAddonManagerActivity()
}
return@launch
}
withContext(Dispatchers.Main) {
if (addon.installedState?.openOptionsPageInTab == true) {
components.useCases.tabsUseCases.selectOrAddTab(
url = optionsPageUrl,
ignoreFragment = true,
)
val launchIntent = context.packageManager.getLaunchIntentForPackage(context.packageName)
launchIntent?.addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_CLEAR_TOP or
Intent.FLAG_ACTIVITY_SINGLE_TOP,
)
if (launchIntent != null) {
context.startActivity(launchIntent)
} else {
startAddonManagerActivity()
}
} else {
val intent = Intent(context, AddonInternalSettingsActivity::class.java)
intent.putExtra("add_on", addon)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
}
}
}
}
override fun invokeAddonAction(extensionId: String, actionType: WebExtensionActionType) {
when(actionType) {
WebExtensionActionType.BROWSER -> components.features.webExtensionToolbarFeature.invokeAddonBrowserAction(extensionId)
@@ -50,4 +105,4 @@ class GeckoAddonsApiImpl(private val context: Context) : GeckoAddonsApi {
}
)
}
}
}
@@ -6815,6 +6815,7 @@ class GeckoSelectionActionEvents(private val binaryMessenger: BinaryMessenger, p
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface GeckoAddonsApi {
fun startAddonManagerActivity()
fun startAddonSettingsActivity(extensionId: String)
fun invokeAddonAction(extensionId: String, actionType: WebExtensionActionType)
fun installAddon(url: String, callback: (Result<Unit>) -> Unit)
@@ -6843,6 +6844,24 @@ interface GeckoAddonsApi {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoAddonsApi.startAddonSettingsActivity$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val extensionIdArg = args[0] as String
val wrapped: List<Any?> = try {
api.startAddonSettingsActivity(extensionIdArg)
listOf(null)
} catch (exception: Throwable) {
GeckoPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoAddonsApi.invokeAddonAction$separatedMessageChannelSuffix", codec)
if (api != null) {
@@ -38,6 +38,10 @@ class GeckoAddonService extends GeckoAddonEvents {
return _api.startAddonManagerActivity();
}
Future<void> startAddonSettingsActivity(String extensionId) {
return _api.startAddonSettingsActivity(extensionId);
}
Future<void> invokeAddonAction(
String extensionId,
WebExtensionActionType actionType,
@@ -8550,6 +8550,31 @@ class GeckoAddonsApi {
}
}
Future<void> startAddonSettingsActivity(String extensionId) async {
final pigeonVar_channelName =
'dev.flutter.pigeon.flutter_mozilla_components.GeckoAddonsApi.startAddonSettingsActivity$pigeonVar_messageChannelSuffix';
final pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(
<Object?>[extensionId],
);
final pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
Future<void> invokeAddonAction(
String extensionId,
WebExtensionActionType actionType,
@@ -1602,6 +1602,8 @@ abstract class GeckoSelectionActionEvents {
abstract class GeckoAddonsApi {
void startAddonManagerActivity();
void startAddonSettingsActivity(String extensionId);
void invokeAddonAction(String extensionId, WebExtensionActionType actionType);
@async