1
0
Fork 0
fenix/app/src/main/java/org/mozilla/fenix/share/ShareController.kt

123 lines
4.5 KiB
Kotlin
Raw Normal View History

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.share
2019-09-04 17:46:34 +02:00
import android.content.Context
import android.content.Intent
import android.content.Intent.ACTION_SEND
import android.content.Intent.EXTRA_TEXT
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import com.google.android.material.snackbar.Snackbar
import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.TabData
import mozilla.components.feature.sendtab.SendTabUseCases
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
2019-09-04 17:46:34 +02:00
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.getRootView
2019-09-04 17:46:34 +02:00
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.share.listadapters.AppShareOption
/**
* [ShareFragment] controller.
*
* Delegated by View Interactors, handles container business logic and operates changes on it.
*/
interface ShareController {
fun handleReauth()
fun handleShareClosed()
fun handleShareToApp(app: AppShareOption)
fun handleAddNewDevice()
fun handleShareToDevice(device: Device)
fun handleShareToAllDevices(devices: List<Device>)
fun handleSignIn()
}
/**
* Default behavior of [ShareController]. Other implementations are possible.
*
* @param fragment the [ShareFragment] instance this controller handles business logic for.
* @param sharedTabs the list of [ShareTab]s that can be shared.
* @param sendTabUseCases instance of [SendTabUseCases] which allows sending tabs to account devices.
* @param navController - [NavController] used for navigation.
* @param dismiss - callback signalling sharing can be closed.
*/
class DefaultShareController(
2019-09-04 17:46:34 +02:00
private val context: Context,
private val fragment: Fragment,
private val sharedTabs: List<ShareTab>,
private val sendTabUseCases: SendTabUseCases,
private val navController: NavController,
private val dismiss: () -> Unit
) : ShareController {
override fun handleReauth() {
val directions = ShareFragmentDirections.actionShareFragmentToAccountProblemFragment()
navController.nav(R.id.shareFragment, directions)
dismiss()
}
override fun handleShareClosed() {
dismiss()
}
override fun handleShareToApp(app: AppShareOption) {
val intent = Intent(ACTION_SEND).apply {
putExtra(EXTRA_TEXT, getShareText())
type = "text/plain"
flags = FLAG_ACTIVITY_NEW_TASK
setClassName(app.packageName, app.activityName)
}
try {
fragment.startActivity(intent)
} catch (e: SecurityException) {
context.getRootView()?.let {
FenixSnackbar.make(it, Snackbar.LENGTH_LONG)
.setText(context.getString(R.string.share_error_snackbar))
.show()
}
}
dismiss()
}
override fun handleAddNewDevice() {
val directions = ShareFragmentDirections.actionShareFragmentToAddNewDeviceFragment()
navController.navigate(directions)
}
override fun handleShareToDevice(device: Device) {
2019-09-04 17:46:34 +02:00
context.metrics.track(Event.SendTab)
sendTabUseCases.sendToDeviceAsync(device.id, sharedTabs.toTabData())
(fragment.activity as ShareFragment.TabsSharedCallback).onTabsShared(sharedTabs.size)
dismiss()
}
override fun handleShareToAllDevices(devices: List<Device>) {
sendTabUseCases.sendToAllAsync(sharedTabs.toTabData())
(fragment.activity as ShareFragment.TabsSharedCallback).onTabsShared(sharedTabs.size)
dismiss()
}
override fun handleSignIn() {
2019-09-04 17:46:34 +02:00
context.metrics.track(Event.SignInToSendTab)
val directions = ShareFragmentDirections.actionShareFragmentToTurnOnSyncFragment()
navController.nav(R.id.shareFragment, directions)
dismiss()
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun getShareText() = sharedTabs.joinToString("\n") { tab -> tab.url }
// Navigation between app fragments uses ShareTab as arguments. SendTabUseCases uses TabData.
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun ShareTab.toTabData() = TabData(title, url)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun List<ShareTab>.toTabData() = map { it.toTabData() }
}