Skip to content

Commit

Permalink
Merge branch 'trunk' into 12565-woo-pos-we-dont-handle-the-low-batter…
Browse files Browse the repository at this point in the history
…y-event-during-ipp-flow-properly
  • Loading branch information
backwardstruck authored Sep 23, 2024
2 parents 859e329 + 56404b5 commit afcb619
Show file tree
Hide file tree
Showing 62 changed files with 1,843 additions and 1,316 deletions.
2 changes: 1 addition & 1 deletion .buildkite/commands/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if [ $app_lint_exit_code -ne 0 ] || [ $wear_lint_exit_code -ne 0 ]; then
lint_exit_code=1
fi

upload_sarif_to_github 'WooCommerce/build/reports/lint-results-jalapenoDebug.sarif' 'woocommerce' 'woocommerce-android'
upload_sarif_to_github 'WooCommerce/build/reports/lint-results-jalapenoDebug.sarif'

exit $lint_exit_code
2 changes: 1 addition & 1 deletion .buildkite/shared-pipeline-vars
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
# This file is `source`'d before calling `buildkite-agent pipeline upload`, and can be used
# to set up some variables that will be interpolated in the `.yml` pipeline before uploading it.

export CI_TOOLKIT="automattic/a8c-ci-toolkit#3.6.2"
export CI_TOOLKIT="automattic/a8c-ci-toolkit#3.7.1"
export TEST_COLLECTOR="test-collector#v1.10.1"

3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<!--
Contains editorialized release notes. Raw release notes should go into `RELEASE-NOTES.txt`.
-->
## 20.5
We’re excited to bring you a smoother experience with our latest update! We've resolved an issue that prevented renaming Product Variation Attributes and fixed a bug related to notification removal. Plus, users can now easily select product images when creating Blaze ads, and the Blaze feature is now fully enabled for sites with the Blaze for WooCommerce plugin active. Enjoy the improvements!

## 20.4
We've enhanced your WooCommerce app experience! You can now effortlessly scan tracking numbers when adding them to orders. Plus, we've fixed an issue with shipping labels, ensuring accurate weight calculations for packages with multiple items. Enjoy a smoother, more reliable app experience!

Expand Down
7 changes: 7 additions & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@
*** Use [*****] to indicate smoke tests of all critical flows should be run on the final APK before release (e.g. major library or targetSdk updates).
*** For entries which are touching the Android Wear app's, start entry with `[WEAR]` too.

20.6
-----


20.5
-----
- [*] Fixes a bug that prevented users to rename the Product Variation Attributes to because of case insensitive checks [https://github.com/woocommerce/woocommerce-android/pull/12608]
- [*] Users can directly pick product images when creating Blaze ads [https://github.com/woocommerce/woocommerce-android/pull/12610]
- [*] Enables Blaze feature for sites with Blaze for WooCommerce plugin installed and active [https://github.com/woocommerce/woocommerce-android/pull/12640]
- [*] Fix for ConcurrentModificationException while removing notification [https://github.com/woocommerce/woocommerce-android/pull/12646]

20.4
-----
- [**] Users can now scan their tracking number when adding it to the order [https://github.com/woocommerce/woocommerce-android/pull/12533]
- [*] Fixed an issue where shipping labels were incorrectly calculating the weight for packages containing multiple quantities of the same product [https://github.com/woocommerce/woocommerce-android/pull/12602]
- [**] [WEAR] Introduces three new complications for the Wear app: Orders Total, Orders Count, and Visitors [https://github.com/woocommerce/woocommerce-android/pull/12558]

20.3
-----
Expand Down
1 change: 1 addition & 0 deletions WooCommerce-Wear/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ dependencies {
// See https://github.com/wordpress-mobile/WordPress-FluxC-Android/issues/919
exclude group: 'com.squareup.okhttp3'
}
lintChecks "com.android.security.lint:lint:$securityLintVersion"
}

def checkGradlePropertiesFile() {
Expand Down
1 change: 1 addition & 0 deletions WooCommerce-Wear/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
android:name=".app.WearMainActivity"
android:exported="true"
android:taskAffinity=""
android:configChanges="density|fontScale|keyboard|keyboardHidden|layoutDirection|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
android:theme="@style/MainActivityTheme.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
2 changes: 1 addition & 1 deletion WooCommerce-Wear/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<!-- Login Screen -->
<string name="login_screen_loading_text">Connecting</string>
<string name="login_screen_error_title">Log in</string>
<string name="login_screen_error_caption">Log in to Woo on your phone and hold your Watch nearby</string>
<string name="login_screen_error_caption">Log in to Woo on your phone and hold it nearby</string>
<string name="login_screen_action_button">It\'s not working</string>

<!-- Stats Screen -->
Expand Down
2 changes: 1 addition & 1 deletion WooCommerce-Wear/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<style name="MainActivityTheme.Starting" parent="Theme.SplashScreen">
<item name="windowSplashScreenBackground">@color/splash_background</item>
<item name="windowSplashScreenAnimatedIcon">@drawable/img_woo_bubble_white_animated</item>
<item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher</item>
<item name="postSplashScreenTheme">@android:style/Theme.DeviceDefault</item>
</style>
</resources>
2 changes: 2 additions & 0 deletions WooCommerce/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ dependencies {
implementation "com.google.guava:guava:$guavaVersion"

implementation "com.google.protobuf:protobuf-javalite:$protobufVersion"

lintChecks "com.android.security.lint:lint:$securityLintVersion"
}

protobuf {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.woocommerce.android.e2e.screens.TabNavComponent
import com.woocommerce.android.model.Notification
import com.woocommerce.android.notifications.NotificationChannelType
import com.woocommerce.android.notifications.WooNotificationBuilder
import com.woocommerce.android.notifications.WooNotificationType.NEW_ORDER
import com.woocommerce.android.notifications.WooNotificationType.NewOrder

/**
* This is not a screen per-se, as it shows the notification drawer with a push notification.
Expand All @@ -32,7 +32,7 @@ class NotificationsScreen(private val wooNotificationBuilder: WooNotificationBui
icon = "https://s.wp.com/wp-content/mu-plugins/notes/images/update-payment-2x.png",
noteTitle = getTranslatedString(R.string.tests_notification_new_order_title),
noteMessage = getTranslatedString(R.string.tests_notification_new_order_message),
noteType = NEW_ORDER,
noteType = NewOrder,
channelType = NotificationChannelType.NEW_ORDER
),
isGroupNotification = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,13 @@ data class Notification(
val data: String? = null
) : Parcelable {
@IgnoredOnParcel
val isOrderNotification = noteType == WooNotificationType.NEW_ORDER
val isOrderNotification = noteType is WooNotificationType.NewOrder

@IgnoredOnParcel
val isReviewNotification = noteType == WooNotificationType.PRODUCT_REVIEW
val isReviewNotification = noteType is WooNotificationType.ProductReview

@IgnoredOnParcel
val isBlazeNotification = noteType == WooNotificationType.BLAZE_APPROVED_NOTE ||
noteType == WooNotificationType.BLAZE_REJECTED_NOTE ||
noteType == WooNotificationType.BLAZE_CANCELLED_NOTE ||
noteType == WooNotificationType.BLAZE_PERFORMED_NOTE
val isBlazeNotification = noteType is WooNotificationType.BlazeStatusUpdate

/**
* Notifications are grouped based on the notification type and the store the notification belongs to.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
package com.woocommerce.android.notifications

import android.os.Parcelable
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.wordpress.android.fluxc.model.notification.NotificationModel

enum class WooNotificationType {
NEW_ORDER,
PRODUCT_REVIEW,
LOCAL_REMINDER,
BLAZE_APPROVED_NOTE,
BLAZE_REJECTED_NOTE,
BLAZE_CANCELLED_NOTE,
BLAZE_PERFORMED_NOTE,
sealed interface WooNotificationType : Parcelable {
val trackingValue: String

@Parcelize
data object NewOrder : WooNotificationType {
@IgnoredOnParcel override val trackingValue: String = "NEW_ORDER"
}

@Parcelize
data object ProductReview : WooNotificationType {
@IgnoredOnParcel override val trackingValue: String = "PRODUCT_REVIEW"
}

@Parcelize
data object LocalReminder : WooNotificationType {
@IgnoredOnParcel override val trackingValue: String = "LOCAL_REMINDER"
}

@Parcelize
sealed interface BlazeStatusUpdate : WooNotificationType, Parcelable {
@Parcelize
data object BlazeApprovedNote : BlazeStatusUpdate {
@IgnoredOnParcel override val trackingValue: String = "blaze_approved_note"
}

@Parcelize
data object BlazeRejectedNote : BlazeStatusUpdate {
@IgnoredOnParcel override val trackingValue: String = "blaze_rejected_note"
}

@Parcelize
data object BlazeCancelledNote : BlazeStatusUpdate {
@IgnoredOnParcel override val trackingValue: String = "blaze_cancelled_note"
}

@Parcelize
data object BlazePerformedNote : BlazeStatusUpdate {
@IgnoredOnParcel override val trackingValue: String = "blaze_performed_note"
}
}
}

fun NotificationModel.getWooType(): WooNotificationType {
return when (this.type) {
NotificationModel.Kind.STORE_ORDER -> WooNotificationType.NEW_ORDER
NotificationModel.Kind.COMMENT -> WooNotificationType.PRODUCT_REVIEW
NotificationModel.Kind.BLAZE_APPROVED_NOTE -> WooNotificationType.BLAZE_APPROVED_NOTE
NotificationModel.Kind.BLAZE_REJECTED_NOTE -> WooNotificationType.BLAZE_REJECTED_NOTE
NotificationModel.Kind.BLAZE_CANCELLED_NOTE -> WooNotificationType.BLAZE_CANCELLED_NOTE
NotificationModel.Kind.BLAZE_PERFORMED_NOTE -> WooNotificationType.BLAZE_PERFORMED_NOTE
else -> WooNotificationType.LOCAL_REMINDER
NotificationModel.Kind.STORE_ORDER -> WooNotificationType.NewOrder
NotificationModel.Kind.COMMENT -> WooNotificationType.ProductReview
NotificationModel.Kind.BLAZE_APPROVED_NOTE -> WooNotificationType.BlazeStatusUpdate.BlazeApprovedNote
NotificationModel.Kind.BLAZE_REJECTED_NOTE -> WooNotificationType.BlazeStatusUpdate.BlazeRejectedNote
NotificationModel.Kind.BLAZE_CANCELLED_NOTE -> WooNotificationType.BlazeStatusUpdate.BlazeCancelledNote
NotificationModel.Kind.BLAZE_PERFORMED_NOTE -> WooNotificationType.BlazeStatusUpdate.BlazePerformedNote
else -> WooNotificationType.LocalReminder
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.woocommerce.android.analytics.AnalyticsTracker
import com.woocommerce.android.model.Notification
import com.woocommerce.android.notifications.NotificationChannelType.OTHER
import com.woocommerce.android.notifications.WooNotificationBuilder
import com.woocommerce.android.notifications.WooNotificationType.LOCAL_REMINDER
import com.woocommerce.android.notifications.WooNotificationType.LocalReminder
import com.woocommerce.android.notifications.local.LocalNotificationScheduler.Companion.LOCAL_NOTIFICATION_DATA
import com.woocommerce.android.notifications.local.LocalNotificationScheduler.Companion.LOCAL_NOTIFICATION_DESC
import com.woocommerce.android.notifications.local.LocalNotificationScheduler.Companion.LOCAL_NOTIFICATION_ID
Expand Down Expand Up @@ -103,7 +103,7 @@ class LocalNotificationWorker @AssistedInject constructor(
icon = null,
noteTitle = title,
noteMessage = description,
noteType = LOCAL_REMINDER,
noteType = LocalReminder,
channelType = OTHER,
data = data
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class NotificationAnalyticsTracker @Inject constructor(
val isFromSelectedSite = selectedSite.getIfExists()?.siteId == notification.remoteSiteId
val properties = mutableMapOf<String, Any>()
properties["notification_note_id"] = notification.remoteNoteId
properties["notification_type"] = notification.noteType.name
properties["notification_type"] = notification.noteType.trackingValue
properties["push_notification_token"] = appPrefsWrapper.getFCMToken()
properties["is_from_selected_site"] = isFromSelectedSite == true
analyticsTrackerWrapper.track(stat, properties)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.woocommerce.android.model.isOrderNotification
import com.woocommerce.android.model.toAppModel
import com.woocommerce.android.notifications.NotificationChannelType
import com.woocommerce.android.notifications.WooNotificationBuilder
import com.woocommerce.android.notifications.WooNotificationType.NEW_ORDER
import com.woocommerce.android.notifications.WooNotificationType.NewOrder
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.util.NotificationsParser
import com.woocommerce.android.util.WooLog.T.NOTIFS
Expand Down Expand Up @@ -52,10 +52,12 @@ class NotificationMessageHandler @Inject constructor(
private val ACTIVE_NOTIFICATIONS_MAP = mutableMapOf<Int, Notification>()
}

@Synchronized
fun onPushNotificationDismissed(notificationId: Int) {
removeNotificationByNotificationIdFromSystemsBar(notificationId)
}

@Synchronized
fun onLocalNotificationDismissed(notificationId: Int, notificationType: String) {
removeNotificationByNotificationIdFromSystemsBar(notificationId)
AnalyticsTracker.track(
Expand Down Expand Up @@ -128,7 +130,7 @@ class NotificationMessageHandler @Inject constructor(
}

private fun handleWooNotification(notification: Notification) {
val randomNumber = if (notification.noteType == NEW_ORDER) Random.nextInt() else 0
val randomNumber = if (notification.noteType == NewOrder) Random.nextInt() else 0
val localPushId = getLocalPushIdForNoteId(notification.remoteNoteId, randomNumber)
ACTIVE_NOTIFICATIONS_MAP[getLocalPushId(localPushId, randomNumber)] = notification
if (notificationBuilder.isNotificationsEnabled()) {
Expand Down Expand Up @@ -221,6 +223,7 @@ class NotificationMessageHandler @Inject constructor(
notificationBuilder.cancelAllNotifications()
}

@Synchronized
fun removeNotificationByRemoteIdFromSystemsBar(remoteNoteId: Long) {
val keptNotifs = HashMap<Int, Notification>()
ACTIVE_NOTIFICATIONS_MAP.asSequence()
Expand All @@ -237,6 +240,7 @@ class NotificationMessageHandler @Inject constructor(
updateNotificationsState()
}

@Synchronized
fun removeNotificationByNotificationIdFromSystemsBar(localPushId: Int) {
val keptNotifs = HashMap<Int, Notification>()
ACTIVE_NOTIFICATIONS_MAP.asSequence()
Expand All @@ -253,6 +257,7 @@ class NotificationMessageHandler @Inject constructor(
updateNotificationsState()
}

@Synchronized
fun removeNotificationsOfTypeFromSystemsBar(type: NotificationChannelType, remoteSiteId: Long) {
val keptNotifs = HashMap<Int, Notification>()
// Using a copy of the map to avoid concurrency problems
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,30 @@ class BlazeRepository @Inject constructor(
const val WEEKLY_DURATION = 7 // Used to calculate weekly budget in endless campaigns
}

fun observeObjectives() = blazeCampaignsStore.observeBlazeCampaignObjectives().map {
it.map { objective ->
Objective(
objective.id,
objective.title,
objective.description,
objective.suitableForDescription
)
}
}

suspend fun fetchObjectives(): Result<Unit> {
val result = blazeCampaignsStore.fetchBlazeCampaignObjectives(selectedSite.get())

return when {
result.isError -> {
WooLog.w(WooLog.T.BLAZE, "Failed to fetch objectives: ${result.error}")
Result.failure(OnChangedException(result.error))
}

else -> Result.success(Unit)
}
}

fun observeLanguages() = blazeCampaignsStore.observeBlazeTargetingLanguages()
.map { it.map { language -> Language(language.id, language.name) } }

Expand Down Expand Up @@ -378,6 +402,14 @@ class BlazeRepository @Inject constructor(
data class RemoteImage(val mediaId: Long, override val uri: String) : BlazeCampaignImage
}

@Parcelize
data class Objective(
val id: String,
val title: String,
val description: String,
val suitableForDescription: String
) : Parcelable

@Parcelize
data class TargetingParameters(
val locations: List<Location> = emptyList(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
package com.woocommerce.android.ui.blaze

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.tools.SiteConnectionType
import com.woocommerce.android.tools.SiteConnectionType.Jetpack
import com.woocommerce.android.util.IsRemoteFeatureFlagEnabled
import com.woocommerce.android.util.RemoteFeatureFlag.WOO_BLAZE
import javax.inject.Inject

class IsBlazeEnabled @Inject constructor(
private val selectedSite: SelectedSite,
private val isRemoteFeatureFlagEnabled: IsRemoteFeatureFlagEnabled,
private val isRemoteFeatureFlagEnabled: IsRemoteFeatureFlagEnabled
) {
companion object {
private const val BLAZE_FOR_WOOCOMMERCE_PLUGIN_SLUG = "blaze-ads"
}

suspend operator fun invoke(): Boolean = selectedSite.getIfExists()?.isAdmin ?: false &&
selectedSite.connectionType == SiteConnectionType.Jetpack &&
hasAValidJetpackConnectionForBlaze() &&
selectedSite.getIfExists()?.canBlaze ?: false &&
isRemoteFeatureFlagEnabled(WOO_BLAZE)

/**
* In order for Blaze to work, the site requires the Jetpack Sync module to be enabled. This means not all
* Jetpack connection will work. For now, Blaze will only be enabled for sites with Jetpack plugin installed and
* active, or for sites with Blaze for WooCommerce plugin installed and connected.
*/
private fun hasAValidJetpackConnectionForBlaze() =
selectedSite.connectionType == Jetpack || isBlazeForWooCommercePluginActive()

private fun isBlazeForWooCommercePluginActive(): Boolean =
selectedSite.get().activeJetpackConnectionPlugins?.contains(BLAZE_FOR_WOOCOMMERCE_PLUGIN_SLUG) == true
}
Loading

0 comments on commit afcb619

Please sign in to comment.