Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 155bb516 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

feat: allow Exodus reports' web URLs to open in (supported) system languages

Currently, Exodus supports English, French, German, Italian, Spanish, and Greek in their website. If the device's language is any of the above, then Exodus will open in that language in the browser. Otherwise, the URL will fall back to English.
parent 16d13b6a
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Bundle
import android.text.Html
import android.text.format.Formatter
@@ -52,7 +51,6 @@ import com.google.android.material.button.MaterialButton
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textview.MaterialTextView
import dagger.hilt.android.AndroidEntryPoint
import foundation.e.apps.ui.MainActivity
import foundation.e.apps.R
import foundation.e.apps.data.application.data.Application
import foundation.e.apps.data.application.data.shareUri
@@ -71,6 +69,7 @@ import foundation.e.apps.install.download.data.DownloadProgress
import foundation.e.apps.install.pkg.AppLoungePackageManager
import foundation.e.apps.install.pkg.PWAManager
import foundation.e.apps.ui.AppInfoFetchViewModel
import foundation.e.apps.ui.MainActivity
import foundation.e.apps.ui.MainActivityViewModel
import foundation.e.apps.ui.PrivacyInfoViewModel
import foundation.e.apps.ui.application.ShareButtonVisibilityState.Hidden
@@ -78,6 +77,7 @@ import foundation.e.apps.ui.application.ShareButtonVisibilityState.Visible
import foundation.e.apps.ui.application.model.ApplicationScreenshotsRVAdapter
import foundation.e.apps.ui.application.subFrags.ApplicationDialogFragment
import foundation.e.apps.ui.parentFragment.TimeoutFragment
import foundation.e.apps.utils.ExodusUriGenerator
import foundation.e.apps.utils.isValid
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collectLatest
@@ -144,11 +144,7 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) {
    companion object {
        private const val PRIVACY_SCORE_SOURCE_CODE_URL =
            "https://gitlab.e.foundation/e/os/apps/-/blob/main/app/src/main/java/foundation/e/apps/data/exodus/repositories/PrivacyScoreRepositoryImpl.kt"
        private const val EXODUS_URL = "https://exodus-privacy.eu.org"
        private const val EXODUS_REPORT_URL = "https://reports.exodus-privacy.eu.org/"
        private const val PRIVACY_GUIDELINE_URL = "https://doc.e.foundation/privacy_score"
        private const val REQUEST_EXODUS_REPORT_URL =
            "https://reports.exodus-privacy.eu.org/en/analysis/submit#"
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -417,8 +413,13 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) {

    private fun openRequestExodusReportUrl() {
        val openUrlIntent = Intent(Intent.ACTION_VIEW)
        openUrlIntent.data =
            Uri.parse("${REQUEST_EXODUS_REPORT_URL}${applicationViewModel.getFusedApp()?.package_name}")
        val packageName = applicationViewModel.getFusedApp()?.package_name

        if (packageName.isNullOrBlank()) {
            return
        }

        openUrlIntent.data = ExodusUriGenerator.buildRequestReportUri(packageName)
        startActivity(openUrlIntent)
    }

@@ -987,11 +988,11 @@ class ApplicationFragment : TimeoutFragment(R.layout.fragment_application) {
        // if app info not loaded yet, pass the default exodus homePage url
        val fusedApp = applicationViewModel.getFusedApp()
        if (fusedApp == null || fusedApp.permsFromExodus == LIST_OF_NULL) {
            return EXODUS_URL
            return ExodusUriGenerator.DEFAULT_URL
        }

        val reportId = applicationViewModel.applicationLiveData.value!!.first.reportId
        return "$EXODUS_REPORT_URL${Locale.getDefault().language}/reports/$reportId"
        return ExodusUriGenerator.buildReportUri(reportId).toString()
    }

    private fun fetchAppTracker(application: Application) {
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.utils

import android.net.Uri
import java.util.Locale

object ExodusUriGenerator {
    const val DEFAULT_URL = "https://exodus-privacy.eu.org"
    private const val SCHEME = "https"
    private const val AUTHORITY = "reports.exodus-privacy.eu.org"

    fun buildReportUri(reportId: Long): Uri {
        val language = getLanguage(Locale.getDefault().language)

        return Uri.Builder()
            .scheme(SCHEME)
            .authority(AUTHORITY)
            .appendPath(language)
            .appendPath("reports")
            .appendPath(reportId.toString())
            .build()  // Example: https://reports.exodus-privacy.eu.org/es/reports/511980/
    }

    fun buildRequestReportUri(packageName: String): Uri {
        val language = getLanguage(Locale.getDefault().language)

        return Uri.Builder()
            .scheme(SCHEME)
            .authority(AUTHORITY)
            .appendPath(language)
            .appendPath("analysis")
            .appendPath("submit")
            .fragment(packageName)
            .build()  // Example: https://reports.exodus-privacy.eu.org/en/analysis/submit/#packagename
    }

    private fun getLanguage(param: String): String {
        return SupportedLanguage.values().find { it.language == param }?.language
            ?: SupportedLanguage.English.language
    }

    private enum class SupportedLanguage(val language: String) {
        English("en"),
        French("fr"),
        German("de"),
        Italian("it"),
        Spanish("es"),
        Greek("el")
    }
}