From 6ba2cc286d43a83c01fb7175358d450325e39b56 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:22:12 -0500 Subject: [PATCH 01/10] Add event for OPENED_SITE_MONITORING from app link --- .../java/org/wordpress/android/analytics/AnalyticsTracker.java | 3 ++- .../wordpress/android/analytics/AnalyticsTrackerNosara.java | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java b/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java index 766cd5e3e775..ba65e2e228ea 100644 --- a/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java +++ b/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java @@ -1101,7 +1101,8 @@ public enum Stat { DYNAMIC_DASHBOARD_CARD_CTA_TAPPED, DYNAMIC_DASHBOARD_CARD_HIDE_TAPPED, DEEP_LINK_FAILED, - SITE_MONITORING_SCREEN_SHOWN + SITE_MONITORING_SCREEN_SHOWN, + OPENED_SITE_MONITORING, } private static final List TRACKERS = new ArrayList<>(); diff --git a/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java b/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java index 96eb82eefa83..6a83354fe74d 100644 --- a/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java +++ b/libs/analytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java @@ -2697,6 +2697,8 @@ public static String getEventNameForStat(AnalyticsTracker.Stat stat) { return "deep_link_failed"; case SITE_MONITORING_SCREEN_SHOWN: return "site_monitoring_screen_shown"; + case OPENED_SITE_MONITORING: + return "opened_site_monitoring"; } return null; } From a6633b00261981ac5ca022bf10046068a8ab248e Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:23:19 -0500 Subject: [PATCH 02/10] Add site-monitoring app link support. Fix miss in media https scheme --- WordPress/src/main/AndroidManifest.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/AndroidManifest.xml b/WordPress/src/main/AndroidManifest.xml index edba81e6e442..f2186cac8386 100644 --- a/WordPress/src/main/AndroidManifest.xml +++ b/WordPress/src/main/AndroidManifest.xml @@ -482,13 +482,23 @@ + android:scheme="https" /> + + + + From 3a3247498797aabb602432850df5854986a89632 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:24:00 -0500 Subject: [PATCH 03/10] Add navigation action OpenSiteMonitoringForSite and handle it --- .../wordpress/android/ui/deeplinks/DeepLinkNavigator.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/DeepLinkNavigator.kt b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/DeepLinkNavigator.kt index 58b2598d1c40..470f6f149669 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/DeepLinkNavigator.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/DeepLinkNavigator.kt @@ -27,6 +27,7 @@ import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.ShowS import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.StartCreateSiteFlow import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.ViewPostInReader import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource.DEEP_LINK +import org.wordpress.android.ui.sitemonitor.SiteMonitorType import org.wordpress.android.ui.stats.StatsTimeframe import org.wordpress.android.util.UriWrapper import javax.inject.Inject @@ -91,6 +92,11 @@ class DeepLinkNavigator navigateAction.site ) NavigateAction.DomainManagement -> ActivityLauncher.openDomainManagement(activity) + is NavigateAction.OpenSiteMonitoringForSite -> activityNavigator.openSiteMonitoringInNewStack( + activity, + navigateAction.site, + navigateAction.siteMonitorType + ) } if (navigateAction != LoginForResult) { activity.finish() @@ -126,5 +132,7 @@ class DeepLinkNavigator object OpenMedia : NavigateAction() data class OpenMediaPickerForSite(val site: SiteModel) : NavigateAction() object DomainManagement : NavigateAction() + data class OpenSiteMonitoringForSite(val site: SiteModel?, val siteMonitorType: SiteMonitorType) : + NavigateAction() } } From ac734290bb569751c83d450367f7427df585c5bd Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:24:27 -0500 Subject: [PATCH 04/10] Add helper for open site monitoring in a new stack from app link --- .../wordpress/android/ui/ActivityNavigator.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt index b37b30457c37..f4966505789d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt @@ -28,6 +28,7 @@ import org.wordpress.android.ui.mysite.menu.MenuActivity import org.wordpress.android.ui.mysite.personalization.PersonalizationActivity import org.wordpress.android.ui.quickstart.QuickStartEvent import org.wordpress.android.ui.sitemonitor.SiteMonitorParentActivity +import org.wordpress.android.ui.sitemonitor.SiteMonitorType import org.wordpress.android.util.ToastUtils import org.wordpress.android.util.analytics.AnalyticsUtils import javax.inject.Inject @@ -163,5 +164,23 @@ class ActivityNavigator @Inject constructor() { intent.putExtra(WordPress.SITE, site) context.startActivity(intent) } + + fun openSiteMonitoringInNewStack(context: Context, site: SiteModel?, siteMonitorType: SiteMonitorType = SiteMonitorType.METRICS) { + if (site == null) { + ToastUtils.showToast(context, R.string.site_monitoring_cannot_be_started, ToastUtils.Duration.SHORT) + return + } + val props = mutableMapOf("site_monitoring_type" to siteMonitorType.name as Any) + AnalyticsUtils.trackWithSiteDetails(AnalyticsTracker.Stat.OPENED_SITE_MONITORING, site, props) + val taskStackBuilder = TaskStackBuilder.create(context) + val mainActivityIntent = getMainActivityInNewStack(context) + val intent = Intent(context, SiteMonitorParentActivity::class.java) + intent.putExtra(WordPress.SITE, site) + intent.putExtra(SiteMonitorParentActivity.ARG_SITE_MONITOR_TYPE_KEY, siteMonitorType) + taskStackBuilder + .addNextIntent(mainActivityIntent) + .addNextIntent(intent) + .startActivities() + } } From 7650adecb8eb304ac34e53cc0d91964f259fa11c Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:24:55 -0500 Subject: [PATCH 05/10] Add resource for when site monitoring can not be app linked into --- WordPress/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index d35b92bd2664..4fe2da0ac0f0 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -4857,4 +4857,5 @@ translators: %s: Select control option value e.g: "Auto, 25%". --> Metrics PHP Logs Web Server Logs + We cannot open site monitoring at the moment. Please try again later From 82e3f7cf39c3622a91cf0cba391ea02eda34e3e0 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:25:30 -0500 Subject: [PATCH 06/10] Add the site monitor app link handler --- .../handlers/SiteMonitorLinkHandler.kt | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt new file mode 100644 index 000000000000..b5f329353399 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt @@ -0,0 +1,60 @@ +package org.wordpress.android.ui.deeplinks.handlers + +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.deeplinks.DeepLinkNavigator +import org.wordpress.android.ui.deeplinks.DeepLinkUriUtils +import org.wordpress.android.ui.deeplinks.DeepLinkingIntentReceiverViewModel +import org.wordpress.android.ui.sitemonitor.SiteMonitorType +import org.wordpress.android.util.UriWrapper +import javax.inject.Inject + +class SiteMonitorLinkHandler +@Inject constructor(private val deepLinkUriUtils: DeepLinkUriUtils) : DeepLinkHandler { + /** + * Returns true if the URI looks like `wordpress.com/SITE_MONITORING_PATH` + */ + override fun shouldHandleUrl(uri: UriWrapper): Boolean { + return (uri.host == DeepLinkingIntentReceiverViewModel.HOST_WORDPRESS_COM && + uri.pathSegments.firstOrNull() == SITE_MONITORING_PATH) || uri.host == SITE_MONITORING_PATH + } + + override fun buildNavigateAction(uri: UriWrapper): DeepLinkNavigator.NavigateAction { + val targetHost = uri.pathSegments[1] + val site: SiteModel? = deepLinkUriUtils.hostToSite(targetHost) + val siteMonitorType = urlToType(uri.toString()) + return DeepLinkNavigator.NavigateAction.OpenSiteMonitoringForSite(site, siteMonitorType) + } + + override fun stripUrl(uri: UriWrapper): String { + return buildString { + val offset = if (uri.host == SITE_MONITORING_PATH) { + append(DeepLinkingIntentReceiverViewModel.APPLINK_SCHEME) + 0 + } else { + append("${DeepLinkingIntentReceiverViewModel.HOST_WORDPRESS_COM}/") + 1 + } + append(SITE_MONITORING_PATH) + val pathSegments = uri.pathSegments + val size = pathSegments.size + val hasSiteUrl = if (size > offset + 1) pathSegments.getOrNull(offset + 1) != null else false + if (hasSiteUrl) { + append("/${DeepLinkingIntentReceiverViewModel.SITE_DOMAIN}") + } + } + } + + private fun urlToType(url: String): SiteMonitorType { + return when { + url.contains(PHP_LOGS_PATTERN) -> SiteMonitorType.PHP_LOGS + url.contains(WEB_SERVER_LOGS_PATTERN) -> SiteMonitorType.WEB_SERVER_LOGS + else -> SiteMonitorType.METRICS + } + } + + companion object { + private const val SITE_MONITORING_PATH = "site-monitoring" + private const val PHP_LOGS_PATTERN = "/php" + private const val WEB_SERVER_LOGS_PATTERN = "/web" + } +} From 64b557993ee0e95918ea09d28b953bfbe7a8d95f Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:26:11 -0500 Subject: [PATCH 07/10] Add the siteMonitorLinkHandler to the list of deepLinkHandlers and update unit test --- .../android/ui/deeplinks/handlers/DeepLinkHandlers.kt | 2 ++ .../android/ui/deeplinks/handlers/DeepLinkHandlersTest.kt | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlers.kt b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlers.kt index c089152827a4..3f7313f563c3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlers.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlers.kt @@ -20,6 +20,7 @@ class DeepLinkHandlers mediaLinkHandler: MediaLinkHandler, domainManagementLinkHandler: DomainManagementLinkHandler, qrCodeMediaLinkHandler: QRCodeMediaLinkHandler, + siteMonitorLinkHandler: SiteMonitorLinkHandler ) { private val handlers = listOf( editorLinkHandler, @@ -33,6 +34,7 @@ class DeepLinkHandlers mediaLinkHandler, domainManagementLinkHandler, qrCodeMediaLinkHandler, + siteMonitorLinkHandler ) private val _toast by lazy { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlersTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlersTest.kt index 224de052cc95..c8aaff5ea24d 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlersTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/deeplinks/handlers/DeepLinkHandlersTest.kt @@ -48,6 +48,9 @@ class DeepLinkHandlersTest : BaseUnitTest() { @Mock lateinit var qrCodeMediaLinkHandler: QRCodeMediaLinkHandler + @Mock + lateinit var siteMonitorLinkHandler: SiteMonitorLinkHandler + @Mock lateinit var uri: UriWrapper private lateinit var deepLinkHandlers: DeepLinkHandlers @@ -67,6 +70,7 @@ class DeepLinkHandlersTest : BaseUnitTest() { mediaLinkHandler, domainManagementLinkHandler, qrCodeMediaLinkHandler, + siteMonitorLinkHandler ) initDeepLinkHandlers() } @@ -84,6 +88,7 @@ class DeepLinkHandlersTest : BaseUnitTest() { mediaLinkHandler, domainManagementLinkHandler, qrCodeMediaLinkHandler, + siteMonitorLinkHandler ) } From 32818303b0a488e6e369d5f678ae94bf79647338 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:27:52 -0500 Subject: [PATCH 08/10] Refactor: add support for passing the siteMonitorType when coming from a app link scenario. --- .../ui/sitemonitor/SiteMonitorParentActivity.kt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitemonitor/SiteMonitorParentActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitemonitor/SiteMonitorParentActivity.kt index 7291b52263ab..c2118117baf2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/sitemonitor/SiteMonitorParentActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/sitemonitor/SiteMonitorParentActivity.kt @@ -65,7 +65,13 @@ class SiteMonitorParentActivity: AppCompatActivity() { return requireNotNull(intent.getSerializableExtraCompat(WordPress.SITE)) as SiteModel } + private fun getInitialTab(): SiteMonitorType { + return intent?.getSerializableExtraCompat(ARG_SITE_MONITOR_TYPE_KEY) as SiteMonitorType? + ?: SiteMonitorType.METRICS + } + companion object { + const val ARG_SITE_MONITOR_TYPE_KEY = "ARG_SITE_MONITOR_TYPE_KEY" const val SAVED_STATE_CONTAINER_KEY = "ContainerKey" const val SAVED_STATE_CURRENT_TAB_KEY = "CurrentTabKey" } @@ -90,7 +96,7 @@ class SiteMonitorParentActivity: AppCompatActivity() { SiteMonitorTabNavigation(selectedTab) { selectedTab -> val item = enumValues().find { it.route == selectedTab - } ?: SiteMonitorTabItem.Metrics + } ?: initialItem(getInitialTab()) SiteMonitorFragmentContainer( modifier = Modifier.fillMaxSize(), @@ -104,6 +110,12 @@ class SiteMonitorParentActivity: AppCompatActivity() { } } + private fun initialItem(type: SiteMonitorType): SiteMonitorTabItem { + return enumValues().find { + it.siteMonitorType == type + } ?: SiteMonitorTabItem.Metrics + } + private fun getCommitFunction( fragment : Fragment, tag: String From e81dd062d36ac8864848c84d7d3f84218e3e0e3c Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 14:55:40 -0500 Subject: [PATCH 09/10] Refactor: move extract host into its own method to expand the extraction --- .../ui/deeplinks/handlers/SiteMonitorLinkHandler.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt index b5f329353399..1461d7db8755 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/deeplinks/handlers/SiteMonitorLinkHandler.kt @@ -19,12 +19,17 @@ class SiteMonitorLinkHandler } override fun buildNavigateAction(uri: UriWrapper): DeepLinkNavigator.NavigateAction { - val targetHost = uri.pathSegments[1] + val targetHost = extractHost(uri) val site: SiteModel? = deepLinkUriUtils.hostToSite(targetHost) val siteMonitorType = urlToType(uri.toString()) return DeepLinkNavigator.NavigateAction.OpenSiteMonitoringForSite(site, siteMonitorType) } + private fun extractHost(uri: UriWrapper): String { + if (uri.pathSegments.size <= 1) return "" + return uri.pathSegments[1] + } + override fun stripUrl(uri: UriWrapper): String { return buildString { val offset = if (uri.host == SITE_MONITORING_PATH) { From bc6452d98f3b1d88132d657d2863541ab336cf05 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Mon, 29 Jan 2024 15:59:25 -0500 Subject: [PATCH 10/10] Refactor: address detekt long lines --- .../main/java/org/wordpress/android/ui/ActivityNavigator.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt index f4966505789d..61cb8664470a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt @@ -165,7 +165,11 @@ class ActivityNavigator @Inject constructor() { context.startActivity(intent) } - fun openSiteMonitoringInNewStack(context: Context, site: SiteModel?, siteMonitorType: SiteMonitorType = SiteMonitorType.METRICS) { + fun openSiteMonitoringInNewStack( + context: Context, + site: SiteModel?, + siteMonitorType: SiteMonitorType = SiteMonitorType.METRICS + ) { if (site == null) { ToastUtils.showToast(context, R.string.site_monitoring_cannot_be_started, ToastUtils.Duration.SHORT) return