1
0
Fork 0

For #4007 - Add ShareController for handling ShareFragment's business logic

`ShareController` defines a contract with all possible `ShareFragment`'s
behavior changes and comes with a default implementation -
`DefaultShareController`.
It is to be delegated by all `ShareFragment`s contained Views' Interactors
following any user interactions.
master
Mugurell 2019-08-28 11:20:32 +03:00 committed by Jeff Boek
parent 16eba61b25
commit e165868a53
3 changed files with 125 additions and 8 deletions

View File

@ -0,0 +1,104 @@
/* 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
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.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.DeviceEventOutgoing
import mozilla.components.concept.sync.OAuthAccount
import org.mozilla.fenix.R
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 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 tabs the list of [ShareTab]s that can be shared.
* @param account the [OAuthAccount] to which tabs can be shared.
* @param navController - [NavController] used for navigation.
* @param dismiss - callback signalling sharing can be closed.
*/
class DefaultShareController(
private val fragment: Fragment,
private val tabs: List<ShareTab>,
private val account: OAuthAccount?,
private val navController: NavController,
private val dismiss: () -> Unit
) : ShareController {
override fun handleShareClosed() {
dismiss()
}
override fun handleShareToApp(app: AppShareOption) {
val shareText = tabs.joinToString("\n") { tab -> tab.url }
val intent = Intent(ACTION_SEND).apply {
putExtra(EXTRA_TEXT, shareText)
type = "text/plain"
flags = FLAG_ACTIVITY_NEW_TASK
setClassName(app.packageName, app.activityName)
}
fragment.startActivity(intent)
dismiss()
}
override fun handleAddNewDevice() {
AlertDialog.Builder(fragment.requireContext()).apply {
setMessage(R.string.sync_connect_device_dialog)
setPositiveButton(R.string.sync_confirmation_button) { dialog, _ -> dialog.cancel() }
create()
}.show()
}
override fun handleShareToDevice(device: Device) {
sendTab(device.id)
(fragment.activity as ShareFragment.TabsSharedCallback).onTabsShared(tabs.size)
dismiss()
}
override fun handleShareToAllDevices(devices: List<Device>) {
devices.forEach { device -> sendTab(device.id) }
(fragment.activity as ShareFragment.TabsSharedCallback).onTabsShared(tabs.size)
dismiss()
}
override fun handleSignIn() {
val directions = ShareFragmentDirections.actionShareFragmentToTurnOnSyncFragment()
navController.nav(R.id.shareFragment, directions)
dismiss()
}
private fun sendTab(deviceId: String) {
account?.run {
tabs.forEach { tab ->
deviceConstellation().sendEventToDeviceAsync(
deviceId,
DeviceEventOutgoing.SendTab(tab.title, tab.url)
)
}
}
}
}

View File

@ -16,6 +16,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_share.view.*
import kotlinx.coroutines.Deferred
@ -27,6 +28,7 @@ import mozilla.components.concept.sync.DeviceType
import mozilla.components.service.fxa.manager.FxaAccountManager
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.share.listadapters.AppShareOption
import org.mozilla.fenix.share.listadapters.SyncShareOption
@ -79,8 +81,17 @@ class ShareFragment : AppCompatDialogFragment() {
}
val tabs = args.tabs?.toList() ?: listOf(ShareTab(args.url!!, args.title ?: ""))
val account = requireComponents.backgroundServices.accountManager.authenticatedAccount()
shareInteractor = ShareInteractor()
shareInteractor = ShareInteractor(
DefaultShareController(
fragment = this,
tabs = tabs,
navController = findNavController(),
account = account,
dismiss = ::dismiss
)
)
if (isSharingToDevicesAvailable(requireContext().applicationContext)) {
shareToAccountDevicesView = ShareToAccountDevicesView(view.devicesShareLayout, shareInteractor)

View File

@ -10,28 +10,30 @@ import org.mozilla.fenix.share.listadapters.AppShareOption
/**
* Interactor for the share screen.
*/
class ShareInteractor : ShareCloseInteractor, ShareToAccountDevicesInteractor, ShareToAppsInteractor {
class ShareInteractor(
private val controller: ShareController
) : ShareCloseInteractor, ShareToAccountDevicesInteractor, ShareToAppsInteractor {
override fun onShareClosed() {
TODO("not yet!? implemented")
controller.handleShareClosed()
}
override fun onSignIn() {
TODO("not yet!? implemented")
controller.handleSignIn()
}
override fun onAddNewDevice() {
TODO("not yet!? implemented")
controller.handleAddNewDevice()
}
override fun onShareToDevice(device: Device) {
TODO("not yet!? implemented")
controller.handleShareToDevice(device)
}
override fun onShareToAllDevices(devices: List<Device>) {
TODO("not yet!? implemented")
controller.handleShareToAllDevices(devices)
}
override fun onShareToApp(appToShareTo: AppShareOption) {
TODO("not yet!? implemented")
controller.handleShareToApp(appToShareTo)
}
}