Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/trunk' into merge/24.8-final-int…
Browse files Browse the repository at this point in the history
…o-trunk
  • Loading branch information
oguzkocer committed May 10, 2024
2 parents 6a48a54 + 8e84068 commit 9eafb3a
Show file tree
Hide file tree
Showing 85 changed files with 1,826 additions and 746 deletions.
3 changes: 2 additions & 1 deletion RELEASE-NOTES.txt
Expand Up @@ -2,7 +2,8 @@

24.9
-----

* [*] [Jetpack-only] Removed Social section from the detail screen of Total Followers card [https://github.com/wordpress-mobile/WordPress-Android/pull/20763]
* [***] [Jetpack-only] Reorganized Stats to include updated Traffic and Insights tabs, along with a newly added Subscribers tab to improve subscriber metrics analysis [https://github.com/wordpress-mobile/WordPress-Android/pull/20756]

24.8
-----
Expand Down
2 changes: 2 additions & 0 deletions WordPress/build.gradle
Expand Up @@ -564,6 +564,8 @@ dependencies {
// Cascade - Compose nested menu
implementation "me.saket.cascade:cascade-compose:2.3.0"

implementation "com.automattic.tracks:crashlogging:$automatticTracksVersion"

// - Flipper
debugImplementation ("com.facebook.flipper:flipper:$flipperVersion") {
exclude group:'org.jetbrains.kotlinx', module:'kotlinx-serialization-json-jvm'
Expand Down
2 changes: 0 additions & 2 deletions WordPress/src/main/AndroidManifest.xml
Expand Up @@ -1148,8 +1148,6 @@
android:label="@string/site_monitoring"
android:theme="@style/WordPress.NoActionBar"/>

<meta-data android:name="io.sentry.traces.activity.enable" android:value="false" />

</application>
<queries>
<intent>
Expand Down
12 changes: 1 addition & 11 deletions WordPress/src/main/java/org/wordpress/android/AppInitializer.kt
Expand Up @@ -283,6 +283,7 @@ class AppInitializer @Inject constructor(
}

fun init() {
crashLogging.initialize()
dispatcher.register(this)
appConfig.init(appScope)

Expand Down Expand Up @@ -432,17 +433,6 @@ class AppInitializer @Inject constructor(
AppLog.enableRecording(false)
AppLog.e(T.UTILS, "Error enabling log file persistence", e)
}
AppLog.addListener { tag, logLevel, message ->
val sb = StringBuffer()
sb.append(logLevel.toString())
.append("/")
.append(AppLog.TAG)
.append("-")
.append(tag.toString())
.append(": ")
.append(message)
crashLogging.recordEvent(sb.toString(), null)
}
}

private fun sanitizeMediaUploadStateForSite() {
Expand Down
Expand Up @@ -7,8 +7,8 @@

public enum PeopleListFilter implements FilterCriteria {
TEAM(R.string.people_dropdown_item_team),
FOLLOWERS(R.string.people_dropdown_item_followers),
EMAIL_FOLLOWERS(R.string.people_dropdown_item_email_followers),
SUBSCRIBERS(R.string.people_dropdown_item_subscribers),
EMAIL_SUBSCRIBERS(R.string.people_dropdown_item_email_subscribers),
VIEWERS(R.string.people_dropdown_item_viewers);

private final int mLabelResId;
Expand Down
Expand Up @@ -29,7 +29,7 @@ public static List<RoleModel> getInviteRoles(SiteStore siteStore, SiteModel site
RoleModel viewerOrFollowerRole = new RoleModel();
// the remote expects "follower" as the role parameter even if the role is "viewer"
viewerOrFollowerRole.setName("follower");
int displayNameRes = siteModel.isPrivate() ? R.string.role_viewer : R.string.role_follower;
int displayNameRes = siteModel.isPrivate() ? R.string.role_viewer : R.string.role_subscriber;
viewerOrFollowerRole.setDisplayName(context.getString(displayNameRes));
inviteRoles.add(viewerOrFollowerRole);
return inviteRoles;
Expand Down
Expand Up @@ -59,7 +59,6 @@
import org.wordpress.android.ui.stats.refresh.lists.InsightsDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.InsightsListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.MonthsListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.SubscribersDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.SubscribersListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.TotalCommentsDetailListViewModel;
import org.wordpress.android.ui.stats.refresh.lists.TotalFollowersDetailListViewModel;
Expand Down Expand Up @@ -199,11 +198,6 @@ abstract class ViewModelModule {
@ViewModelKey(InsightsDetailListViewModel.class)
abstract ViewModel insightsDetailListViewModel(InsightsDetailListViewModel viewModel);

@Binds
@IntoMap
@ViewModelKey(SubscribersDetailListViewModel.class)
abstract ViewModel subscribersDetailListViewModel(SubscribersDetailListViewModel viewModel);

@Binds
@IntoMap
@ViewModelKey(DetailListViewModel.class)
Expand Down
Expand Up @@ -2,11 +2,11 @@ package org.wordpress.android.ui.deeplinks.handlers

import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenJetpackStaticPosterView
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenStats
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenStatsForSite
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenStatsForSiteAndTimeframe
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenStatsForTimeframe
import org.wordpress.android.ui.deeplinks.DeepLinkNavigator.NavigateAction.OpenJetpackStaticPosterView
import org.wordpress.android.ui.deeplinks.DeepLinkUriUtils
import org.wordpress.android.ui.deeplinks.DeepLinkingIntentReceiverViewModel.Companion.APPLINK_SCHEME
import org.wordpress.android.ui.deeplinks.DeepLinkingIntentReceiverViewModel.Companion.HOST_WORDPRESS_COM
Expand All @@ -32,7 +32,8 @@ class StatsLinkHandler
val pathSegments = uri.pathSegments
val length = pathSegments.size
val site = pathSegments.getOrNull(length - 1)?.toSite()
val statsTimeframe = pathSegments.getOrNull(length - 2)?.toStatsTimeframe()
val timeframeIndex = if (site == null) (length - 1) else (length - 2)
val statsTimeframe = pathSegments.getOrNull(timeframeIndex)?.toStatsTimeframe()
return when {
jetpackFeatureRemovalPhaseHelper.shouldShowStaticPage() -> OpenJetpackStaticPosterView
site != null && statsTimeframe != null -> {
Expand Down Expand Up @@ -98,6 +99,7 @@ class StatsLinkHandler
"month" -> StatsTimeframe.MONTH
"year" -> StatsTimeframe.YEAR
"insights" -> StatsTimeframe.INSIGHTS
"subscribers" -> StatsTimeframe.SUBSCRIBERS
else -> null
}
}
Expand Down
@@ -1,5 +1,7 @@
package org.wordpress.android.ui.jetpackoverlay

import org.wordpress.android.analytics.AnalyticsTracker
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseFour
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseNewUsers
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseOne
Expand All @@ -9,7 +11,9 @@ import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseS
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseStaticPosters
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalSiteCreationPhase.PHASE_ONE
import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalSiteCreationPhase.PHASE_TWO
import org.wordpress.android.ui.main.WPMainNavigationView.PageType
import org.wordpress.android.util.BuildConfigWrapper
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import org.wordpress.android.util.config.JetpackFeatureRemovalNewUsersConfig
import org.wordpress.android.util.config.JetpackFeatureRemovalPhaseFourConfig
import org.wordpress.android.util.config.JetpackFeatureRemovalPhaseOneConfig
Expand Down Expand Up @@ -40,7 +44,8 @@ class JetpackFeatureRemovalPhaseHelper @Inject constructor(
private val jetpackFeatureRemovalNewUsersConfig: JetpackFeatureRemovalNewUsersConfig,
private val jetpackFeatureRemovalSelfHostedUsersConfig: JetpackFeatureRemovalSelfHostedUsersConfig,
private val jetpackFeatureRemovalStaticPostersConfig: JetpackFeatureRemovalStaticPostersConfig,
private val jetpackPhaseFourOverlayFrequencyConfig: PhaseFourOverlayFrequencyConfig
private val jetpackPhaseFourOverlayFrequencyConfig: PhaseFourOverlayFrequencyConfig,
private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
) {
fun getCurrentPhase(): JetpackFeatureRemovalPhase? {
return if (buildConfigWrapper.isJetpackApp) null
Expand Down Expand Up @@ -126,6 +131,26 @@ class JetpackFeatureRemovalPhaseHelper @Inject constructor(
}
}

@JvmOverloads
fun trackPageAccessedEventIfNeeded(pageType: PageType, site: SiteModel? = null) {
when (pageType) {
PageType.MY_SITE -> analyticsTrackerWrapper.track(AnalyticsTracker.Stat.MY_SITE_ACCESSED, site)
PageType.READER -> {
if (arePosterizedPagesVisible()) {
analyticsTrackerWrapper.track(AnalyticsTracker.Stat.READER_ACCESSED)
}
}

PageType.NOTIFS -> {
if (arePosterizedPagesVisible()) {
analyticsTrackerWrapper.track(AnalyticsTracker.Stat.NOTIFICATIONS_ACCESSED)
}
}

PageType.ME -> analyticsTrackerWrapper.track(AnalyticsTracker.Stat.ME_ACCESSED)
}
}

fun shouldShowNotifications(): Boolean {
val currentPhase = getCurrentPhase() ?: return true
return when (currentPhase) {
Expand Down Expand Up @@ -153,6 +178,8 @@ class JetpackFeatureRemovalPhaseHelper @Inject constructor(
fun getPhaseFourOverlayFrequency(): Int {
return jetpackPhaseFourOverlayFrequencyConfig.getValue()
}

private fun arePosterizedPagesVisible() = !shouldShowStaticPage()
}
// Global overlay frequency is the frequency at which the overlay is shown across the features
// no matter which feature was accessed last time
Expand Down
Expand Up @@ -1301,19 +1301,19 @@ private void trackLastVisiblePage(@NonNull final PageType pageType) {
switch (pageType) {
case MY_SITE:
ActivityId.trackLastActivity(ActivityId.MY_SITE);
mAnalyticsTrackerWrapper.track(AnalyticsTracker.Stat.MY_SITE_ACCESSED, getSelectedSite());
mJetpackFeatureRemovalPhaseHelper.trackPageAccessedEventIfNeeded(PageType.MY_SITE, getSelectedSite());
break;
case READER:
ActivityId.trackLastActivity(ActivityId.READER);
AnalyticsTracker.track(AnalyticsTracker.Stat.READER_ACCESSED);
mJetpackFeatureRemovalPhaseHelper.trackPageAccessedEventIfNeeded(PageType.READER);
break;
case NOTIFS:
ActivityId.trackLastActivity(ActivityId.NOTIFICATIONS);
AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATIONS_ACCESSED);
mJetpackFeatureRemovalPhaseHelper.trackPageAccessedEventIfNeeded(PageType.NOTIFS);
break;
case ME:
ActivityId.trackLastActivity(ActivityId.ME);
AnalyticsTracker.track(Stat.ME_ACCESSED);
mJetpackFeatureRemovalPhaseHelper.trackPageAccessedEventIfNeeded(PageType.ME);
break;
default:
break;
Expand Down
Expand Up @@ -795,6 +795,10 @@ public void onMediaCapturePathReady(String mediaCapturePath) {
mMediaCapturePath = mediaCapturePath;
}

@Override public void onCameraError(String errorMessage) {
ToastUtils.showToast(this, errorMessage, LONG);
}

private void showMediaToastError(@StringRes int message, @Nullable String messageDetail) {
if (isFinishing()) {
return;
Expand Down
Expand Up @@ -47,6 +47,7 @@ import org.wordpress.android.ui.posts.editor.ImageEditorTracker
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.AppLog.T.MEDIA
import org.wordpress.android.util.ToastUtils
import org.wordpress.android.util.WPMediaUtils
import org.wordpress.android.util.extensions.getSerializableCompat
import org.wordpress.android.util.extensions.getSerializableExtraCompat
Expand Down Expand Up @@ -316,7 +317,23 @@ class MediaPickerActivity : LocaleAwareActivity(), MediaPickerListener {
startActivityForResult(buildIntent(this, action.mediaPickerSetup, site, localPostId), PHOTO_PICKER)
}
OpenCameraForPhotos -> {
WPMediaUtils.launchCamera(this, BuildConfig.APPLICATION_ID) { mediaCapturePath = it }
WPMediaUtils.launchCamera(
this,
BuildConfig.APPLICATION_ID,
object : WPMediaUtils.LaunchCameraCallback {
override fun onMediaCapturePathReady(mediaCapturePath: String?) {
this@MediaPickerActivity.mediaCapturePath = mediaCapturePath
}

override fun onCameraError(errorMessage: String?) {
ToastUtils.showToast(
this@MediaPickerActivity,
errorMessage,
ToastUtils.Duration.SHORT
)
}
}
)
}
}
}
Expand Down
Expand Up @@ -52,9 +52,11 @@ import org.wordpress.android.ui.compose.components.MainTopAppBar
import org.wordpress.android.ui.compose.components.NavigationIcons
import org.wordpress.android.ui.compose.components.buttons.WPSwitch
import org.wordpress.android.ui.compose.theme.AppTheme
import org.wordpress.android.ui.compose.utils.LocaleAwareComposable
import org.wordpress.android.ui.compose.utils.uiStringText
import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.util.LocaleManager

@AndroidEntryPoint
class PersonalizationActivity : AppCompatActivity() {
Expand All @@ -64,8 +66,14 @@ class PersonalizationActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
viewModel.start()
PersonalizationScreen()
val language by viewModel.appLanguage.observeAsState("")

LocaleAwareComposable(
locale = LocaleManager.languageLocale(language),
) {
viewModel.start()
PersonalizationScreen()
}
}
}
viewModel.onSelectedSiteMissing.observe(this) { finish() }
Expand Down Expand Up @@ -193,7 +201,7 @@ class PersonalizationActivity : AppCompatActivity() {
state = shortcutState,
actionIcon = R.drawable.ic_personalization_quick_link_remove_circle,
actionIconTint = Color(0xFFD63638),
actionButtonClick = { viewModel.removeShortcut(shortcutState)}
actionButtonClick = { viewModel.removeShortcut(shortcutState) }
)
}
}
Expand Down
Expand Up @@ -7,6 +7,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineDispatcher
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.ui.mysite.SelectedSiteRepository
import org.wordpress.android.util.LocaleManagerWrapper
import org.wordpress.android.viewmodel.ScopedViewModel
import javax.inject.Inject
import javax.inject.Named
Expand All @@ -18,15 +19,20 @@ class PersonalizationViewModel @Inject constructor(
@param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
private val selectedSiteRepository: SelectedSiteRepository,
private val shortcutsPersonalizationViewModelSlice: ShortcutsPersonalizationViewModelSlice,
private val dashboardCardPersonalizationViewModelSlice: DashboardCardPersonalizationViewModelSlice
private val dashboardCardPersonalizationViewModelSlice: DashboardCardPersonalizationViewModelSlice,
private val localeManagerWrapper: LocaleManagerWrapper
) : ScopedViewModel(bgDispatcher) {
val uiState = dashboardCardPersonalizationViewModelSlice.uiState
val shortcutsState = shortcutsPersonalizationViewModelSlice.uiState

private val _onSelectedSiteMissing = MutableLiveData<Unit>()
val onSelectedSiteMissing = _onSelectedSiteMissing as LiveData<Unit>

private val _appLanguage = MutableLiveData<String>()
val appLanguage = _appLanguage as LiveData<String>

init {
emitLanguageRefreshIfNeeded(localeManagerWrapper.getLanguage())
shortcutsPersonalizationViewModelSlice.initialize(viewModelScope)
dashboardCardPersonalizationViewModelSlice.initialize(viewModelScope)
}
Expand Down Expand Up @@ -61,4 +67,13 @@ class PersonalizationViewModel @Inject constructor(
val siteId = selectedSiteRepository.getSelectedSite()!!.siteId
shortcutsPersonalizationViewModelSlice.addShortcut(shortcutState,siteId)
}

private fun emitLanguageRefreshIfNeeded(languageCode: String) {
if (languageCode.isNotEmpty()) {
val shouldEmitLanguageRefresh = !localeManagerWrapper.isSameLanguage(languageCode)
if (shouldEmitLanguageRefresh) {
_appLanguage.value = languageCode
}
}
}
}
Expand Up @@ -347,7 +347,7 @@ private void setActionBarTitleForNote(Note note) {
// set a default title if title is not set within the note
switch (note.getRawType()) {
case NOTE_FOLLOW_TYPE:
title = getString(R.string.follows);
title = getString(R.string.subscribers);
break;
case NOTE_COMMENT_LIKE_TYPE:
title = getString(R.string.comment_likes);
Expand Down
Expand Up @@ -334,7 +334,7 @@ class NotificationsListFragment : Fragment(R.layout.notifications_list_fragment)
All(R.string.notifications_tab_title_all, Filter.ALL),
Unread(R.string.notifications_tab_title_unread_notifications, Filter.UNREAD),
Comment(R.string.notifications_tab_title_comments, Filter.COMMENT),
Follow(R.string.notifications_tab_title_follows, Filter.FOLLOW),
Subscribers(R.string.notifications_tab_title_subscribers, Filter.FOLLOW),
Like(R.string.notifications_tab_title_likes, Filter.LIKE);
}

Expand Down
Expand Up @@ -53,7 +53,7 @@ import org.wordpress.android.ui.notifications.NotificationEvents.OnNoteCommentLi
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.All
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Comment
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Follow
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Subscribers
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Like
import org.wordpress.android.ui.notifications.NotificationsListFragment.Companion.TabPosition.Unread
import org.wordpress.android.ui.notifications.NotificationsListViewModel.InlineActionEvent
Expand Down Expand Up @@ -364,8 +364,8 @@ class NotificationsListFragmentPage : ViewPagerFragment(R.layout.notifications_l
descriptionResId = R.string.notifications_empty_action_comments
buttonResId = R.string.notifications_empty_view_reader
}
Follow.ordinal -> {
titleResId = R.string.notifications_empty_followers
Subscribers.ordinal -> {
titleResId = R.string.notifications_empty_subscribers
descriptionResId = R.string.notifications_empty_action_followers_likes
buttonResId = R.string.notifications_empty_view_reader
}
Expand Down
Expand Up @@ -533,8 +533,8 @@ String getValidationErrorString(String username, ValidationResult validationResu
return getString(R.string.invite_username_not_found, username);
case ALREADY_MEMBER:
return getString(R.string.invite_already_a_member, username);
case ALREADY_FOLLOWING:
return getString(R.string.invite_already_following, username);
case ALREADY_SUBSCRIBED:
return getString(R.string.invite_already_subscribed, username);
case BLOCKED_INVITES:
return getString(R.string.invite_user_blocked_invites, username);
case INVALID_EMAIL:
Expand Down

0 comments on commit 9eafb3a

Please sign in to comment.