diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3588c1f76b32..054e8f9e47a5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -163,6 +163,7 @@ dependencies { // Crash analytics implementation("io.sentry:sentry-android:4.3.0") + implementation("org.matomo.sdk:tracker:4.1.2") // ShowCaseView dependency implementation("com.github.mreram:showcaseview:1.0.5") @@ -286,6 +287,7 @@ android { buildConfigField("String", "OFWEBSITE", "\"https://world.openfoodfacts.org/\"") buildConfigField("String", "WIKIDATA", "\"https://www.wikidata.org/wiki/Special:EntityData/\"") buildConfigField("String", "STATICURL", "\"https://static.openfoodfacts.org\"") + buildConfigField("String", "MATOMO_URL", "\"https://analytics.openfoodfacts.org/piwik.php\"") dimension = "versionCode" } create("obf") { @@ -297,6 +299,7 @@ android { buildConfigField("String", "OFWEBSITE", "\"https://world.openbeautyfacts.org/\"") buildConfigField("String", "WIKIDATA", "\"https://www.wikidata.org/wiki/Special:EntityData/\"") buildConfigField("String", "STATICURL", "\"https://static.openbeautyfacts.org\"") + buildConfigField("String", "MATOMO_URL", "\"https://analytics.openfoodfacts.org/piwik.php\"") dimension = "versionCode" } create("opff") { @@ -308,6 +311,7 @@ android { buildConfigField("String", "OFWEBSITE", "\"https://world.openpetfoodfacts.org/\"") buildConfigField("String", "WIKIDATA", "\"https://www.wikidata.org/wiki/Special:EntityData/\"") buildConfigField("String", "STATICURL", "\"https://static.openpetfoodfacts.org\"") + buildConfigField("String", "MATOMO_URL", "\"https://analytics.openfoodfacts.org/piwik.php\"") dimension = "versionCode" } create("opf") { @@ -319,6 +323,7 @@ android { buildConfigField("String", "OFWEBSITE", "\"https://world.openproductsfacts.org/\"") buildConfigField("String", "WIKIDATA", "\"https://www.wikidata.org/wiki/Special:EntityData/\"") buildConfigField("String", "STATICURL", "\"https://static.openproductsfacts.org\"") + buildConfigField("String", "MATOMO_URL", "\"https://analytics.openfoodfacts.org/piwik.php\"") dimension = "versionCode" } create("playstore") { diff --git a/app/src/fdroid/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt b/app/src/fdroid/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt index fb877c908749..37cf225020b6 100644 --- a/app/src/fdroid/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt +++ b/app/src/fdroid/java/openfoodfacts/github/scrachx/openfood/features/scan/ContinuousScanActivity.kt @@ -58,6 +58,10 @@ import io.reactivex.schedulers.Schedulers import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.databinding.ActivityContinuousScanBinding import openfoodfacts.github.scrachx.openfood.features.ImagesManageActivity import openfoodfacts.github.scrachx.openfood.features.compare.ProductCompareActivity @@ -112,6 +116,9 @@ class ContinuousScanActivity : AppCompatActivity() { @Inject lateinit var daoSession: DaoSession + @Inject + lateinit var productRepository: ProductRepository + private val cameraPref by lazy { getSharedPreferences("camera", 0) } private val commonDisp = CompositeDisposable() @@ -226,6 +233,7 @@ class ContinuousScanActivity : AppCompatActivity() { putExtra(ProductCompareActivity.KEY_PRODUCT_ALREADY_EXISTS, true) } else { productsToCompare += product + MatomoAnalytics.trackEvent(AnalyticsEvent.AddProductToComparison(product.code)) } putExtra(ProductCompareActivity.KEY_PRODUCTS_TO_COMPARE, productsToCompare) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) @@ -362,9 +370,6 @@ class ContinuousScanActivity : AppCompatActivity() { } } - @Inject - lateinit var productRepository: ProductRepository - private fun showProductNotFound(text: String) { hideAllViews() quickViewBehavior.state = BottomSheetBehavior.STATE_COLLAPSED @@ -519,6 +524,7 @@ class ContinuousScanActivity : AppCompatActivity() { if (quickViewBehavior.state != BottomSheetBehavior.STATE_EXPANDED) { binding.barcodeScanner.resume() } + MatomoAnalytics.trackView(AnalyticsView.Scanner) } override fun onSaveInstanceState(outState: Bundle) { @@ -711,10 +717,12 @@ class ContinuousScanActivity : AppCompatActivity() { lastBarcode = null binding.txtProductCallToAction.visibility = View.GONE } - else -> { - binding.barcodeScanner.pause() - } + BottomSheetBehavior.STATE_EXPANDED -> { + binding.barcodeScanner.pause() + MatomoAnalytics.trackEvent(AnalyticsEvent.ScannedBarcodeResultExpanded(lastBarcode)) } + else -> binding.barcodeScanner.pause() + } if (binding.quickViewSearchByBarcode.visibility == View.VISIBLE) { @@ -796,7 +804,11 @@ class ContinuousScanActivity : AppCompatActivity() { if (beepActive) { beepManager.playBeepSound() } - lastBarcode = result.text.also { if (!isFinishing) setShownProduct(it) } + lastBarcode = result.text + if (!isFinishing) { + setShownProduct(result.text) + MatomoAnalytics.trackEvent(AnalyticsEvent.ScannedBarcode(result.text)) + } } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b81330b93754..780535cb7f4a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -48,6 +48,7 @@ + + scope.setTag("flavor", BuildConfig.FLAVOR) + } + } + } + + fun setBarcode(barcode: String) { + setTag("barcode", barcode) + } + + fun setTag(key: String, value: String) { + if (isCrashReportingEnabled) { + Sentry.setTag(key, value) + } + } + + fun record(exception: Throwable) { + if (isCrashReportingEnabled) { + Sentry.captureException(exception) + } + } +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/AnalyticsService.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/AnalyticsService.kt deleted file mode 100644 index bbdcc6a3b48b..000000000000 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/AnalyticsService.kt +++ /dev/null @@ -1,14 +0,0 @@ -package openfoodfacts.github.scrachx.openfood.app - -import io.sentry.Sentry -import openfoodfacts.github.scrachx.openfood.BuildConfig - -object AnalyticsService { - fun init() = Sentry.configureScope { it.setTag("flavor", BuildConfig.FLAVOR) } - - fun setBarcode(barcode: String) = setTag("barcode", barcode) - - fun setTag(key: String, value: String) = Sentry.setTag(key, value) - - fun record(exception: Throwable) = Sentry.captureException(exception) -} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/OFFApplication.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/OFFApplication.kt index 4db11c8d40af..3059521d2f3a 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/OFFApplication.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/app/OFFApplication.kt @@ -28,7 +28,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.greendao.query.QueryBuilder import java.io.IOException import javax.inject.Inject -import openfoodfacts.github.scrachx.openfood.app.AnalyticsService.init as initAnalytics +import openfoodfacts.github.scrachx.openfood.analytics.SentryAnalytics.init as initAnalytics @HiltAndroidApp class OFFApplication : MultiDexApplication(), Configuration.Provider { @@ -87,4 +87,4 @@ class OFFApplication : MultiDexApplication(), Configuration.Provider { @Synchronized private set } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/LoginActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/LoginActivity.kt index 97dcd1fd1237..99bb74ffee06 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/LoginActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/LoginActivity.kt @@ -38,6 +38,8 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.BuildConfig import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabsHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback @@ -147,6 +149,9 @@ class LoginActivity : BaseActivity() { } binding.txtInfoLogin.setTextColor(ContextCompat.getColor(this, R.color.green_500)) binding.txtInfoLogin.setText(R.string.txtInfoLoginOk) + + MatomoAnalytics.trackEvent(AnalyticsEvent.UserLogin) + setResult(RESULT_OK) finish() } @@ -235,4 +240,4 @@ class LoginActivity : BaseActivity() { override fun parseResult(resultCode: Int, intent: Intent?) = resultCode == RESULT_OK } } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/MainActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/MainActivity.kt index 95f1266cf76c..d9cb49717938 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/MainActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/MainActivity.kt @@ -72,6 +72,8 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.BuildConfig import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabsHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback @@ -519,6 +521,7 @@ class MainActivity : BaseActivity(), NavigationDrawerListener { private fun logout() { getSharedPreferences(PreferencesFragment.LOGIN_PREF, MODE_PRIVATE).edit { clear() } updateConnectedState() + MatomoAnalytics.trackEvent(AnalyticsEvent.UserLogout) } override fun onSaveInstanceState(outState: Bundle) { @@ -728,6 +731,7 @@ class MainActivity : BaseActivity(), NavigationDrawerListener { public override fun onResume() { super.onResume() binding.bottomNavigationInclude.bottomNavigation.selectNavigationItem(R.id.home_page) + MatomoAnalytics.showAnalyticsBottomSheetIfNeeded(supportFragmentManager) // change drawer menu item from "install" to "open" when navigating back from play store. if (isApplicationInstalled(this@MainActivity, BuildConfig.OFOTHERLINKAPP)) { diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/PreferencesFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/PreferencesFragment.kt index 09b947a35207..e2fa381125eb 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/PreferencesFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/PreferencesFragment.kt @@ -54,6 +54,9 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF import openfoodfacts.github.scrachx.openfood.AppFlavors.OPFF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback import openfoodfacts.github.scrachx.openfood.features.scan.ContinuousScanActivity @@ -272,7 +275,9 @@ class PreferencesFragment : PreferenceFragmentCompat(), INavigationItem, OnShare // Disable photo mode for OpenProductFacts - if (isFlavors(AppFlavors.OPF)) requirePreference(getString(R.string.pref_show_product_photos_key)).isVisible = false + if (isFlavors(AppFlavors.OPF)) { + requirePreference(getString(R.string.pref_show_product_photos_key)).isVisible = false + } // Preference to show version name requirePreference(getString(R.string.pref_version_key)).let { @@ -291,6 +296,13 @@ class PreferencesFragment : PreferenceFragmentCompat(), INavigationItem, OnShare preferenceScreen.removePreference(preferenceScreen.requirePreference(getString(R.string.pref_key_display))) } } + + requirePreference(getString(R.string.pref_analytics_reporting_key)).let { + it.setOnPreferenceChangeListener { _, newValue -> + MatomoAnalytics.onAnalyticsEnabledToggled(newValue == true) + true + } + } } private fun buildDisplayCategory(configs: List) { @@ -310,6 +322,15 @@ class PreferencesFragment : PreferenceFragmentCompat(), INavigationItem, OnShare summaryOn = null summaryOff = null title = getString(R.string.display_analysis_tag_status, config.typeName.toLowerCase(Locale.getDefault())) + setOnPreferenceChangeListener { _, newValue -> + val event = if (newValue == true) { + AnalyticsEvent.IngredientAnalysisEnabled(config.type) + } else { + AnalyticsEvent.IngredientAnalysisDisabled(config.type) + } + MatomoAnalytics.trackEvent(event) + true + } }) } } else { diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/allergensalert/AllergensAlertFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/allergensalert/AllergensAlertFragment.kt index 06eaf053d71a..cf3fdb7dc098 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/allergensalert/AllergensAlertFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/allergensalert/AllergensAlertFragment.kt @@ -37,6 +37,8 @@ import openfoodfacts.github.scrachx.openfood.databinding.FragmentAlertAllergensB import openfoodfacts.github.scrachx.openfood.features.shared.NavigationBaseFragment import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenName import openfoodfacts.github.scrachx.openfood.repositories.ProductRepository +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.utils.LocaleHelper import openfoodfacts.github.scrachx.openfood.utils.NavigationDrawerListener import openfoodfacts.github.scrachx.openfood.utils.NavigationDrawerListener.NavigationDrawerType @@ -137,6 +139,7 @@ class AllergensAlertFragment : NavigationBaseFragment() { mAllergensEnabled!!.add(allergens[position]) adapter.notifyItemInserted(mAllergensEnabled!!.size - 1) binding.allergensRecycle.scrollToPosition(adapter.itemCount - 1) + MatomoAnalytics.trackEvent(AnalyticsEvent.AllergenAlertCreated(allergens[position].allergenTag)) } }.show() }.addTo(disp) diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/analyticsusage/AnalyticsUsageDialogFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/analyticsusage/AnalyticsUsageDialogFragment.kt new file mode 100644 index 000000000000..9a30188a90ca --- /dev/null +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/analyticsusage/AnalyticsUsageDialogFragment.kt @@ -0,0 +1,46 @@ +package openfoodfacts.github.scrachx.openfood.features.analyticsusage + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.preference.PreferenceManager +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication +import openfoodfacts.github.scrachx.openfood.databinding.FragmentAnalyticsUsageBottomSheetBinding + +class AnalyticsUsageDialogFragment : BottomSheetDialogFragment() { + + companion object { + const val TAG = "AnalyticsUsageDialogFragment" + } + + init { + isCancelable = false + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { + val binding: FragmentAnalyticsUsageBottomSheetBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_analytics_usage_bottom_sheet, container, false) + binding.grantButton.setOnClickListener { + saveAnalyticsReportingPref(true) + MatomoAnalytics.onAnalyticsEnabledToggled(true) + dismiss() + } + binding.declineButton.setOnClickListener { + saveAnalyticsReportingPref(false) + MatomoAnalytics.onAnalyticsEnabledToggled(false) + dismiss() + } + return binding.root + } + + private fun saveAnalyticsReportingPref(value: Boolean) { + PreferenceManager.getDefaultSharedPreferences(OFFApplication._instance) + .edit() + .putBoolean(OFFApplication._instance.getString(R.string.pref_analytics_reporting_key), value) + .apply() + } +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/changelog/ChangelogDialog.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/changelog/ChangelogDialog.kt index fe26caf4ecd6..cfbe8a969e54 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/changelog/ChangelogDialog.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/changelog/ChangelogDialog.kt @@ -17,7 +17,7 @@ import androidx.recyclerview.widget.RecyclerView import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import openfoodfacts.github.scrachx.openfood.R -import openfoodfacts.github.scrachx.openfood.app.AnalyticsService +import openfoodfacts.github.scrachx.openfood.analytics.SentryAnalytics import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabsHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback @@ -80,7 +80,7 @@ class ChangelogDialog : DialogFragment(R.layout.fragment_changelog) { saveVersionCode(activity, currentVersionCode) } } catch (ex: NameNotFoundException) { - AnalyticsService.record(ex) + SentryAnalytics.record(ex) Unit } } @@ -128,7 +128,7 @@ class ChangelogDialog : DialogFragment(R.layout.fragment_changelog) { .observeOn(AndroidSchedulers.mainThread()) .subscribe( { items -> recyclerView.adapter = ChangelogAdapter(items) }, - { throwable -> AnalyticsService.record(throwable) } + { throwable -> SentryAnalytics.record(throwable) } ) ) } diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/compare/ProductCompareActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/compare/ProductCompareActivity.kt index 8f9b4dd92fb1..479d8d691348 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/compare/ProductCompareActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/compare/ProductCompareActivity.kt @@ -13,12 +13,14 @@ import androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL import com.afollestad.materialdialogs.MaterialDialog import dagger.hilt.android.AndroidEntryPoint import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent import openfoodfacts.github.scrachx.openfood.databinding.ActivityProductComparisonBinding import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.installBottomNavigation import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.selectNavigationItem import openfoodfacts.github.scrachx.openfood.features.scan.ContinuousScanActivity import openfoodfacts.github.scrachx.openfood.features.shared.BaseActivity import openfoodfacts.github.scrachx.openfood.models.Product +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient import openfoodfacts.github.scrachx.openfood.repositories.ProductRepository import openfoodfacts.github.scrachx.openfood.utils.MY_PERMISSIONS_REQUEST_CAMERA @@ -57,6 +59,10 @@ class ProductCompareActivity : BaseActivity() { } } + if (productsToCompare.size > 1) { + MatomoAnalytics.trackEvent(AnalyticsEvent.CompareProducts(productsToCompare.size.toFloat())) + } + productComparisonAdapter = ProductCompareAdapter(productsToCompare, this, api, productRepository) binding.productComparisonRv.layoutManager = LinearLayoutManager(this, HORIZONTAL, false) binding.productComparisonRv.adapter = productComparisonAdapter @@ -122,4 +128,4 @@ class ProductCompareActivity : BaseActivity() { @JvmStatic fun start(context: Context) = context.startActivity(Intent(context, ProductCompareActivity::class.java)) } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt index 7a7dfb00d81c..a6c29fceec5a 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt @@ -43,9 +43,10 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors.OPF import openfoodfacts.github.scrachx.openfood.AppFlavors.OPFF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.databinding.ActivityEditProductBinding import openfoodfacts.github.scrachx.openfood.features.product.ProductFragmentPagerAdapter -import openfoodfacts.github.scrachx.openfood.features.product.edit.overview.ProductEditOverviewFragment import openfoodfacts.github.scrachx.openfood.images.IMG_ID import openfoodfacts.github.scrachx.openfood.images.ProductImage import openfoodfacts.github.scrachx.openfood.jobs.OfflineProductWorker.Companion.scheduleSync @@ -311,6 +312,13 @@ class ProductEditActivity : AppCompatActivity() { Toast.makeText(this, R.string.productSavedToast, Toast.LENGTH_SHORT).show() hideKeyboard(this) + + if (editingMode) { + MatomoAnalytics.trackEvent(AnalyticsEvent.ProductEdited(productDetails["code"])) + } else { + MatomoAnalytics.trackEvent(AnalyticsEvent.ProductCreated(productDetails["code"])) + } + setResult(RESULT_OK) finish() } @@ -618,4 +626,4 @@ class ProductEditActivity : AppCompatActivity() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt index 52cef138efcf..1221ee08877c 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt @@ -32,6 +32,10 @@ import dagger.hilt.android.AndroidEntryPoint import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.addTo import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.databinding.FragmentAddProductIngredientsBinding import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_PERFORM_OCR import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_SEND_UPDATED @@ -96,6 +100,7 @@ class ProductEditIngredientsFragment : ProductEditFragment() { filePath = uri.path } (activity as? ProductEditActivity)?.addToPhotoMap(image, 1) + MatomoAnalytics.trackEvent(AnalyticsEvent.ProductIngredientsPictureEdited(code)) hideImageProgress(false, getString(R.string.image_uploaded_successfully)) } val intent = if (activity == null) null else requireActivity().intent @@ -155,6 +160,11 @@ class ProductEditIngredientsFragment : ProductEditFragment() { } } + override fun onResume() { + super.onResume() + MatomoAnalytics.trackView(AnalyticsView.ProductEditIngredients) + } + private fun getImageIngredients() = productDetails[ApiFields.Keys.IMAGE_INGREDIENTS] private fun getAddProductActivity() = activity as ProductEditActivity? diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditNutritionFactsFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditNutritionFactsFragment.kt index a155dc0bc631..f20969cfed5a 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditNutritionFactsFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditNutritionFactsFragment.kt @@ -35,7 +35,9 @@ import com.squareup.picasso.Callback import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.rxkotlin.addTo import openfoodfacts.github.scrachx.openfood.R -import openfoodfacts.github.scrachx.openfood.app.AnalyticsService +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.analytics.SentryAnalytics import openfoodfacts.github.scrachx.openfood.databinding.FragmentAddProductNutritionFactsBinding import openfoodfacts.github.scrachx.openfood.features.shared.views.CustomValidatingEditTextView import openfoodfacts.github.scrachx.openfood.images.ProductImage @@ -159,6 +161,11 @@ class ProductEditNutritionFactsFragment : ProductEditFragment() { } } + override fun onResume() { + super.onResume() + MatomoAnalytics.trackView(AnalyticsView.ProductEditNutritionFacts) + } + override fun onDestroyView() { super.onDestroyView() _binding = null @@ -716,7 +723,7 @@ class ProductEditNutritionFactsFragment : ProductEditFragment() { modSpinner.setSelection(modSelectedIndex) } } catch (t: Throwable) { - AnalyticsService.record(IllegalStateException("Can't find weight units for nutriment: $nutrientShortName", t)) + SentryAnalytics.record(IllegalStateException("Can't find weight units for nutriment: $nutrientShortName", t)) closeScreenWithAlert() } diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditOverviewFragment.kt similarity index 99% rename from app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt rename to app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditOverviewFragment.kt index 88771457df26..73d893e77d54 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditOverviewFragment.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package openfoodfacts.github.scrachx.openfood.features.product.edit.overview +package openfoodfacts.github.scrachx.openfood.features.product.edit import android.content.Intent import android.net.Uri @@ -44,16 +44,17 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF import openfoodfacts.github.scrachx.openfood.AppFlavors.OPF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabsHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback import openfoodfacts.github.scrachx.openfood.databinding.FragmentAddProductOverviewBinding import openfoodfacts.github.scrachx.openfood.features.adapters.autocomplete.EmbCodeAutoCompleteAdapter import openfoodfacts.github.scrachx.openfood.features.adapters.autocomplete.PeriodAfterOpeningAutoCompleteAdapter -import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_PERFORM_OCR import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_SEND_UPDATED -import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditFragment import openfoodfacts.github.scrachx.openfood.images.ProductImage import openfoodfacts.github.scrachx.openfood.models.DaoSession import openfoodfacts.github.scrachx.openfood.models.Product @@ -215,6 +216,11 @@ class ProductEditOverviewFragment : ProductEditFragment() { } } + override fun onResume() { + super.onResume() + MatomoAnalytics.trackView(AnalyticsView.ProductEditOverview) + } + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/view/summary/SummaryProductFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/view/summary/SummaryProductFragment.kt index d9006c571125..f3b82c508adb 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/view/summary/SummaryProductFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/view/summary/SummaryProductFragment.kt @@ -48,6 +48,9 @@ import io.reactivex.rxkotlin.addTo import openfoodfacts.github.scrachx.openfood.AppFlavors.OFF import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabActivityHelper import openfoodfacts.github.scrachx.openfood.customtabs.CustomTabsHelper import openfoodfacts.github.scrachx.openfood.customtabs.WebViewFallback @@ -134,8 +137,12 @@ class SummaryProductFragment : BaseFragment(), ISummaryProductPresenter.View { } private var productQuestion: Question? = null - private val loginThenProcessInsight = registerForActivityResult(LoginContract()) - { isLogged -> if (isLogged) processInsight() } + private val loginThenProcessInsight = registerForActivityResult(LoginContract()) { isLogged -> + if (isLogged) { + MatomoAnalytics.trackEvent(AnalyticsEvent.RobotoffLoggedInAfterPrompt) + processInsight() + } + } private lateinit var productState: ProductState private var sendOther = false @@ -644,6 +651,7 @@ class SummaryProductFragment : BaseFragment(), ISummaryProductPresenter.View { if (requireActivity().isUserSet()) { processInsight() } else { + MatomoAnalytics.trackEvent(AnalyticsEvent.RobotoffLoginPrompt) MaterialDialog.Builder(requireActivity()).run { title(getString(R.string.sign_in_to_answer)) positiveText(getString(R.string.sign_in_or_register)) diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlist/ProductListActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlist/ProductListActivity.kt index ee9d3ba09e14..071296888d4e 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlist/ProductListActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlist/ProductListActivity.kt @@ -27,6 +27,8 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors import openfoodfacts.github.scrachx.openfood.AppFlavors.isFlavors import openfoodfacts.github.scrachx.openfood.BuildConfig import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.databinding.ActivityYourListedProductsBinding import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.installBottomNavigation import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.selectNavigationItem @@ -229,6 +231,7 @@ class ProductListActivity : BaseActivity(), SwipeController.Actions { } } else { exportAsCSV() + MatomoAnalytics.trackEvent(AnalyticsEvent.ShoppingListExported) } true } @@ -396,4 +399,4 @@ class ProductListActivity : BaseActivity(), SwipeController.Actions { const val KEY_LIST_NAME = "listName" const val KEY_PRODUCT_TO_ADD = "product" } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlists/ProductListsActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlists/ProductListsActivity.kt index 8de425ab0392..07c4250b13db 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlists/ProductListsActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/productlists/ProductListsActivity.kt @@ -37,6 +37,9 @@ import io.reactivex.disposables.CompositeDisposable import io.reactivex.rxkotlin.addTo import io.reactivex.schedulers.Schedulers import openfoodfacts.github.scrachx.openfood.R +import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent +import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics +import openfoodfacts.github.scrachx.openfood.app.OFFApplication import openfoodfacts.github.scrachx.openfood.databinding.ActivityProductListsBinding import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.installBottomNavigation import openfoodfacts.github.scrachx.openfood.features.listeners.CommonBottomListenerInstaller.selectNavigationItem @@ -137,7 +140,7 @@ class ProductListsActivity : BaseActivity(), SwipeController.Actions { .positiveText(R.string.dialog_create) .negativeText(R.string.dialog_cancel) .onPositive { dialog, _ -> // this enable to avoid dismissing dialog if list name already exist - Log.d("CreateListDialog", "Positive clicked") + MatomoAnalytics.trackEvent(AnalyticsEvent.ShoppingListCreated) val inputEditText = dialog.inputEditText!! val listName = inputEditText.text.toString() val productList = ProductLists(listName, if (productToAdd != null) 1 else 0) @@ -297,4 +300,4 @@ class ProductListsActivity : BaseActivity(), SwipeController.Actions { return productListsDao } } -} \ No newline at end of file +} diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/network/OpenFoodAPIClient.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/network/OpenFoodAPIClient.kt index 2666a28d7672..f86868113ff6 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/network/OpenFoodAPIClient.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/network/OpenFoodAPIClient.kt @@ -23,7 +23,7 @@ import openfoodfacts.github.scrachx.openfood.AppFlavors.OPF import openfoodfacts.github.scrachx.openfood.AppFlavors.OPFF import openfoodfacts.github.scrachx.openfood.BuildConfig import openfoodfacts.github.scrachx.openfood.R -import openfoodfacts.github.scrachx.openfood.app.AnalyticsService +import openfoodfacts.github.scrachx.openfood.analytics.SentryAnalytics import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_EDIT_PRODUCT import openfoodfacts.github.scrachx.openfood.features.product.view.ProductViewActivity @@ -53,7 +53,7 @@ class OpenFoodAPIClient @Inject constructor( private var historySyncDisp = CompositeDisposable() fun getProductStateFull(barcode: String, customHeader: String = Utils.HEADER_USER_AGENT_SEARCH): Single { - AnalyticsService.setBarcode(barcode) + SentryAnalytics.setBarcode(barcode) return productsApi.getProductByBarcode(barcode, getAllFields(), getUserAgent(customHeader)) } diff --git a/app/src/main/res/layout/fragment_add_product_overview.xml b/app/src/main/res/layout/fragment_add_product_overview.xml index 49d9b107458f..fa54f3d5adc3 100644 --- a/app/src/main/res/layout/fragment_add_product_overview.xml +++ b/app/src/main/res/layout/fragment_add_product_overview.xml @@ -11,7 +11,7 @@ android:clipToPadding="false" android:isScrollContainer="false" app:layout_behavior="@string/appbar_scrolling_view_behavior" - tools:context=".features.product.edit.overview.ProductEditOverviewFragment"> + tools:context=".features.product.edit.ProductEditOverviewFragment"> + + + + + + + + + + + + + + + +