Skip to content

Commit

Permalink
Merge pull request #18169 from wordpress-mobile/issue/18114-wp-jp-plu…
Browse files Browse the repository at this point in the history
…gin-overlay-dialog

[WP Individual JP Plugin] Show dialog with overlay
  • Loading branch information
Thomas Horta authored Mar 28, 2023
2 parents d609fa5 + c84ebfc commit 8a07a96
Show file tree
Hide file tree
Showing 20 changed files with 500 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.wordpress.android.ui.ShareIntentReceiverFragment;
import org.wordpress.android.ui.WPWebViewActivity;
import org.wordpress.android.ui.about.UnifiedAboutActivity;
import org.wordpress.android.ui.accounts.PostSignupInterstitialActivity;
import org.wordpress.android.ui.accounts.SignupEpilogueActivity;
import org.wordpress.android.ui.accounts.signup.SignupEpilogueFragment;
import org.wordpress.android.ui.activitylog.detail.ActivityLogDetailFragment;
Expand Down Expand Up @@ -49,7 +48,6 @@
import org.wordpress.android.ui.main.AddContentAdapter;
import org.wordpress.android.ui.main.MainBottomSheetFragment;
import org.wordpress.android.ui.main.MeFragment;
import org.wordpress.android.ui.main.SitePickerActivity;
import org.wordpress.android.ui.main.SitePickerAdapter;
import org.wordpress.android.ui.main.WPMainActivity;
import org.wordpress.android.ui.media.MediaBrowserActivity;
Expand Down Expand Up @@ -213,8 +211,6 @@ public interface AppComponent {

void inject(SignupEpilogueFragment object);

void inject(PostSignupInterstitialActivity object);

void inject(JetpackConnectionResultActivity object);

void inject(StatsConnectJetpackActivity object);
Expand All @@ -241,8 +237,6 @@ public interface AppComponent {

void inject(AccountSettingsFragment object);

void inject(SitePickerActivity object);

void inject(SitePickerAdapter object);

void inject(SiteSettingsFragment object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package org.wordpress.android.ui

import android.content.DialogInterface
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.wordpress.android.util.extensions.fillScreen

/**
* Customises [BottomSheetDialogFragment] for fullscreen
Expand All @@ -20,24 +19,7 @@ abstract class FullscreenBottomSheetDialogFragment : BottomSheetDialogFragment()
}

override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(requireContext(), getTheme()).apply {
fillTheScreen(this)
this.fillScreen(isDraggable = true)
window?.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
}

private fun fillTheScreen(dialog: BottomSheetDialog) {
dialog.setOnShowListener {
dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)?.let {
val behaviour = BottomSheetBehavior.from(it)
setupFullHeight(it)
behaviour.skipCollapsed = true
behaviour.state = BottomSheetBehavior.STATE_EXPANDED
}
}
}

private fun setupFullHeight(bottomSheet: View) {
val layoutParams = bottomSheet.layoutParams
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT
bottomSheet.layoutParams = layoutParams
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import org.wordpress.android.ui.accounts.LoginNavigationEvents.CloseWithResultOk;
import org.wordpress.android.ui.accounts.LoginNavigationEvents.CreateNewSite;
import org.wordpress.android.ui.accounts.LoginNavigationEvents.SelectSite;
import org.wordpress.android.ui.accounts.LoginNavigationEvents.ShowJetpackIndividualPluginOverlay;
import org.wordpress.android.ui.accounts.LoginNavigationEvents.ShowNoJetpackSites;
import org.wordpress.android.ui.accounts.LoginNavigationEvents.ShowPostSignupInterstitialScreen;
import org.wordpress.android.ui.accounts.login.LoginEpilogueFragment;
import org.wordpress.android.ui.accounts.login.LoginEpilogueListener;
import org.wordpress.android.ui.accounts.login.jetpack.LoginNoSitesFragment;
import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginFragment;
import org.wordpress.android.ui.main.SitePickerActivity;
import org.wordpress.android.ui.mysite.SelectedSiteRepository;
import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource;
Expand Down Expand Up @@ -80,6 +82,8 @@ private void initObservers() {
closeWithResultOk();
} else if (loginEvent instanceof ShowNoJetpackSites) {
showNoJetpackSites();
} else if (loginEvent instanceof ShowJetpackIndividualPluginOverlay) {
showJetpackIndividualPluginOverlay();
}
});
}
Expand Down Expand Up @@ -150,6 +154,10 @@ private void showFragment(Fragment fragment, String tag, boolean applySlideAnima
fragmentTransaction.commit();
}

private void showJetpackIndividualPluginOverlay() {
WPJetpackIndividualPluginFragment.show(getSupportFragmentManager());
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ package org.wordpress.android.ui.accounts
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginHelper
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.util.BuildConfigWrapper
import org.wordpress.android.viewmodel.Event

import javax.inject.Inject

class LoginEpilogueViewModel @Inject constructor(
private val appPrefsWrapper: AppPrefsWrapper,
private val buildConfigWrapper: BuildConfigWrapper,
private val siteStore: SiteStore
private val siteStore: SiteStore,
private val wpJetpackIndividualPluginHelper: WPJetpackIndividualPluginHelper,
) : ViewModel() {
private val _navigationEvents = MediatorLiveData<Event<LoginNavigationEvents>>()
val navigationEvents: LiveData<Event<LoginNavigationEvents>> = _navigationEvents
Expand Down Expand Up @@ -52,4 +56,21 @@ class LoginEpilogueViewModel @Inject constructor(
fun onLoginFinished(doLoginUpdate: Boolean) {
if (doLoginUpdate && !siteStore.hasSite()) handleNoSitesFound()
}

fun onSiteListLoaded() {
// don't check if already shown
if (_navigationEvents.value?.peekContent() == LoginNavigationEvents.ShowJetpackIndividualPluginOverlay) return

viewModelScope.launch {
val showOverlay = wpJetpackIndividualPluginHelper.shouldShowJetpackIndividualPluginOverlay()
if (showOverlay) {
delay(DELAY_BEFORE_SHOWING_JETPACK_INDIVIDUAL_PLUGIN_OVERLAY)
_navigationEvents.postValue(Event(LoginNavigationEvents.ShowJetpackIndividualPluginOverlay))
}
}
}

companion object {
private const val DELAY_BEFORE_SHOWING_JETPACK_INDIVIDUAL_PLUGIN_OVERLAY = 500L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ sealed class LoginNavigationEvents {
object CloseWithResultOk : LoginNavigationEvents()
object ShowEmailLoginScreen : LoginNavigationEvents()
object ShowLoginViaSiteAddressScreen : LoginNavigationEvents()
object ShowJetpackIndividualPluginOverlay : LoginNavigationEvents()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@ import android.os.Bundle
import androidx.activity.addCallback
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.button.MaterialButton
import dagger.hilt.android.AndroidEntryPoint
import org.wordpress.android.R
import org.wordpress.android.WordPress
import org.wordpress.android.databinding.PostSignupInterstitialActivityBinding
import org.wordpress.android.ui.ActivityLauncher
import org.wordpress.android.ui.LocaleAwareActivity
import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginFragment
import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel.NavigationAction
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel.NavigationAction.DISMISS
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel.NavigationAction.SHOW_JETPACK_INDIVIDUAL_PLUGIN_OVERLAY
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel.NavigationAction.START_SITE_CONNECTION_FLOW
import org.wordpress.android.viewmodel.accounts.PostSignupInterstitialViewModel.NavigationAction.START_SITE_CREATION_FLOW
import javax.inject.Inject

@AndroidEntryPoint
class PostSignupInterstitialActivity : LocaleAwareActivity() {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
private lateinit var viewModel: PostSignupInterstitialViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
(application as WordPress).component().inject(this)

LoginFlowThemeHelper.injectMissingCustomAttributes(theme)

Expand Down Expand Up @@ -57,6 +59,7 @@ class PostSignupInterstitialActivity : LocaleAwareActivity() {
private fun executeAction(navigationAction: NavigationAction) = when (navigationAction) {
START_SITE_CREATION_FLOW -> startSiteCreationFlow()
START_SITE_CONNECTION_FLOW -> startSiteConnectionFlow()
SHOW_JETPACK_INDIVIDUAL_PLUGIN_OVERLAY -> showJetpackIndividualPluginOverlay()
DISMISS -> dismiss()
}

Expand All @@ -74,4 +77,8 @@ class PostSignupInterstitialActivity : LocaleAwareActivity() {
ActivityLauncher.viewReader(this)
finish()
}

private fun showJetpackIndividualPluginOverlay() {
WPJetpackIndividualPluginFragment.show(supportFragmentManager)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ public void onAfterLoad() {
mBottomShadow.setVisibility(View.GONE);
}
}

mParentViewModel.onSiteListLoaded();
});
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package org.wordpress.android.ui.jetpackoverlay

import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.fragment.app.activityViewModels
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
Expand All @@ -27,6 +24,7 @@ import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.RtlUtils
import org.wordpress.android.util.UrlUtils
import org.wordpress.android.util.extensions.exhaustive
import org.wordpress.android.util.extensions.fillScreen
import org.wordpress.android.util.extensions.getSerializableCompat
import org.wordpress.android.util.extensions.setVisible
import javax.inject.Inject
Expand Down Expand Up @@ -66,32 +64,7 @@ class JetpackFeatureFullScreenOverlayFragment : BottomSheetDialogFragment() {
RtlUtils.isRtl(view.context)
)
binding.setupObservers()

(dialog as? BottomSheetDialog)?.apply {
setOnShowListener {
val bottomSheet: FrameLayout = dialog?.findViewById(
com.google.android.material.R.id.design_bottom_sheet
) ?: return@setOnShowListener
val bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet)
bottomSheetBehavior.maxWidth = ViewGroup.LayoutParams.MATCH_PARENT
bottomSheetBehavior.isDraggable = false
if (bottomSheet.layoutParams != null) {
showFullScreenBottomSheet(bottomSheet)
}
expandBottomSheet(bottomSheetBehavior)
}
}
}

private fun showFullScreenBottomSheet(bottomSheet: FrameLayout) {
val layoutParams = bottomSheet.layoutParams
layoutParams.height = Resources.getSystem().displayMetrics.heightPixels
bottomSheet.layoutParams = layoutParams
}

private fun expandBottomSheet(bottomSheetBehavior: BottomSheetBehavior<FrameLayout>) {
bottomSheetBehavior.skipCollapsed = true
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
(dialog as? BottomSheetDialog)?.fillScreen()
}

private fun getSiteScreen() = arguments?.getSerializableCompat<JetpackFeatureOverlayScreenType>(OVERLAY_SCREEN_TYPE)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package org.wordpress.android.ui.jetpackoverlay.individualplugin

import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.ComposeView
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.wordpress.android.ui.ActivityLauncherWrapper
import org.wordpress.android.ui.compose.theme.AppTheme
import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginViewModel.ActionEvent
import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginViewModel.UiState
import org.wordpress.android.ui.jetpackoverlay.individualplugin.compose.WPJetpackIndividualPluginOverlayScreen
import org.wordpress.android.util.extensions.exhaustive
import org.wordpress.android.util.extensions.fillScreen
import javax.inject.Inject

@AndroidEntryPoint
class WPJetpackIndividualPluginFragment : BottomSheetDialogFragment() {
private val viewModel: WPJetpackIndividualPluginViewModel by viewModels()

@Inject
lateinit var activityLauncher: ActivityLauncherWrapper

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = ComposeView(requireContext()).apply {
setContent {
AppTheme {
val uiState by viewModel.uiState.collectAsState()
when (val state = uiState) {
is UiState.Loaded -> {
WPJetpackIndividualPluginOverlayScreen(
state.sites,
onCloseClick = viewModel::onDismissScreenClick,
onPrimaryButtonClick = viewModel::onPrimaryButtonClick,
onSecondaryButtonClick = viewModel::onDismissScreenClick,
)
}

is UiState.None -> {}
}
}
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.onScreenShown()
observeActionEvents()
}

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog =
super.onCreateDialog(savedInstanceState).apply {
(this as? BottomSheetDialog)?.fillScreen()
}

override fun onCancel(dialog: DialogInterface) {
// called when user hits the back button
viewModel.onDismissScreenClick()
}

private fun observeActionEvents() {
viewModel.actionEvents.onEach(this::handleActionEvents).launchIn(lifecycleScope)
}

private fun handleActionEvents(actionEvent: ActionEvent) {
when (actionEvent) {
is ActionEvent.PrimaryButtonClick -> activityLauncher.openPlayStoreLink(
requireActivity(),
ActivityLauncherWrapper.JETPACK_PACKAGE_NAME
)

is ActionEvent.Dismiss -> dismiss()
}.exhaustive
}

companion object {
const val TAG = "WP_JETPACK_INDIVIDUAL_PLUGIN_FRAGMENT"

@JvmStatic
fun newInstance(): WPJetpackIndividualPluginFragment = WPJetpackIndividualPluginFragment()

@JvmStatic
fun show(fm: FragmentManager): WPJetpackIndividualPluginFragment = newInstance().also {
it.show(fm, TAG)
}
}
}
Loading

0 comments on commit 8a07a96

Please sign in to comment.