mirror of
https://github.com/ev-map/EVMap.git
synced 2025-12-24 07:37:46 -05:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c4136c66d | ||
|
|
6e56f5c3ff | ||
|
|
017be6f31a | ||
|
|
b398a5dc81 | ||
|
|
3fb0dec868 | ||
|
|
8c4de115ec | ||
|
|
334b68cf5e | ||
|
|
788c68c9dd | ||
|
|
7842a15529 | ||
|
|
e7c9432191 | ||
|
|
76b6abd3ca | ||
|
|
752c184146 | ||
|
|
5471ac5073 | ||
|
|
69ae13a199 | ||
|
|
8a2e2d9a25 | ||
|
|
fe69a78b94 | ||
|
|
2663bd7964 | ||
|
|
3b54b2799f | ||
|
|
3a24711626 | ||
|
|
c158744bc2 | ||
|
|
c01033a036 | ||
|
|
16474c3864 | ||
|
|
7ce2f8d452 | ||
|
|
28df158d94 | ||
|
|
90b3645a0b | ||
|
|
de901aa825 | ||
|
|
2ce61f2f6b |
@@ -92,8 +92,4 @@ free, i.e. the background map displayed in the app if OpenStreetMap is selected
|
||||
|
||||
<a href="https://chargeprice.app"><img src="https://raw.githubusercontent.com/ev-map/EVMap/master/_img/powered_by_chargeprice.svg" alt="Powered by Chargeprice" height="58"/></a><br>
|
||||
Since April 2021, **Chargeprice.app** provide their price comparison API at a greatly reduced
|
||||
price for EVMap. This data is used in EVMap's price comparison feature.
|
||||
|
||||
<a href="https://fronyx.io/"><img src="https://github.com/ev-map/EVMap/blob/master/_img/powered_by_fronyx.svg" alt="Powered by Fronyx" height="68"/></a><br>
|
||||
Since September 2022, for certain charging stations, **Fronyx** provide us free access to their API
|
||||
for availability predictions.
|
||||
price for EVMap. This data is used in EVMap's price comparison feature.
|
||||
@@ -20,8 +20,8 @@ android {
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
// NOTE: always increase versionCode by 2 since automotive flavor uses versionCode + 1
|
||||
versionCode = 230
|
||||
versionName = "1.9.6"
|
||||
versionCode = 244
|
||||
versionName = "1.9.12"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -315,7 +315,7 @@ dependencies {
|
||||
automotiveImplementation("androidx.car.app:app-automotive:$carAppVersion")
|
||||
|
||||
// AnyMaps
|
||||
val anyMapsVersion = "3e6c71410f"
|
||||
val anyMapsVersion = "1174ef9375"
|
||||
implementation("com.github.ev-map.AnyMaps:anymaps-base:$anyMapsVersion")
|
||||
googleImplementation("com.github.ev-map.AnyMaps:anymaps-google:$anyMapsVersion")
|
||||
googleImplementation("com.google.android.gms:play-services-maps:19.0.0")
|
||||
@@ -323,7 +323,7 @@ dependencies {
|
||||
// duplicates classes from mapbox-sdk-services
|
||||
exclude("org.maplibre.gl", "android-sdk-geojson")
|
||||
}
|
||||
implementation("org.maplibre.gl:android-sdk:10.3.2-pre3") {
|
||||
implementation("org.maplibre.gl:android-sdk:10.3.3") {
|
||||
exclude("org.maplibre.gl", "android-sdk-geojson")
|
||||
}
|
||||
|
||||
@@ -365,6 +365,8 @@ dependencies {
|
||||
debugImplementation("com.facebook.flipper:flipper:0.238.0")
|
||||
debugImplementation("com.facebook.soloader:soloader:0.10.5")
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:0.238.0")
|
||||
debugImplementation("com.jakewharton.timber:timber:5.0.1")
|
||||
debugImplementation("com.squareup.leakcanary:leakcanary-android:2.14")
|
||||
|
||||
// testing
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin
|
||||
import com.facebook.soloader.SoLoader
|
||||
import okhttp3.OkHttpClient
|
||||
import timber.log.Timber
|
||||
|
||||
private val networkFlipperPlugin = NetworkFlipperPlugin()
|
||||
|
||||
@@ -24,6 +25,8 @@ fun addDebugInterceptors(context: Context) {
|
||||
client.addPlugin(DatabasesFlipperPlugin(context))
|
||||
client.addPlugin(SharedPreferencesFlipperPlugin(context))
|
||||
client.start()
|
||||
|
||||
Timber.plant(Timber.DebugTree())
|
||||
}
|
||||
|
||||
fun OkHttpClient.Builder.addDebugInterceptors(): OkHttpClient.Builder {
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
@@ -43,7 +42,7 @@ class DonateFragment : DonateFragmentBase() {
|
||||
)
|
||||
|
||||
binding.btnDonate.setOnClickListener {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.paypal_link))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.paypal_link), binding.root)
|
||||
}
|
||||
|
||||
setupReferrals(referrals)
|
||||
|
||||
@@ -44,14 +44,11 @@ const val EXTRA_DONATE = "donate"
|
||||
|
||||
class MapsActivity : AppCompatActivity(),
|
||||
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
||||
interface FragmentCallback {
|
||||
fun getRootView(): View
|
||||
}
|
||||
|
||||
private var reenterState: Bundle? = null
|
||||
private lateinit var navController: NavController
|
||||
private lateinit var navHostFragment: NavHostFragment
|
||||
lateinit var appBarConfiguration: AppBarConfiguration
|
||||
var fragmentCallback: FragmentCallback? = null
|
||||
private lateinit var prefs: PreferenceDataSource
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -70,7 +67,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
),
|
||||
drawerLayout
|
||||
)
|
||||
val navHostFragment =
|
||||
navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
val navGraph = navController.navInflater.inflate(R.navigation.nav_graph)
|
||||
@@ -237,7 +234,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
deepLink?.send()
|
||||
}
|
||||
|
||||
fun navigateTo(charger: ChargeLocation) {
|
||||
fun navigateTo(charger: ChargeLocation, rootView: View) {
|
||||
// google maps navigation
|
||||
val coord = charger.coordinates
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
@@ -247,11 +244,11 @@ class MapsActivity : AppCompatActivity(),
|
||||
startActivity(intent)
|
||||
} else {
|
||||
// fallback: generic geo intent
|
||||
showLocation(charger)
|
||||
showLocation(charger, rootView)
|
||||
}
|
||||
}
|
||||
|
||||
fun showLocation(charger: ChargeLocation) {
|
||||
fun showLocation(charger: ChargeLocation, rootView: View) {
|
||||
val coord = charger.coordinates
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = Uri.parse(
|
||||
@@ -262,16 +259,15 @@ class MapsActivity : AppCompatActivity(),
|
||||
if (intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent)
|
||||
} else {
|
||||
val cb = fragmentCallback ?: return
|
||||
Snackbar.make(
|
||||
cb.getRootView(),
|
||||
rootView,
|
||||
R.string.no_maps_app_found,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
fun openUrl(url: String, preferBrowser: Boolean = true) {
|
||||
fun openUrl(url: String, rootView: View, preferBrowser: Boolean = true) {
|
||||
val pkg = CustomTabsClient.getPackageName(this, null)
|
||||
val intent = CustomTabsIntent.Builder()
|
||||
.setDefaultColorSchemeParams(
|
||||
@@ -288,9 +284,8 @@ class MapsActivity : AppCompatActivity(),
|
||||
try {
|
||||
intent.launchUrl(this, Uri.parse(url))
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
val cb = fragmentCallback ?: return
|
||||
Snackbar.make(
|
||||
cb.getRootView(),
|
||||
rootView,
|
||||
R.string.no_browser_app_found,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
@@ -51,14 +51,11 @@ import net.vonforst.evmap.api.availability.ChargeLocationStatus
|
||||
import net.vonforst.evmap.api.availability.tesla.Pricing
|
||||
import net.vonforst.evmap.api.chargeprice.ChargepriceApi
|
||||
import net.vonforst.evmap.api.createApi
|
||||
import net.vonforst.evmap.api.fronyx.FronyxApi
|
||||
import net.vonforst.evmap.api.fronyx.PredictionData
|
||||
import net.vonforst.evmap.api.fronyx.PredictionRepository
|
||||
import net.vonforst.evmap.api.iconForPlugType
|
||||
import net.vonforst.evmap.api.nameForPlugType
|
||||
import net.vonforst.evmap.api.stringProvider
|
||||
import net.vonforst.evmap.model.ChargeLocation
|
||||
import net.vonforst.evmap.model.Coordinate
|
||||
import net.vonforst.evmap.model.Cost
|
||||
import net.vonforst.evmap.model.FaultReport
|
||||
import net.vonforst.evmap.model.Favorite
|
||||
@@ -92,7 +89,8 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
private val repo =
|
||||
ChargeLocationsRepository(createApi(prefs.dataSource, ctx), lifecycleScope, db, prefs)
|
||||
private val availabilityRepo = AvailabilityRepository(ctx)
|
||||
private val predictionRepo = PredictionRepository(ctx)
|
||||
|
||||
//private val predictionRepo = PredictionRepository(ctx)
|
||||
private val timeFormat = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
|
||||
|
||||
private val imageSize = 128 // images should be 128dp according to docs
|
||||
@@ -547,10 +545,13 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
}
|
||||
|
||||
private fun navigateToCharger(charger: ChargeLocation) {
|
||||
val success = navigateCarApp(charger)
|
||||
var success = navigateCarApp(charger)
|
||||
if (!success && BuildConfig.FLAVOR_automotive == "automotive") {
|
||||
// on AAOS, some OEMs' navigation apps might not support
|
||||
navigateRegularApp(charger)
|
||||
success = navigateRegularApp(charger)
|
||||
}
|
||||
if (!success) {
|
||||
CarToast.makeText(carContext, R.string.no_maps_app_found, CarToast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,6 +585,7 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
Uri.encode(charger.name)
|
||||
})"
|
||||
)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
if (intent.resolveActivity(carContext.packageManager) != null) {
|
||||
carContext.startActivity(intent)
|
||||
return true
|
||||
@@ -645,12 +647,12 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
)
|
||||
this@ChargerDetailScreen.photo = outImg
|
||||
}
|
||||
fronyxSupported = charger.chargepoints.any {
|
||||
fronyxSupported = false /*charger.chargepoints.any {
|
||||
FronyxApi.isChargepointSupported(
|
||||
charger,
|
||||
it
|
||||
)
|
||||
} && !availabilityRepo.isSupercharger(charger)
|
||||
} && !availabilityRepo.isSupercharger(charger)*/
|
||||
teslaSupported = availabilityRepo.isTeslaSupported(charger)
|
||||
|
||||
invalidate()
|
||||
@@ -659,7 +661,7 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
|
||||
invalidate()
|
||||
|
||||
prediction = predictionRepo.getPredictionData(charger, availability)
|
||||
//prediction = predictionRepo.getPredictionData(charger, availability)
|
||||
|
||||
invalidate()
|
||||
} else {
|
||||
|
||||
@@ -4,7 +4,14 @@ 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.model.*
|
||||
import androidx.car.app.model.Action
|
||||
import androidx.car.app.model.ActionStrip
|
||||
import androidx.car.app.model.CarColor
|
||||
import androidx.car.app.model.CarIcon
|
||||
import androidx.car.app.model.ItemList
|
||||
import androidx.car.app.model.Row
|
||||
import androidx.car.app.model.SearchTemplate
|
||||
import androidx.car.app.model.Template
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -45,7 +52,7 @@ abstract class MultiSelectSearchScreen<T>(ctx: CarContext) : Screen(ctx),
|
||||
} ?: run {
|
||||
setLoading(true)
|
||||
}
|
||||
if (isMultiSelect) {
|
||||
if (isMultiSelect && shouldShowSelectAll) {
|
||||
setActionStrip(ActionStrip.Builder().apply {
|
||||
addAction(
|
||||
Action.Builder().setIcon(
|
||||
|
||||
@@ -216,7 +216,7 @@ class DataSettingsScreen(ctx: CarContext) : Screen(ctx) {
|
||||
}
|
||||
}
|
||||
}.build())
|
||||
addItem(
|
||||
/*addItem(
|
||||
Row.Builder()
|
||||
.setTitle(carContext.getString(R.string.pref_prediction_enabled))
|
||||
.addText(carContext.getString(R.string.pref_prediction_enabled_summary))
|
||||
@@ -224,7 +224,7 @@ class DataSettingsScreen(ctx: CarContext) : Screen(ctx) {
|
||||
prefs.predictionEnabled = it
|
||||
}.setChecked(prefs.predictionEnabled).build())
|
||||
.build()
|
||||
)
|
||||
)*/
|
||||
addItem(Row.Builder().apply {
|
||||
setTitle(carContext.getString(R.string.pref_tesla_account))
|
||||
addText(
|
||||
@@ -825,13 +825,24 @@ class AboutScreen(ctx: CarContext) : Screen(ctx) {
|
||||
}.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))
|
||||
.setTitle(carContext.getString(R.string.mastodon))
|
||||
.addText(carContext.getString(R.string.mastodon_handle))
|
||||
.setBrowsable(true)
|
||||
.setOnClickListener(ParkedOnlyOnClickListener.create {
|
||||
openUrl(carContext, carContext.getString(R.string.twitter_url))
|
||||
openUrl(carContext, carContext.getString(R.string.mastodon_url))
|
||||
}).build()
|
||||
)
|
||||
if (maxRows > 8) {
|
||||
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))
|
||||
@@ -844,6 +855,19 @@ class AboutScreen(ctx: CarContext) : Screen(ctx) {
|
||||
}).build()
|
||||
)
|
||||
}
|
||||
if (maxRows > 7) {
|
||||
addItem(
|
||||
Row.Builder()
|
||||
.setTitle(carContext.getString(R.string.tff_forum))
|
||||
.setBrowsable(true)
|
||||
.setOnClickListener(ParkedOnlyOnClickListener.create {
|
||||
openUrl(
|
||||
carContext,
|
||||
carContext.getString(R.string.tff_forum_url)
|
||||
)
|
||||
}).build()
|
||||
)
|
||||
}
|
||||
}.build(), carContext.getString(R.string.contact)))
|
||||
addSectionedList(SectionedItemList.create(ItemList.Builder().apply {
|
||||
addItem(Row.Builder()
|
||||
|
||||
@@ -100,9 +100,9 @@ class ChargepriceFragment : Fragment() {
|
||||
inflater,
|
||||
R.layout.fragment_chargeprice_header, container, false
|
||||
)
|
||||
binding.lifecycleOwner = this
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.vm = vm
|
||||
headerBinding.lifecycleOwner = this
|
||||
headerBinding.lifecycleOwner = viewLifecycleOwner
|
||||
headerBinding.vm = vm
|
||||
|
||||
binding.toolbar.inflateMenu(R.menu.chargeprice)
|
||||
@@ -141,7 +141,7 @@ class ChargepriceFragment : Fragment() {
|
||||
|
||||
val chargepriceAdapter = ChargepriceAdapter().apply {
|
||||
onClickListener = {
|
||||
(requireActivity() as MapsActivity).openUrl(it.url)
|
||||
(requireActivity() as MapsActivity).openUrl(it.url, binding.root)
|
||||
}
|
||||
}
|
||||
val joinedAdapter = ConcatAdapter(
|
||||
@@ -194,7 +194,10 @@ class ChargepriceFragment : Fragment() {
|
||||
}
|
||||
|
||||
binding.imgChargepriceLogo.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(ChargepriceApi.getPoiUrl(charger))
|
||||
(requireActivity() as MapsActivity).openUrl(
|
||||
ChargepriceApi.getPoiUrl(charger),
|
||||
binding.root
|
||||
)
|
||||
}
|
||||
|
||||
binding.btnSettings.setOnClickListener {
|
||||
@@ -217,7 +220,10 @@ class ChargepriceFragment : Fragment() {
|
||||
binding.toolbar.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_help -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.chargeprice_faq_link))
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
getString(R.string.chargeprice_faq_link),
|
||||
binding.root
|
||||
)
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
|
||||
@@ -14,14 +14,14 @@ import net.vonforst.evmap.api.availability.ChargeLocationStatus
|
||||
import net.vonforst.evmap.databinding.DialogConnectorDetailsBinding
|
||||
import net.vonforst.evmap.databinding.DialogConnectorDetailsHeaderBinding
|
||||
import net.vonforst.evmap.model.Chargepoint
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
|
||||
class ConnectorDetailsDialog(
|
||||
val binding: DialogConnectorDetailsBinding,
|
||||
binding: DialogConnectorDetailsBinding,
|
||||
context: Context,
|
||||
onClose: () -> Unit
|
||||
) {
|
||||
private val headerBinding: DialogConnectorDetailsHeaderBinding
|
||||
private var headerBinding_: DialogConnectorDetailsHeaderBinding? = null
|
||||
private val headerBinding get() = headerBinding_!!
|
||||
private val detailsAdapter = ConnectorDetailsAdapter()
|
||||
|
||||
init {
|
||||
@@ -30,7 +30,7 @@ class ConnectorDetailsDialog(
|
||||
layoutManager =
|
||||
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
|
||||
}
|
||||
headerBinding = DataBindingUtil.inflate(
|
||||
headerBinding_ = DataBindingUtil.inflate(
|
||||
LayoutInflater.from(context),
|
||||
R.layout.dialog_connector_details_header, binding.list, false
|
||||
)
|
||||
@@ -60,4 +60,8 @@ class ConnectorDetailsDialog(
|
||||
headerBinding.divider.visibility = if (items.isEmpty()) View.GONE else View.VISIBLE
|
||||
headerBinding.item = ConnectorAdapter.ChargepointWithAvailability(cp, cpStatus)
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
headerBinding_ = null
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,26 @@
|
||||
package net.vonforst.evmap.fragment
|
||||
|
||||
import android.content.Intent
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.fragment.app.Fragment
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.databinding.FragmentDonateReferralBinding
|
||||
|
||||
abstract class DonateFragmentBase : Fragment() {
|
||||
fun setupReferrals(referrals: FragmentDonateReferralBinding) {
|
||||
referrals.referralTesla.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.tesla_referral_link))
|
||||
}
|
||||
referrals.referralJuicify.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.juicify_referral_link))
|
||||
}
|
||||
referrals.referralGeldfuereauto.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.geldfuereauto_referral_link))
|
||||
}
|
||||
referrals.referralMaingau.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.maingau_referral_link))
|
||||
}
|
||||
referrals.referralEwieeinfach.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.ewieeinfach_referral_link))
|
||||
}
|
||||
referrals.referralEprimo.setOnClickListener {
|
||||
(requireActivity() as MapsActivity).openUrl(getString(R.string.eprimo_referral_link))
|
||||
referrals.referralWebView.loadUrl(getString(R.string.referral_link))
|
||||
referrals.referralWebView.webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(
|
||||
view: WebView,
|
||||
request: WebResourceRequest
|
||||
): Boolean {
|
||||
Intent(Intent.ACTION_VIEW, request.url).apply {
|
||||
startActivity(this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,7 +65,7 @@ class FavoritesFragment : Fragment() {
|
||||
inflater,
|
||||
R.layout.fragment_favorites, container, false
|
||||
)
|
||||
binding.lifecycleOwner = this
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.vm = vm
|
||||
|
||||
return binding.root
|
||||
|
||||
@@ -45,7 +45,7 @@ class FilterFragment : Fragment(), MenuProvider {
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_filter, container, false)
|
||||
binding.lifecycleOwner = this
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.vm = vm
|
||||
vm.filterProfile.observe(viewLifecycleOwner) {}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class FilterProfilesFragment : Fragment() {
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = FragmentFilterProfilesBinding.inflate(inflater, container, false)
|
||||
binding.lifecycleOwner = this
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.vm = vm
|
||||
|
||||
return binding.root
|
||||
@@ -188,9 +188,17 @@ class FilterProfilesFragment : Fragment() {
|
||||
|
||||
dialog.setTitle(R.string.rename)
|
||||
.setMessage(R.string.save_profile_enter_name)
|
||||
}, {
|
||||
}, { newName ->
|
||||
lifecycleScope.launch {
|
||||
vm.update(fp.copy(name = it))
|
||||
if (vm.filterProfiles.value?.find { it.name == newName } != null) {
|
||||
Snackbar.make(
|
||||
view,
|
||||
R.string.filterprofile_name_not_unique,
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
} else {
|
||||
vm.update(fp.copy(name = newName))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -55,6 +55,7 @@ import androidx.transition.TransitionManager
|
||||
import coil.load
|
||||
import coil.memory.MemoryCache
|
||||
import com.car2go.maps.AnyMap
|
||||
import com.car2go.maps.MapFactory
|
||||
import com.car2go.maps.MapFragment
|
||||
import com.car2go.maps.OnMapReadyCallback
|
||||
import com.car2go.maps.model.BitmapDescriptor
|
||||
@@ -136,8 +137,9 @@ import kotlin.collections.set
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback, MenuProvider {
|
||||
private lateinit var binding: FragmentMapBinding
|
||||
class MapFragment : Fragment(), OnMapReadyCallback, MenuProvider {
|
||||
private var _binding: FragmentMapBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val vm: MapViewModel by viewModels()
|
||||
private val galleryVm: GalleryViewModel by activityViewModels()
|
||||
private var mapFragment: MapFragment? = null
|
||||
@@ -211,9 +213,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_map, container, false)
|
||||
_binding = DataBindingUtil.inflate(inflater, R.layout.fragment_map, container, false)
|
||||
println(binding.detailView.sourceButton)
|
||||
binding.lifecycleOwner = this
|
||||
binding.lifecycleOwner = viewLifecycleOwner
|
||||
binding.vm = vm
|
||||
|
||||
val provider = prefs.mapProvider
|
||||
@@ -221,16 +223,12 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
mapFragment =
|
||||
childFragmentManager.findFragmentByTag(mapFragmentTag) as MapFragment?
|
||||
}
|
||||
if (mapFragment == null || mapFragment!!.priority[0] != provider) {
|
||||
if (mapFragment == null || mapFragment!!.priority[0] != getMapProvider(provider)) {
|
||||
mapFragment = MapFragment()
|
||||
mapFragment!!.priority = arrayOf(
|
||||
when (provider) {
|
||||
"mapbox" -> MapFragment.MAPLIBRE
|
||||
"google" -> MapFragment.GOOGLE
|
||||
else -> null
|
||||
},
|
||||
MapFragment.GOOGLE,
|
||||
MapFragment.MAPLIBRE
|
||||
getMapProvider(provider),
|
||||
MapFactory.GOOGLE,
|
||||
MapFactory.MAPLIBRE
|
||||
)
|
||||
childFragmentManager
|
||||
.beginTransaction()
|
||||
@@ -293,6 +291,12 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun getMapProvider(provider: String) = when (provider) {
|
||||
"mapbox" -> MapFactory.MAPLIBRE
|
||||
"google" -> MapFactory.GOOGLE
|
||||
else -> null
|
||||
}
|
||||
|
||||
val bottomSheetCollapsible
|
||||
get() = resources.getBoolean(R.bool.bottom_sheet_collapsible)
|
||||
|
||||
@@ -362,9 +366,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
|
||||
binding.appLogo.root.animate().alpha(1f)
|
||||
.withEndAction {
|
||||
if (_binding == null) return@withEndAction
|
||||
binding.appLogo.root.animate().alpha(0f).apply {
|
||||
startDelay = 1000
|
||||
}.withEndAction {
|
||||
if (_binding == null) return@withEndAction
|
||||
binding.appLogo.root.visibility = View.GONE
|
||||
binding.search.visibility = View.VISIBLE
|
||||
binding.search.alpha = 0f
|
||||
@@ -388,9 +394,6 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val hostActivity = activity as? MapsActivity ?: return
|
||||
hostActivity.fragmentCallback = this
|
||||
|
||||
vm.reloadPrefs()
|
||||
if (requestingLocationUpdates && requireContext().checkAnyLocationPermission()
|
||||
) {
|
||||
@@ -422,7 +425,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
val charger = vm.charger.value?.data
|
||||
if (charger != null) {
|
||||
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
|
||||
(requireActivity() as MapsActivity).navigateTo(charger)
|
||||
(requireActivity() as MapsActivity).navigateTo(charger, binding.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,7 +438,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
binding.detailView.sourceButton.setOnClickListener {
|
||||
val charger = vm.charger.value?.data
|
||||
if (charger != null) {
|
||||
(activity as? MapsActivity)?.openUrl(charger.url)
|
||||
(activity as? MapsActivity)?.openUrl(charger.url, binding.root)
|
||||
}
|
||||
}
|
||||
binding.detailView.btnChargeprice.setOnClickListener {
|
||||
@@ -448,12 +451,16 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
extras
|
||||
)
|
||||
} else {
|
||||
(activity as? MapsActivity)?.openUrl(ChargepriceApi.getPoiUrl(charger), false)
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
ChargepriceApi.getPoiUrl(charger),
|
||||
binding.root,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.detailView.btnChargerWebsite.setOnClickListener {
|
||||
val charger = vm.charger.value?.data ?: return@setOnClickListener
|
||||
charger.chargerUrl?.let { (activity as? MapsActivity)?.openUrl(it) }
|
||||
charger.chargerUrl?.let { (activity as? MapsActivity)?.openUrl(it, binding.root) }
|
||||
}
|
||||
binding.detailView.btnLogin.setOnClickListener {
|
||||
findNavController().safeNavigate(
|
||||
@@ -461,7 +468,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
)
|
||||
}
|
||||
binding.detailView.imgPredictionSource.setOnClickListener {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.fronyx_url))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.fronyx_url), binding.root)
|
||||
}
|
||||
binding.detailView.btnPredictionHelp.setOnClickListener {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
@@ -501,7 +508,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
R.id.menu_edit -> {
|
||||
val charger = vm.charger.value?.data
|
||||
if (charger?.editUrl != null) {
|
||||
(activity as? MapsActivity)?.openUrl(charger.editUrl)
|
||||
(activity as? MapsActivity)?.openUrl(charger.editUrl, binding.root)
|
||||
if (vm.apiId.value == "goingelectric") {
|
||||
// instructions specific to GoingElectric
|
||||
Toast.makeText(
|
||||
@@ -917,10 +924,10 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
if (charger != null) {
|
||||
when (it.icon) {
|
||||
R.drawable.ic_location, R.drawable.ic_address -> {
|
||||
(activity as? MapsActivity)?.showLocation(charger)
|
||||
(activity as? MapsActivity)?.showLocation(charger, binding.root)
|
||||
}
|
||||
R.drawable.ic_fault_report -> {
|
||||
(activity as? MapsActivity)?.openUrl(charger.url)
|
||||
(activity as? MapsActivity)?.openUrl(charger.url, binding.root)
|
||||
}
|
||||
|
||||
R.drawable.ic_payment -> {
|
||||
@@ -928,7 +935,12 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
|
||||
R.drawable.ic_network -> {
|
||||
charger.networkUrl?.let { (activity as? MapsActivity)?.openUrl(it) }
|
||||
charger.networkUrl?.let {
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
it,
|
||||
binding.root
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1047,7 +1059,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
.setTitle(R.string.charge_cards)
|
||||
.setItems(names.toTypedArray()) { _, i ->
|
||||
val card = data[i]
|
||||
(activity as? MapsActivity)?.openUrl("https:${card.url}")
|
||||
(activity as? MapsActivity)?.openUrl("https:${card.url}", binding.root)
|
||||
}.show()
|
||||
}
|
||||
|
||||
@@ -1062,7 +1074,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
vm.mapTrafficSupported.value =
|
||||
mapFragment?.let { AnyMap.Feature.TRAFFIC_LAYER in it.supportedFeatures } ?: false
|
||||
|
||||
if (BuildConfig.FLAVOR.contains("google") && mapFragment!!.priority[0] == MapFragment.GOOGLE) {
|
||||
if (BuildConfig.FLAVOR.contains("google") && mapFragment!!.priority[0] == MapFactory.GOOGLE) {
|
||||
// Google Maps: icons can be generated in background thread
|
||||
lifecycleScope.launch {
|
||||
withContext(Dispatchers.Default) {
|
||||
@@ -1113,7 +1125,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
}
|
||||
vm.mapPosition.observe(viewLifecycleOwner) {
|
||||
binding.scaleView.update(map.cameraPosition.zoom, map.cameraPosition.target.latitude)
|
||||
val target = map.cameraPosition.target ?: return@observe
|
||||
binding.scaleView.update(map.cameraPosition.zoom, target.latitude)
|
||||
}
|
||||
|
||||
map.setOnCameraMoveStartedListener { reason ->
|
||||
@@ -1130,6 +1143,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
}
|
||||
map.setOnMarkerClickListener { marker ->
|
||||
val map = this@MapFragment.map ?: return@setOnMarkerClickListener false
|
||||
when (marker) {
|
||||
in markers -> {
|
||||
vm.chargerSparse.value = markers[marker]
|
||||
@@ -1536,10 +1550,6 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun getRootView(): View {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@RequiresPermission(anyOf = [ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION])
|
||||
private fun requestLocationUpdates() {
|
||||
locationEngine.requestLocationUpdates(
|
||||
@@ -1589,8 +1599,15 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
detailsDialog.onDestroy()
|
||||
vm.mapProjection = null
|
||||
|
||||
map = null
|
||||
mapFragment = null
|
||||
_binding = null
|
||||
vm.mapProjection = null
|
||||
/* if we don't dismiss the popup menu, it will be recreated in some cases
|
||||
(split-screen mode) and then have references to a destroyed fragment. */
|
||||
popupMenu?.dismiss()
|
||||
|
||||
@@ -78,22 +78,25 @@ class AboutFragment : PreferenceFragmentCompat() {
|
||||
}
|
||||
|
||||
"website" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.website_url))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.website_url), requireView())
|
||||
true
|
||||
}
|
||||
|
||||
"github_link" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.github_link))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.github_link), requireView())
|
||||
true
|
||||
}
|
||||
|
||||
"privacy" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.privacy_link))
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
getString(R.string.privacy_link),
|
||||
requireView()
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
"faq" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.faq_link))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.faq_link), requireView())
|
||||
true
|
||||
}
|
||||
"oss_licenses" -> {
|
||||
@@ -115,12 +118,29 @@ class AboutFragment : PreferenceFragmentCompat() {
|
||||
findNavController().safeNavigate(AboutFragmentDirections.actionAboutToGithubSponsors())
|
||||
true
|
||||
}
|
||||
"mastodon" -> {
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
getString(R.string.mastodon_url),
|
||||
requireView()
|
||||
)
|
||||
true
|
||||
}
|
||||
"twitter" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.twitter_url))
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.twitter_url), requireView())
|
||||
true
|
||||
}
|
||||
"goingelectric" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.goingelectric_forum_url))
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
getString(R.string.goingelectric_forum_url),
|
||||
requireView()
|
||||
)
|
||||
true
|
||||
}
|
||||
"tffforum" -> {
|
||||
(activity as? MapsActivity)?.openUrl(
|
||||
getString(R.string.tff_forum_url),
|
||||
requireView()
|
||||
)
|
||||
true
|
||||
}
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
|
||||
@@ -27,7 +27,6 @@ import net.vonforst.evmap.api.availability.ChargeLocationStatus
|
||||
import net.vonforst.evmap.api.availability.tesla.Pricing
|
||||
import net.vonforst.evmap.api.createApi
|
||||
import net.vonforst.evmap.api.fronyx.PredictionData
|
||||
import net.vonforst.evmap.api.fronyx.PredictionRepository
|
||||
import net.vonforst.evmap.api.goingelectric.GEChargepoint
|
||||
import net.vonforst.evmap.api.openchargemap.OCMConnection
|
||||
import net.vonforst.evmap.api.openchargemap.OCMReferenceData
|
||||
@@ -266,13 +265,14 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
|
||||
it.data?.extraData as? Pricing
|
||||
}
|
||||
|
||||
private val predictionRepository = PredictionRepository(application)
|
||||
//private val predictionRepository = PredictionRepository(application)
|
||||
|
||||
val predictionData: LiveData<PredictionData> = availability.switchMap { av ->
|
||||
liveData {
|
||||
/*liveData {
|
||||
val charger = charger.value?.data ?: return@liveData
|
||||
emit(predictionRepository.getPredictionData(charger, av.data, filteredConnectors.value))
|
||||
}
|
||||
}*/
|
||||
MutableLiveData()
|
||||
}
|
||||
|
||||
val myLocationEnabled: MutableLiveData<Boolean> by lazy {
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeTitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.7"
|
||||
app:srcCompat="@drawable/android_auto" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -8,7 +8,8 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
android:layout_marginBottom="16dp"
|
||||
tools:ignore="WebViewLayout">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView20"
|
||||
@@ -18,76 +19,27 @@
|
||||
android:text="@string/referrals"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/textView21"
|
||||
app:layout_constraintBottom_toTopOf="@+id/referralWebView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView21"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/referrals_info"
|
||||
app:layout_constraintBottom_toTopOf="@+id/referral_tesla"
|
||||
app:layout_constraintStart_toStartOf="@+id/textView20"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView20" />
|
||||
|
||||
<androidx.constraintlayout.helper.widget.Flow
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:constraint_referenced_ids="referral_tesla,referral_juicify,referral_geldfuereauto,referral_maingau,referral_eprimo,referral_ewieeinfach"
|
||||
app:flow_horizontalGap="16dp"
|
||||
app:flow_horizontalStyle="packed"
|
||||
app:flow_verticalAlign="baseline"
|
||||
app:flow_wrapMode="chain"
|
||||
app:layout_constraintBottom_toTopOf="@+id/referralWebView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView21" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView20" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_tesla"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
<WebView
|
||||
android:id="@+id/referralWebView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_tesla"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_tesla" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_juicify"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_juicify" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_geldfuereauto"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_geldfuereauto" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_maingau"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_maingau" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_eprimo"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_eprimo" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/referral_ewieeinfach"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/referral_ewieeinfach" />
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/textView21" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -3,14 +3,14 @@
|
||||
<string name="no_browser_app_found">Nejprve si nainstalujte webový prohlížeč</string>
|
||||
<string name="address">Adresa</string>
|
||||
<string name="hours">Otevírací doba</string>
|
||||
<string name="open_247"><b>Otevřeno 24/7</b></string>
|
||||
<string name="closed"><b>Zavřeno</b></string>
|
||||
<string name="open_closesat"><b>Otevřeno</b> · Zavírá v %s</string>
|
||||
<string name="closed_opensat"><b>Zavřeno</b> · Otevírá v %s</string>
|
||||
<string name="open_247"><![CDATA[<b>Otevřeno 24/7</b>]]></string>
|
||||
<string name="closed"><![CDATA[<b>Zavřeno</b>]]></string>
|
||||
<string name="open_closesat"><![CDATA[<b>Otevřeno</b> · Zavírá v %s]]></string>
|
||||
<string name="closed_opensat"><![CDATA[<b>Zavřeno</b> · Otevírá v %s]]></string>
|
||||
<string name="cost">Cena</string>
|
||||
<string name="cost_detail"><b>Nabíjení:</b> %1$s · <b>Parkování:</b> %2$s</string>
|
||||
<string name="cost_detail_charging"><b>%s nabíjení</b></string>
|
||||
<string name="cost_detail_parking"><b>%s parkování</b></string>
|
||||
<string name="cost_detail"><![CDATA[<b>Nabíjení:</b> %1$s · <b>Parkování:</b> %2$s]]></string>
|
||||
<string name="cost_detail_charging"><![CDATA[<b>%s nabíjení</b>]]></string>
|
||||
<string name="cost_detail_parking"><![CDATA[<b>%s parkování</b>]]></string>
|
||||
<string name="charging_free">Bezplatné</string>
|
||||
<string name="charging_paid">Placené</string>
|
||||
<string name="parking_free">Bezplatné</string>
|
||||
@@ -177,7 +177,7 @@
|
||||
<string name="crash_report_comment_prompt">Níže můžete přidat komentář:</string>
|
||||
<string name="powered_by_mapbox">používá službu Mapbox</string>
|
||||
<string name="pref_search_provider">Poskytovatel vyhledávání</string>
|
||||
<string name="pref_search_provider_info">Načtení dat pro vyhledávání bývá drahé, obzvláště z Map Google. Zvažte prosím poslání finančního daru v nabídce „O aplikaci“ → „Přispět“.</string>
|
||||
<string name="pref_search_provider_info"><![CDATA[Načtení dat pro vyhledávání bývá drahé, obzvláště z Map Google. Zvažte prosím poslání finančního daru v nabídce „O aplikaci“ → „Přispět“.]]></string>
|
||||
<string name="github_sponsors">GitHub Sponsors</string>
|
||||
<string name="donate_desc">Podpořte vývoj aplikace EVMap jednorázovým darem</string>
|
||||
<string name="github_sponsors_desc">Podpořte EVMap ve službě GitHub Sponsors</string>
|
||||
@@ -281,7 +281,7 @@
|
||||
<string name="loading">Načítání…</string>
|
||||
<string name="auto_multipage_goto">Stránka %d</string>
|
||||
<string name="reload">Obnovit</string>
|
||||
<string name="accept_privacy"><![CDATA[Přečetl/a jsem si a souhlasím se <a href="%s">zásadami ochrany osobních údajů</a> aplikace EVMap.]]></string>
|
||||
<string name="accept_privacy"><![CDATA[Přečetl/a jsem si a souhlasím se <a href=\"%s\">zásadami ochrany osobních údajů</a> aplikace EVMap.]]></string>
|
||||
<string name="referrals">Referenční odkazy</string>
|
||||
<string name="referrals_info">Pro podpoření vývojáře svým nákupem můžete také použít jeden z referenčních odkazů níže.</string>
|
||||
<string name="generic_connection_error">Nepodařilo se načíst data</string>
|
||||
@@ -344,7 +344,7 @@
|
||||
<string name="chargeprice_connection_error">Nepodařilo se načíst ceny</string>
|
||||
<string name="unknown_operator">Neznámý operátor</string>
|
||||
<string name="data_source_goingelectric">GoingElectric.de</string>
|
||||
<string name="data_source_openchargemap_desc">Celosvětové, s různou kvalitou. Popisy jsou v angličtině nebo v místním jazyce. Spravováno komunitou, v některých zemích obsahuje vládní data (např. Severní Amerika, Spojené království, Francie, Norsko).</string>
|
||||
<string name="data_source_openchargemap_desc"><![CDATA[Celosvětové, s různou kvalitou. Popisy jsou v angličtině nebo v místním jazyce. Spravováno komunitou, v některých zemích obsahuje vládní data (např. Severní Amerika, Spojené království, Francie, Norsko).]]></string>
|
||||
<string name="privacy_link">https://ev-map.app/privacypolicy/</string>
|
||||
<string name="chargeprice_faq_link">https://ev-map.app/faq/#price-comparison-feature</string>
|
||||
<string name="pref_darkmode_always_on">vždy zapnut</string>
|
||||
@@ -372,4 +372,5 @@
|
||||
<string name="pref_chargeprice_native_integration_on">Data o cenách budou zobrazena přímo v EVMap</string>
|
||||
<string name="pref_chargeprice_native_integration_off">Tlačítko porovnání cen bude odkazovat na aplikaci nebo web Chargeprice</string>
|
||||
<string name="pref_provider_osm">OpenStreetMap</string>
|
||||
<string name="filterprofile_name_not_unique">Již existuje profil filtru s tímto názvem</string>
|
||||
</resources>
|
||||
@@ -110,7 +110,9 @@
|
||||
<string name="and_n_others">und %d weitere</string>
|
||||
<string name="pref_map_provider">Kartenanbieter</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="mastodon">Mastodon</string>
|
||||
<string name="goingelectric_forum">Forenthread bei GoingElectric.de</string>
|
||||
<string name="tff_forum">Forenthread im TFF-Forum</string>
|
||||
<string name="contact">Kontakt</string>
|
||||
<string name="menu_report_new_charger">Ladesäule melden</string>
|
||||
<string name="edit_at_datasource">Bei %s bearbeiten</string>
|
||||
@@ -151,6 +153,7 @@
|
||||
<string name="delete">Löschen</string>
|
||||
<string name="save_as_profile">Als Profil speichern</string>
|
||||
<string name="save_profile_enter_name">Gib den Namen des Filterprofils ein:</string>
|
||||
<string name="filterprofile_name_not_unique">Ein Filterprofil mit diesem Namen existiert bereits</string>
|
||||
<string name="filterprofiles_empty_state">Du hast keine Filterprofile gespeichert</string>
|
||||
<string name="welcome_to_evmap">Willkommen bei EVMap</string>
|
||||
<string name="welcome_1">Finde Ladestationen für Elektroautos in deiner Nähe</string>
|
||||
@@ -232,7 +235,7 @@
|
||||
<string name="crash_report_comment_prompt">Du kannst unten noch einen Kommentar hinzufügen:</string>
|
||||
<string name="powered_by_mapbox">powered by Mapbox</string>
|
||||
<string name="pref_search_provider">Anbieter für Ortssuche</string>
|
||||
<string name="pref_search_provider_info">Die Daten für die Ortssuche, vor allem von Google Maps, sind relativ teuer. Über eine Spende unter \"Über EVMap -> Spenden\" würde ich mich sehr freuen.</string>
|
||||
<string name="pref_search_provider_info"><![CDATA[Die Daten für die Ortssuche, vor allem von Google Maps, sind relativ teuer. Über eine Spende unter „Über EVMap → Spenden“ würde ich mich sehr freuen.]]></string>
|
||||
<string name="github_sponsors">GitHub Sponsors</string>
|
||||
<string name="donate_desc">Unterstütze die Weiterentwicklung von EVMap mit einer einmaligen Spende</string>
|
||||
<string name="github_sponsors_desc">Unterstütze EVMap über GitHub Sponsors</string>
|
||||
@@ -240,6 +243,7 @@
|
||||
<string name="privacy_link">https://ev-map.app/de/privacypolicy/</string>
|
||||
<string name="faq_link">https://ev-map.app/de/faq/</string>
|
||||
<string name="chargeprice_faq_link">https://ev-map.app/de/faq/#preisvergleichsfunktion</string>
|
||||
<string name="referral_link">https://ev-map.app/de/referrals/</string>
|
||||
<string name="required">erforderlich</string>
|
||||
<string name="edit_filter_profile">„%s“ bearbeiten</string>
|
||||
<string name="pref_search_delete_recent">Suchverlauf löschen</string>
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<string name="pref_data_source">Fonte da informação</string>
|
||||
<string name="data_source_openchargemap">Open Charge Map</string>
|
||||
<string name="next">próximo</string>
|
||||
<string name="data_source_openchargemap_desc">Mundial, com vários níveis de qualidade. Descrições em inglês ou língua local. Mantido pela comunidade e usa informação governamental publica em alguns países (ex: América do Norte, Reino Unido, França, Noruega, etc).</string>
|
||||
<string name="data_source_openchargemap_desc"><![CDATA[Mundial, com vários níveis de qualidade. Descrições em inglês ou língua local. Mantido pela comunidade e usa informação governamental publica em alguns países (ex: América do Norte, Reino Unido, França, Noruega, etc).]]></string>
|
||||
<string name="get_started">Começar</string>
|
||||
<string name="lets_go">Vamos lá</string>
|
||||
<string name="crash_report_text">O EVMap encontrou um problema. Por favor envie um relatório do erro para o criador da app.</string>
|
||||
@@ -160,7 +160,7 @@
|
||||
<string name="pref_map_rotate_gestures_on">Use dois dedos para girar o mapa</string>
|
||||
<string name="pref_map_rotate_gestures_off">Rotação desligada (norte sempre para cima)</string>
|
||||
<string name="refresh_live_data">atualizar estado em tempo real</string>
|
||||
<string name="pref_search_provider_info">As pesquisas são caras, especialmente se o Google Maps for utilizado. Por favor considere doar através de \"Sobre\" → \"Doar\".</string>
|
||||
<string name="pref_search_provider_info"><![CDATA[As pesquisas são caras, especialmente quando o Google Maps é utilizado. Por favor considere doar através de "Sobre" → "Doar".]]></string>
|
||||
<string name="github_sponsors_desc">Apoie o EVMap através do GitHub</string>
|
||||
<string name="unnamed_filter_profile">Filtro sem nome</string>
|
||||
<string name="deleted_recent_search_results">As pesquisas recentes foram eliminadas</string>
|
||||
@@ -205,18 +205,18 @@
|
||||
<string name="operator">Operador</string>
|
||||
<string name="network">Rede</string>
|
||||
<string name="hours">Horário de abertura</string>
|
||||
<string name="open_247"><b>Aberto 24/7</b></string>
|
||||
<string name="closed"><b>Fechado</b></string>
|
||||
<string name="open_closesat"><b>Aberto</b> · Fecha às %s</string>
|
||||
<string name="closed_opensat"><b>Fechado</b> · Abre às %s</string>
|
||||
<string name="open_247"><![CDATA[<b>Aberto 24/7</b>]]></string>
|
||||
<string name="closed"><![CDATA[<b>Fechado</b>]]></string>
|
||||
<string name="open_closesat"><![CDATA[<b>Aberto</b> · Fecha às %s]]></string>
|
||||
<string name="closed_opensat"><![CDATA[<b>Fechado</b> · Abre às %s]]></string>
|
||||
<string name="app_name">EVMap</string>
|
||||
<string name="title_activity_maps">EVMap</string>
|
||||
<string name="closed_unfmt">Fechado</string>
|
||||
<string name="holiday">Feriado</string>
|
||||
<string name="cost">Custo</string>
|
||||
<string name="cost_detail"><b>Carregamento:</b> %1$s · <b>Parque:</b> %2$s</string>
|
||||
<string name="cost_detail_charging"><b>Carregamento %s</b></string>
|
||||
<string name="cost_detail_parking"><b>Parque %s</b></string>
|
||||
<string name="cost_detail"><![CDATA[<b>Carregamento:</b> %1$s · <b>Parque:</b> %2$s]]></string>
|
||||
<string name="cost_detail_charging"><![CDATA[<b>Carregamento %s</b>]]></string>
|
||||
<string name="cost_detail_parking"><![CDATA[<b>Parque %s</b>]]></string>
|
||||
<string name="charging_free">Gratuito</string>
|
||||
<string name="charging_paid">Pago</string>
|
||||
<string name="parking_free">Gratuito</string>
|
||||
@@ -372,4 +372,5 @@
|
||||
<string name="pref_chargeprice_native_integration_on">Os preços serão exibidos diretamente no EVMap</string>
|
||||
<string name="pref_chargeprice_native_integration_off">O botão de comparação de preços abrirá a app ou site do Chargeprice</string>
|
||||
<string name="pref_provider_osm">OpenStreetMap</string>
|
||||
<string name="filterprofile_name_not_unique">Já existe um filtro com este nome</string>
|
||||
</resources>
|
||||
@@ -5,7 +5,10 @@
|
||||
<string name="github_link">https://github.com/ev-map/EVMap</string>
|
||||
<string name="twitter_handle">\@ev_map</string>
|
||||
<string name="twitter_url">https://twitter.com/ev_map</string>
|
||||
<string name="mastodon_handle">\@evmap\@electroverse.tech</string>
|
||||
<string name="mastodon_url">https://electroverse.tech/@evmap</string>
|
||||
<string name="goingelectric_forum_url"><![CDATA[https://www.goingelectric.de/forum/viewtopic.php?f=5&t=56342]]></string>
|
||||
<string name="tff_forum_url"><![CDATA[https://tff-forum.de/t/283834]]></string>
|
||||
<string name="github_sponsors_link">https://github.com/sponsors/johan12345/</string>
|
||||
<string name="chargeprice_api_url">https://api.chargeprice.app/v1/</string>
|
||||
<string name="fronyx_url">https://fronyx.io/</string>
|
||||
@@ -27,17 +30,6 @@
|
||||
<string name="hide_on_scroll_fab_behavior">net.vonforst.evmap.ui.HideOnScrollFabBehavior</string>
|
||||
<string name="paypal_link" translatable="false">https://paypal.me/johan98</string>
|
||||
<string name="donate_link" translatable="false">https://ev-map.app/donate/</string>
|
||||
<string name="tesla_referral_link" translatable="false">http://ts.la/johan94494</string>
|
||||
<string name="juicify_referral_link" translatable="false">https://trck.juicify.green/trck/eclick/9dba357fbfed1e82fb05c7ec004ee2972ea174ce46d8ae0d</string>
|
||||
<string name="geldfuereauto_referral_link" translatable="false">https://trck.geld-fuer-eauto.de/trck/eclick/c4713e9520bdb8842a3f1fbfa3a0669b3e58421043df78ad</string>
|
||||
<string name="maingau_referral_link" translatable="false">https://trck.maingau-energie.de/trck/eclick/799b39cda39575dab1dcd3351abeb77b62dc33e4f9558a57</string>
|
||||
<string name="ewieeinfach_referral_link" translatable="false">https://trck.e-wie-einfach.de/trck/eclick/fca74c186b54e7287a62102a13e073be4fc963825b85f7df</string>
|
||||
<string name="eprimo_referral_link" translatable="false">https://netzwerk.uppr.de/trck/eclick/781768d2e779806b5e09229932662c14adddd69323594c52</string>
|
||||
<string name="referral_juicify" translatable="false">Juicify</string>
|
||||
<string name="referral_geldfuereauto" translatable="false">Geld für eAuto</string>
|
||||
<string name="referral_maingau" translatable="false">Maingau</string>
|
||||
<string name="referral_ewieeinfach" translatable="false">E wie einfach</string>
|
||||
<string name="referral_eprimo" translatable="false">eprimo</string>
|
||||
<string name="copyright_summary">©2020–2024 Johan von Forstner and contributors</string>
|
||||
<string name="acra_backend_url" translatable="false">https://acra.muc.vonforst.net/report</string>
|
||||
</resources>
|
||||
|
||||
@@ -110,7 +110,9 @@
|
||||
<string name="and_n_others">and %d others</string>
|
||||
<string name="pref_map_provider">Map provider</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="mastodon">Mastodon</string>
|
||||
<string name="goingelectric_forum">Forum thread at GoingElectric.de</string>
|
||||
<string name="tff_forum">Forum thread at TFF-Forum.de</string>
|
||||
<string name="contact">Contact</string>
|
||||
<string name="menu_report_new_charger">New charger</string>
|
||||
<string name="edit_at_datasource">Edit at %s</string>
|
||||
@@ -151,6 +153,7 @@
|
||||
<string name="delete">Delete</string>
|
||||
<string name="save_as_profile">Save as profile</string>
|
||||
<string name="save_profile_enter_name">Enter the name of the filter profile:</string>
|
||||
<string name="filterprofile_name_not_unique">There is already a filter profile with that name</string>
|
||||
<string name="filterprofiles_empty_state">You have no filter profiles saved</string>
|
||||
<string name="welcome_to_evmap">Welcome to EVMap</string>
|
||||
<string name="welcome_1">Find electric vehicle chargers around you</string>
|
||||
@@ -240,6 +243,7 @@
|
||||
<string name="privacy_link">https://ev-map.app/privacypolicy/</string>
|
||||
<string name="faq_link">https://ev-map.app/faq/</string>
|
||||
<string name="chargeprice_faq_link">https://ev-map.app/faq/#price-comparison-feature</string>
|
||||
<string name="referral_link">https://ev-map.app/referrals/</string>
|
||||
<string name="required">required</string>
|
||||
<string name="edit_filter_profile">Edit “%s”</string>
|
||||
<string name="pref_search_delete_recent">Delete recent search results</string>
|
||||
|
||||
@@ -39,6 +39,10 @@
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/contact">
|
||||
<Preference
|
||||
android:key="mastodon"
|
||||
android:title="@string/mastodon"
|
||||
android:summary="@string/mastodon_handle" />
|
||||
|
||||
<Preference
|
||||
android:key="twitter"
|
||||
@@ -49,6 +53,10 @@
|
||||
android:key="goingelectric"
|
||||
android:title="@string/goingelectric_forum" />
|
||||
|
||||
<Preference
|
||||
android:key="tffforum"
|
||||
android:title="@string/tff_forum" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/other">
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
android:defaultValue="goingelectric"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
|
||||
<CheckBoxPreference
|
||||
<!--<CheckBoxPreference
|
||||
android:key="prediction_enabled"
|
||||
android:title="@string/pref_prediction_enabled"
|
||||
android:defaultValue="true"
|
||||
android:summary="@string/pref_prediction_enabled_summary" />
|
||||
android:summary="@string/pref_prediction_enabled_summary" />-->
|
||||
|
||||
<Preference
|
||||
android:key="tesla_account"
|
||||
|
||||
2
fastlane/metadata/android/de-DE/changelogs/244.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/244.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Fehler behoben:
|
||||
- Abstürze behoben
|
||||
2
fastlane/metadata/android/en-US/changelogs/244.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/244.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Bugfixes:
|
||||
- Fixed crashes
|
||||
@@ -12,7 +12,7 @@
|
||||
# org.gradle.parallel=true
|
||||
#Sun Jul 24 11:49:27 CEST 2022
|
||||
kotlin.code.style=official
|
||||
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
|
||||
org.gradle.jvmargs=-Xmx4096M -Dkotlin.daemon.jvm.options\="-Xmx4096M"
|
||||
android.useAndroidX=true
|
||||
android.nonTransitiveRClass=true
|
||||
android.nonFinalResIds=true
|
||||
|
||||
Reference in New Issue
Block a user