diff --git a/app/src/foss/res/values/donottranslate.xml b/app/src/foss/res/values/donottranslate.xml index 1283d53f..e16e098f 100644 --- a/app/src/foss/res/values/donottranslate.xml +++ b/app/src/foss/res/values/donottranslate.xml @@ -2,5 +2,4 @@ mapbox mapbox - https://paypal.me/johan98 \ No newline at end of file diff --git a/app/src/google/java/net/vonforst/evmap/auto/ChargepriceScreen.kt b/app/src/google/java/net/vonforst/evmap/auto/ChargepriceScreen.kt index bc6892ff..4988f21d 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/ChargepriceScreen.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/ChargepriceScreen.kt @@ -1,10 +1,5 @@ package net.vonforst.evmap.auto -import android.content.ActivityNotFoundException -import android.content.Intent -import android.net.Uri -import androidx.browser.customtabs.CustomTabColorSchemeParams -import androidx.browser.customtabs.CustomTabsIntent import androidx.car.app.CarContext import androidx.car.app.CarToast import androidx.car.app.Screen @@ -22,7 +17,6 @@ import jsonapi.ResourceIdentifier import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import net.vonforst.evmap.BuildConfig import net.vonforst.evmap.R import net.vonforst.evmap.api.chargeprice.* import net.vonforst.evmap.api.equivalentPlugTypes @@ -137,38 +131,7 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c ) ).build() ).setOnClickListener { - val intent = CustomTabsIntent.Builder() - .setDefaultColorSchemeParams( - CustomTabColorSchemeParams.Builder() - .setToolbarColor( - ContextCompat.getColor( - carContext, - R.color.colorPrimary - ) - ) - .build() - ) - .build().intent - intent.data = - Uri.parse(ChargepriceApi.getPoiUrl(charger)) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - try { - carContext.startActivity(intent) - if (BuildConfig.FLAVOR_automotive != "automotive") { - // only show the toast "opened on phone" if we're running on a phone - CarToast.makeText( - carContext, - R.string.opened_on_phone, - CarToast.LENGTH_LONG - ).show() - } - } catch (e: ActivityNotFoundException) { - CarToast.makeText( - carContext, - R.string.no_browser_app_found, - CarToast.LENGTH_LONG - ).show() - } + openUrl(carContext, ChargepriceApi.getPoiUrl(charger)) }.build() ).build() ) diff --git a/app/src/google/java/net/vonforst/evmap/auto/SettingsScreens.kt b/app/src/google/java/net/vonforst/evmap/auto/SettingsScreens.kt index 0494e3cf..058f6890 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/SettingsScreens.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/SettingsScreens.kt @@ -1,6 +1,7 @@ package net.vonforst.evmap.auto import android.content.Context +import android.content.Intent import android.hardware.Sensor import android.hardware.SensorManager import androidx.annotation.StringRes @@ -14,6 +15,8 @@ import androidx.core.graphics.drawable.IconCompat import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch import net.vonforst.evmap.BuildConfig +import net.vonforst.evmap.EXTRA_DONATE +import net.vonforst.evmap.MapsActivity import net.vonforst.evmap.R import net.vonforst.evmap.api.chargeprice.ChargepriceApi import net.vonforst.evmap.api.chargeprice.ChargepriceCar @@ -26,7 +29,6 @@ import kotlin.math.min @ExperimentalCarApi class SettingsScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx) { val prefs = PreferenceDataSource(ctx) - var developerOptionsCounter = 0 override fun onGetTemplate(): Template { return ListTemplate.Builder().apply { @@ -88,37 +90,31 @@ class SettingsScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx) { .setToggle(Toggle.Builder { prefs.showChargersAheadAndroidAuto = it }.setChecked(prefs.showChargersAheadAndroidAuto).build()) + .setImage( + CarIcon.Builder( + IconCompat.createWithResource( + carContext, + R.drawable.ic_navigation + ) + ).setTint(CarColor.DEFAULT).build() + ) .build() ) } addItem( Row.Builder() .setTitle(carContext.getString(R.string.about)) - .addText(carContext.getString(R.string.version) + " " + BuildConfig.VERSION_NAME) - .addText( - carContext.getString(R.string.copyright) + " " + carContext.getString( - R.string.copyright_summary - ) + .setImage( + CarIcon.Builder( + IconCompat.createWithResource( + carContext, + R.drawable.ic_about + ) + ).setTint(CarColor.DEFAULT).build() ) - .setBrowsable(prefs.developerModeEnabled) + .setBrowsable(true) .setOnClickListener { - if (!prefs.developerModeEnabled) { - developerOptionsCounter += 1 - if (developerOptionsCounter >= 7) { - prefs.developerModeEnabled = true - invalidate() - CarToast.makeText( - carContext, - carContext.getString(R.string.developer_mode_enabled), - CarToast.LENGTH_SHORT - ).show() - } - } else { - screenManager.pushForResult(DeveloperOptionsScreen(carContext)) { - developerOptionsCounter = 0 - invalidate() - } - } + screenManager.push(AboutScreen(carContext)) } .build() ) @@ -596,6 +592,121 @@ class SelectChargingRangeScreen(ctx: CarContext) : Screen(ctx) { } } +class AboutScreen(ctx: CarContext) : Screen(ctx) { + val prefs = PreferenceDataSource(ctx) + var developerOptionsCounter = 0 + private val maxRows = if (ctx.carAppApiLevel >= 2) { + ctx.constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST) + } else 6 + + override fun onGetTemplate(): Template { + return ListTemplate.Builder().apply { + setTitle(carContext.getString(R.string.about)) + setHeaderAction(Action.BACK) + addSectionedList(SectionedItemList.create(ItemList.Builder().apply { + addItem( + Row.Builder() + .setTitle(carContext.getString(R.string.version)) + .addText(BuildConfig.VERSION_NAME) + .addText( + carContext.getString(R.string.copyright) + " " + carContext.getString( + R.string.copyright_summary + ) + ) + .setBrowsable(prefs.developerModeEnabled) + .setOnClickListener { + if (!prefs.developerModeEnabled) { + developerOptionsCounter += 1 + if (developerOptionsCounter >= 7) { + prefs.developerModeEnabled = true + invalidate() + CarToast.makeText( + carContext, + carContext.getString(R.string.developer_mode_enabled), + CarToast.LENGTH_SHORT + ).show() + } + } else { + screenManager.pushForResult(DeveloperOptionsScreen(carContext)) { + developerOptionsCounter = 0 + invalidate() + } + } + }.build() + ) + addItem( + Row.Builder() + .setTitle(carContext.getString(R.string.faq)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + openUrl(carContext, carContext.getString(R.string.faq_link)) + }).build() + ) + addItem( + Row.Builder() + .setTitle(carContext.getString(R.string.donate)) + .addText(carContext.getString(R.string.donate_desc)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + if (BuildConfig.FLAVOR_automotive == "automotive") { + // we can't open the donation page on the phone in this case + openUrl(carContext, carContext.getString(R.string.paypal_link)) + } else { + val intent = Intent(carContext, MapsActivity::class.java) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(EXTRA_DONATE, true) + carContext.startActivity(intent) + CarToast.makeText( + carContext, + R.string.opened_on_phone, + CarToast.LENGTH_LONG + ).show() + } + }).build() + ) + }.build(), carContext.getString(R.string.about))) + addSectionedList(SectionedItemList.create(ItemList.Builder().apply { + addItem(Row.Builder() + .setTitle(carContext.getString(R.string.twitter)) + .addText(carContext.getString(R.string.twitter_handle)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + openUrl(carContext, carContext.getString(R.string.twitter_url)) + }).build() + ) + if (maxRows > 6) { + addItem(Row.Builder() + .setTitle(carContext.getString(R.string.goingelectric_forum)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + openUrl( + carContext, + carContext.getString(R.string.goingelectric_forum_url) + ) + }).build() + ) + } + }.build(), carContext.getString(R.string.contact))) + addSectionedList(SectionedItemList.create(ItemList.Builder().apply { + addItem(Row.Builder() + .setTitle(carContext.getString(R.string.github_link_title)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + openUrl(carContext, carContext.getString(R.string.github_link)) + }).build() + ) + addItem(Row.Builder() + .setTitle(carContext.getString(R.string.privacy)) + .setBrowsable(true) + .setOnClickListener(ParkedOnlyOnClickListener.create { + openUrl(carContext, carContext.getString(R.string.privacy_link)) + }).build() + ) + }.build(), carContext.getString(R.string.other))) + }.build() + } +} + class DeveloperOptionsScreen(ctx: CarContext) : Screen(ctx) { val prefs = PreferenceDataSource(ctx) diff --git a/app/src/google/java/net/vonforst/evmap/auto/Utils.kt b/app/src/google/java/net/vonforst/evmap/auto/Utils.kt index 3299702a..23c51f2b 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/Utils.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/Utils.kt @@ -1,14 +1,22 @@ package net.vonforst.evmap.auto +import android.content.ActivityNotFoundException import android.content.Context +import android.content.Intent import android.graphics.Bitmap +import android.net.Uri +import androidx.browser.customtabs.CustomTabColorSchemeParams +import androidx.browser.customtabs.CustomTabsIntent import androidx.car.app.CarContext +import androidx.car.app.CarToast import androidx.car.app.Screen import androidx.car.app.constraints.ConstraintManager import androidx.car.app.hardware.common.CarUnit import androidx.car.app.model.* import androidx.car.app.versioning.CarAppApiLevels +import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.IconCompat +import net.vonforst.evmap.BuildConfig import net.vonforst.evmap.R import net.vonforst.evmap.api.availability.ChargepointStatus import java.util.* @@ -190,6 +198,40 @@ fun supportsCarApiLevel3(ctx: CarContext): Boolean { return true } +fun openUrl(carContext: CarContext, url: String) { + val intent = CustomTabsIntent.Builder() + .setDefaultColorSchemeParams( + CustomTabColorSchemeParams.Builder() + .setToolbarColor( + ContextCompat.getColor( + carContext, + R.color.colorPrimary + ) + ) + .build() + ) + .build().intent + intent.data = Uri.parse(url) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + try { + carContext.startActivity(intent) + if (BuildConfig.FLAVOR_automotive != "automotive") { + // only show the toast "opened on phone" if we're running on a phone + CarToast.makeText( + carContext, + R.string.opened_on_phone, + CarToast.LENGTH_LONG + ).show() + } + } catch (e: ActivityNotFoundException) { + CarToast.makeText( + carContext, + R.string.no_browser_app_found, + CarToast.LENGTH_LONG + ).show() + } +} + class DummyReturnScreen(ctx: CarContext) : Screen(ctx) { /* Dummy screen to get around template refresh limitations. diff --git a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt index cd7c34aa..89e259fb 100644 --- a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt +++ b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt @@ -40,6 +40,7 @@ const val EXTRA_CHARGER_ID = "chargerId" const val EXTRA_LAT = "lat" const val EXTRA_LON = "lon" const val EXTRA_FAVORITES = "favorites" +const val EXTRA_DONATE = "donate" class MapsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { @@ -188,6 +189,11 @@ class MapsActivity : AppCompatActivity(), .setGraph(navGraph) .setDestination(R.id.favs) .createPendingIntent() + } else if (intent.hasExtra(EXTRA_DONATE)) { + deepLink = navController.createDeepLink() + .setGraph(navGraph) + .setDestination(R.id.donate) + .createPendingIntent() } deepLink?.send() diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index b314430d..26519586 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -23,4 +23,5 @@ nautilusx net.vonforst.evmap.ui.HideOnScrollFabBehavior + https://paypal.me/johan98 \ No newline at end of file