From 984aaa36a7cd50bb7230eacd0e6b000aac3b724a Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 21 Mar 2021 19:20:50 +0200 Subject: [PATCH 001/109] init --- OsmAnd/res/layout/empty_purchases_layout.xml | 220 ++++++++++++ .../profile_preference_toolbar_with_icon.xml | 1 + OsmAnd/res/layout/purchases_layout.xml | 338 ++++++++++++++++++ OsmAnd/res/values/strings.xml | 7 + OsmAnd/res/xml/settings_main_screen.xml | 8 + .../fragments/MainSettingsFragment.java | 6 +- .../settings/fragments/PurchasesFragment.java | 101 ++++++ .../fragments/PurchasesFragmentEmpty.java | 148 ++++++++ 8 files changed, 827 insertions(+), 2 deletions(-) create mode 100644 OsmAnd/res/layout/empty_purchases_layout.xml create mode 100644 OsmAnd/res/layout/purchases_layout.xml create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java diff --git a/OsmAnd/res/layout/empty_purchases_layout.xml b/OsmAnd/res/layout/empty_purchases_layout.xml new file mode 100644 index 0000000000..7a19918581 --- /dev/null +++ b/OsmAnd/res/layout/empty_purchases_layout.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/profile_preference_toolbar_with_icon.xml b/OsmAnd/res/layout/profile_preference_toolbar_with_icon.xml index 98f2b0966d..3890b58e8f 100644 --- a/OsmAnd/res/layout/profile_preference_toolbar_with_icon.xml +++ b/OsmAnd/res/layout/profile_preference_toolbar_with_icon.xml @@ -69,6 +69,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 2bc271e8dd..74cea426f4 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,13 @@ Thx - Hardy --> + + support@osmand.net + Contact support + If your purchases don\'t show up here, tap on “Restore purchases”, or contact our support team. + If you have any questions, please contact us at %1$s. + New device / new account + You don\'t have any purchases Please select another type of colorization. The track does not contain speed data. The track does not contain altitude data. diff --git a/OsmAnd/res/xml/settings_main_screen.xml b/OsmAnd/res/xml/settings_main_screen.xml index ba31622bf4..610b675747 100644 --- a/OsmAnd/res/xml/settings_main_screen.xml +++ b/OsmAnd/res/xml/settings_main_screen.xml @@ -13,6 +13,14 @@ app:fragment="net.osmand.plus.settings.fragments.GlobalSettingsFragment" tools:icon="@drawable/ic_action_settings" /> + + diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java index 225ed389e7..1dd498a4c2 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/MainSettingsFragment.java @@ -70,10 +70,12 @@ public class MainSettingsFragment extends BaseSettingsFragment implements OnSele availableAppModes = new LinkedHashSet<>(ApplicationMode.values(getMyApplication())); Preference globalSettings = findPreference("global_settings"); globalSettings.setIcon(getContentIcon(R.drawable.ic_action_settings)); - PreferenceCategory selectedProfile = (PreferenceCategory) findPreference(SELECTED_PROFILE); + Preference purchasesSettings = findPreference("purchases_settings"); + purchasesSettings.setIcon(getContentIcon(R.drawable.ic_action_purchases)); + PreferenceCategory selectedProfile = findPreference(SELECTED_PROFILE); selectedProfile.setIconSpaceReserved(false); setupConfigureProfilePref(); - PreferenceCategory appProfiles = (PreferenceCategory) findPreference(APP_PROFILES); + PreferenceCategory appProfiles = findPreference(APP_PROFILES); appProfiles.setIconSpaceReserved(false); setupAppProfiles(appProfiles); profileManagementPref(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java new file mode 100644 index 0000000000..8f96c68fa6 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -0,0 +1,101 @@ +package net.osmand.plus.settings.fragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.google.android.material.appbar.AppBarLayout; + +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.OsmandInAppPurchaseActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; +import net.osmand.plus.inapp.InAppPurchaseHelper; + +public class PurchasesFragment extends BaseOsmAndFragment { + public static final String TAG = PurchasesFragmentEmpty.class.getName(); + private InAppPurchaseHelper purchaseHelper; + private View mainView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Context context = requireContext(); + purchaseHelper = getInAppPurchaseHelper(); + boolean nightMode = !getMyApplication().getSettings().isLightContent(); + LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); + mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); + AppBarLayout appbar = mainView.findViewById(R.id.appbar); + View toolbar = themedInflater.inflate(R.layout.profile_preference_toolbar_with_icon, container, false); + appbar.addView(toolbar); + + TextView toolbarTitle = appbar.findViewById(R.id.toolbar_title); + View iconToolbarContainer = appbar.findViewById(R.id.icon_toolbar); + toolbarTitle.setText(getString(R.string.purchases)); + ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); + icon.setImageResource(R.drawable.ic_action_help_online); + icon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Uri uri = Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + } + }); + ImageButton backButton = mainView.findViewById(R.id.close_button); + backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity fragmentActivity = getActivity(); + if (fragmentActivity != null) { + fragmentActivity.onBackPressed(); + } + } + }); + LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); + purchasesRestore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (purchaseHelper != null && !purchaseHelper.hasInventory()) { + purchaseHelper.requestInventory(); + } + } + }); + LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); + osmandLive.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// ChoosePlanDialogFragment.showOsmLiveInstance(getMyActivity().getSupportFragmentManager()); + } + }); + return mainView; + } + + @Nullable + public InAppPurchaseHelper getInAppPurchaseHelper() { + Activity activity = getActivity(); + if (activity instanceof OsmandInAppPurchaseActivity) { + return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper(); + } else { + return null; + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java new file mode 100644 index 0000000000..f3fc5621fb --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java @@ -0,0 +1,148 @@ +package net.osmand.plus.settings.fragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.graphics.Typeface; +import android.net.Uri; +import android.os.Bundle; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.StyleSpan; +import android.text.style.URLSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; + +import com.google.android.material.appbar.AppBarLayout; + +import net.osmand.AndroidUtils; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.OsmandInAppPurchaseActivity; +import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; +import net.osmand.plus.inapp.InAppPurchaseHelper; + +public class PurchasesFragmentEmpty extends BaseOsmAndFragment { + public static final String TAG = PurchasesFragmentEmpty.class.getName(); + private InAppPurchaseHelper purchaseHelper; + private View mainView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + Context context = requireContext(); + purchaseHelper = getInAppPurchaseHelper(); + boolean nightMode = !getMyApplication().getSettings().isLightContent(); + LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); + mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); + createToolbar(mainView, nightMode); + LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); + purchasesRestore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (purchaseHelper != null && !purchaseHelper.hasInventory()) { + purchaseHelper.requestInventory(); + } + } + }); + LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); + osmandLive.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); + } + }); + setFormatLink(); + return mainView; + } + + @Nullable + public InAppPurchaseHelper getInAppPurchaseHelper() { + Activity activity = getActivity(); + if (activity instanceof OsmandInAppPurchaseActivity) { + return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper(); + } else { + return null; + } + } + + private void createToolbar(View mainView, boolean nightMode) { + AppBarLayout appbar = mainView.findViewById(R.id.appbar); + View toolbar = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.profile_preference_toolbar_with_icon, appbar, false); + + View iconToolbarContainer = toolbar.findViewById(R.id.icon_toolbar); + ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); + icon.setImageResource(R.drawable.ic_action_help_online); + icon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Uri uri = Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + startActivity(intent); + } + }); + ImageButton backButton = toolbar.findViewById(R.id.close_button); + backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity fragmentActivity = getActivity(); + if (fragmentActivity != null) { + fragmentActivity.onBackPressed(); + } + } + }); + TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); + toolbarTitle.setText(getString(R.string.purchases)); + appbar.addView(toolbar); + } + + public void setFormatLink() { + TextView newDeviceAccountLink = mainView.findViewById(R.id.new_device_account_title); + TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); + TextView supportDescription = mainView.findViewById(R.id.support_link_title); + + SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); + String urlSupport = "mailto:support@osmand.net"; + spannableStringSupport.setSpan(new URLSpan(urlSupport), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + SpannableString spannableStringNewDeviceAccount = new SpannableString(getString(R.string.new_device_account)); + String urlNewDeviceAccount = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; + spannableStringNewDeviceAccount.setSpan(new URLSpan(urlNewDeviceAccount), 0, spannableStringNewDeviceAccount.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + String emailString = getString(R.string.contact_support_mail); + String supportDescriptionString = getString(R.string.contact_support_description, emailString); + SpannableString spannableStringMail = new SpannableString(supportDescriptionString); + int startIndex = supportDescriptionString.indexOf(emailString); + int endIndex = startIndex + emailString.length(); + StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); + spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + contactSupportLink.setText(spannableStringSupport); + newDeviceAccountLink.setText(spannableStringNewDeviceAccount); + supportDescription.setText(spannableStringMail); + + AndroidUtils.removeLinkUnderline(contactSupportLink); + AndroidUtils.removeLinkUnderline(newDeviceAccountLink); + + contactSupportLink.setMovementMethod(LinkMovementMethod.getInstance()); + newDeviceAccountLink.setMovementMethod(LinkMovementMethod.getInstance()); + + } + +} From ac370efcd95adbcdf8c741cc93073bdeb6577316 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 22 Mar 2021 01:48:00 +0200 Subject: [PATCH 002/109] First iteration --- OsmAnd/res/layout/purchases_layout.xml | 47 ++--- OsmAnd/res/values/attrs.xml | 1 + OsmAnd/res/values/strings.xml | 2 + OsmAnd/res/values/styles.xml | 2 + OsmAnd/res/xml/settings_main_screen.xml | 2 +- .../fragments/MainSettingsFragment.java | 3 +- .../settings/fragments/PurchasesFragment.java | 160 ++++++++++++++---- .../fragments/PurchasesFragmentEmpty.java | 4 +- 8 files changed, 163 insertions(+), 58 deletions(-) diff --git a/OsmAnd/res/layout/purchases_layout.xml b/OsmAnd/res/layout/purchases_layout.xml index dfab75ff90..b0c12c905d 100644 --- a/OsmAnd/res/layout/purchases_layout.xml +++ b/OsmAnd/res/layout/purchases_layout.xml @@ -11,21 +11,16 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> + + + - - - - + app:tint="?attr/active_color_basic_green" /> @@ -189,18 +185,14 @@ android:layout_height="wrap_content" android:layout_marginEnd="@dimen/card_button_progress_size_small" android:layout_marginRight="@dimen/card_button_progress_size_small" - android:letterSpacing="@dimen/text_button_letter_spacing" - android:text="@string/live_updates" - android:textColor="?attr/active_color_basic" - android:textSize="@dimen/default_list_text_size" - app:typeface="@string/font_roboto_medium" /> + android:letterSpacing="@dimen/description_letter_spacing" + android:text="@string/troubleshooting_description" + android:textColor="?android:textColorSecondary" + android:textSize="@dimen/default_desc_text_size" + app:typeface="@string/font_roboto_regular" /> - - + + + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 74cea426f4..b18a660072 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,8 @@ --> + Please follow this link if you any issues with purchases. + Troubleshooting support@osmand.net Contact support If your purchases don\'t show up here, tap on “Restore purchases”, or contact our support team. diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml index 7f16bc4586..81c73d5697 100644 --- a/OsmAnd/res/values/styles.xml +++ b/OsmAnd/res/values/styles.xml @@ -218,6 +218,7 @@ @color/divider_color_light @color/text_color_primary_light @color/active_color_primary_light + @color/profile_icon_color_green_light @color/card_and_list_background_light @color/activity_background_light @drawable/pages_bg_light @@ -519,6 +520,7 @@ @color/divider_color_dark @color/text_color_primary_dark @color/active_color_primary_dark + @color/profile_icon_color_green_dark @color/card_and_list_background_dark @color/activity_background_dark @drawable/pages_bg_dark diff --git a/OsmAnd/res/xml/settings_main_screen.xml b/OsmAnd/res/xml/settings_main_screen.xml index 610b675747..b71907f71c 100644 --- a/OsmAnd/res/xml/settings_main_screen.xml +++ b/OsmAnd/res/xml/settings_main_screen.xml @@ -18,7 +18,7 @@ android:layout="@layout/preference_with_descr" android:persistent="false" android:title="@string/purchases" - app:fragment="net.osmand.plus.settings.fragments.PurchasesFragmentEmpty" + app:fragment="net.osmand.plus.settings.fragments.PurchasesFragment" tools:icon="@drawable/ic_action_purchases" /> (ApplicationMode.values(getMyApplication())); Preference globalSettings = findPreference("global_settings"); globalSettings.setIcon(getContentIcon(R.drawable.ic_action_settings)); - Preference purchasesSettings = findPreference("purchases_settings"); + Preference purchasesSettings = findPreference(PURCHASES_SETTINGS); purchasesSettings.setIcon(getContentIcon(R.drawable.ic_action_purchases)); PreferenceCategory selectedProfile = findPreference(SELECTED_PROFILE); selectedProfile.setIconSpaceReserved(false); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index 8f96c68fa6..9fe813fa1f 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -3,8 +3,15 @@ package net.osmand.plus.settings.fragments; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.StyleSpan; +import android.text.style.URLSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,17 +26,27 @@ import androidx.fragment.app.FragmentActivity; import com.google.android.material.appbar.AppBarLayout; +import net.osmand.AndroidUtils; +import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.liveupdates.OsmLiveActivity; public class PurchasesFragment extends BaseOsmAndFragment { - public static final String TAG = PurchasesFragmentEmpty.class.getName(); + + public static final String TAG = PurchasesFragment.class.getName(); private InAppPurchaseHelper purchaseHelper; private View mainView; + private Context context; + private OsmandApplication app; + private String url; + private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; + private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; + @Override public void onCreate(Bundle savedInstanceState) { @@ -38,38 +55,15 @@ public class PurchasesFragment extends BaseOsmAndFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Context context = requireContext(); + app = getMyApplication(); + context = requireContext(); purchaseHelper = getInAppPurchaseHelper(); + final MapActivity mapActivity = (MapActivity) getActivity(); boolean nightMode = !getMyApplication().getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); - AppBarLayout appbar = mainView.findViewById(R.id.appbar); - View toolbar = themedInflater.inflate(R.layout.profile_preference_toolbar_with_icon, container, false); - appbar.addView(toolbar); - TextView toolbarTitle = appbar.findViewById(R.id.toolbar_title); - View iconToolbarContainer = appbar.findViewById(R.id.icon_toolbar); - toolbarTitle.setText(getString(R.string.purchases)); - ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); - icon.setImageResource(R.drawable.ic_action_help_online); - icon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Uri uri = Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); - } - }); - ImageButton backButton = mainView.findViewById(R.id.close_button); - backButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity fragmentActivity = getActivity(); - if (fragmentActivity != null) { - fragmentActivity.onBackPressed(); - } - } - }); + createToolbar(mainView, nightMode); LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); purchasesRestore.setOnClickListener(new View.OnClickListener() { @Override @@ -79,13 +73,28 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); - LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); - osmandLive.setOnClickListener(new View.OnClickListener() { + LinearLayout reportContainer = mainView.findViewById(R.id.report_container); + reportContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { -// ChoosePlanDialogFragment.showOsmLiveInstance(getMyActivity().getSupportFragmentManager()); + Intent intent = new Intent(mapActivity, OsmLiveActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + if (mapActivity != null) { + mapActivity.startActivity(intent); + } } }); + LinearLayout liveUpdatesContainer = mainView.findViewById(R.id.live_updates_container); + liveUpdatesContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// Fragment parent = getParentFragment(); +// if (parent != null) { +// ((LiveUpdatesFragment) parent).updateSubscriptionHeader(); +// } + } + }); + setFormatLink(); return mainView; } @@ -98,4 +107,91 @@ public class PurchasesFragment extends BaseOsmAndFragment { return null; } } + + private void createToolbar(View mainView, boolean nightMode) { + AppBarLayout appbar = mainView.findViewById(R.id.appbar); + View toolbar = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.profile_preference_toolbar_with_icon, appbar, false); + + View iconToolbarContainer = toolbar.findViewById(R.id.icon_toolbar); + ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); + icon.setImageResource(R.drawable.ic_action_help_online); + icon.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Uri uri = Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + if (AndroidUtils.isIntentSafe(context, intent)) { + startActivity(intent); + } + } + }); + ImageButton backButton = toolbar.findViewById(R.id.close_button); + backButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentActivity fragmentActivity = getActivity(); + if (fragmentActivity != null) { + fragmentActivity.onBackPressed(); + } + } + }); + getSkuAppId(); + LinearLayout manageSubscriptionContainer = mainView.findViewById(R.id.manage_subscription_container); + manageSubscriptionContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + if (AndroidUtils.isIntentSafe(context, intent)) { + startActivity(intent); + } + } + }); + TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); + toolbarTitle.setText(getString(R.string.purchases)); + appbar.addView(toolbar); + } + + public void setFormatLink() { + TextView newDeviceAccountLink = mainView.findViewById(R.id.new_device_account_title); + TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); + TextView supportDescription = mainView.findViewById(R.id.support_link_title); + + SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); + String urlSupport = "mailto:support@osmand.net"; + spannableStringSupport.setSpan(new URLSpan(urlSupport), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + SpannableString spannableStringNewDeviceAccount = new SpannableString(getString(R.string.new_device_account)); + String urlNewDeviceAccount = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; + spannableStringNewDeviceAccount.setSpan(new URLSpan(urlNewDeviceAccount), 0, spannableStringNewDeviceAccount.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + + String emailString = getString(R.string.contact_support_mail); + String supportDescriptionString = getString(R.string.contact_support_description, emailString); + SpannableString spannableStringMail = new SpannableString(supportDescriptionString); + int startIndex = supportDescriptionString.indexOf(emailString); + int endIndex = startIndex + emailString.length(); + StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); + spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + contactSupportLink.setText(spannableStringSupport); + newDeviceAccountLink.setText(spannableStringNewDeviceAccount); + supportDescription.setText(spannableStringMail); + + AndroidUtils.removeLinkUnderline(contactSupportLink); + AndroidUtils.removeLinkUnderline(newDeviceAccountLink); + + contactSupportLink.setMovementMethod(LinkMovementMethod.getInstance()); + newDeviceAccountLink.setMovementMethod(LinkMovementMethod.getInstance()); + } + + private void getSkuAppId() { + InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); + if (purchaseHelper != null) { + String sku = purchaseHelper.getFullVersion().getSku(); + url = String.format(PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL, + sku, context.getPackageName()); + } else { + url = PLAY_STORE_SUBSCRIPTION_URL; + } + } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java index f3fc5621fb..8fe8676cdc 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java @@ -65,7 +65,9 @@ public class PurchasesFragmentEmpty extends BaseOsmAndFragment { osmandLive.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); + if (getMyApplication() != null && getMyActivity() != null) { + ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); + } } }); setFormatLink(); From 8de07a2c59a42f9eecd5c5170bca4de132b0bbab Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 22 Mar 2021 14:36:32 +0200 Subject: [PATCH 003/109] Second Iteration --- OsmAnd/res/layout/purchases_layout.xml | 7 +- OsmAnd/res/xml/settings_main_screen.xml | 1 - .../fragments/MainSettingsFragment.java | 8 ++- .../settings/fragments/PurchasesFragment.java | 64 ++++++++++++------- 4 files changed, 52 insertions(+), 28 deletions(-) diff --git a/OsmAnd/res/layout/purchases_layout.xml b/OsmAnd/res/layout/purchases_layout.xml index b0c12c905d..c5f9bb471b 100644 --- a/OsmAnd/res/layout/purchases_layout.xml +++ b/OsmAnd/res/layout/purchases_layout.xml @@ -11,11 +11,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - - + android:paddingBottom="@dimen/card_padding" + android:clickable="true" + android:focusable="true"> Date: Tue, 23 Mar 2021 01:02:19 +0200 Subject: [PATCH 004/109] Review --- OsmAnd/res/layout/empty_purchases_layout.xml | 12 +- OsmAnd/res/layout/purchases_layout.xml | 25 +-- OsmAnd/res/values/attrs.xml | 2 +- OsmAnd/res/values/strings.xml | 1 - OsmAnd/res/values/styles.xml | 4 +- .../plus/activities/MapActivityActions.java | 16 -- .../settings/fragments/PurchasesFragment.java | 81 +++++++--- .../fragments/PurchasesFragmentEmpty.java | 150 ------------------ 8 files changed, 81 insertions(+), 210 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java diff --git a/OsmAnd/res/layout/empty_purchases_layout.xml b/OsmAnd/res/layout/empty_purchases_layout.xml index 7a19918581..ca7fdef2dd 100644 --- a/OsmAnd/res/layout/empty_purchases_layout.xml +++ b/OsmAnd/res/layout/empty_purchases_layout.xml @@ -12,13 +12,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - - + + + + app:tint="?attr/profile_icon_color_green" /> + + - + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index b18a660072..30b850dba0 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -14,7 +14,6 @@ Please follow this link if you any issues with purchases. Troubleshooting - support@osmand.net Contact support If your purchases don\'t show up here, tap on “Restore purchases”, or contact our support team. If you have any questions, please contact us at %1$s. diff --git a/OsmAnd/res/values/styles.xml b/OsmAnd/res/values/styles.xml index 81c73d5697..113454ae88 100644 --- a/OsmAnd/res/values/styles.xml +++ b/OsmAnd/res/values/styles.xml @@ -218,7 +218,7 @@ @color/divider_color_light @color/text_color_primary_light @color/active_color_primary_light - @color/profile_icon_color_green_light + @color/profile_icon_color_green_light @color/card_and_list_background_light @color/activity_background_light @drawable/pages_bg_light @@ -520,7 +520,7 @@ @color/divider_color_dark @color/text_color_primary_dark @color/active_color_primary_dark - @color/profile_icon_color_green_dark + @color/profile_icon_color_green_dark @color/card_and_list_background_dark @color/activity_background_dark @drawable/pages_bg_dark diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index c0fec48168..01ae04a0d8 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -1030,22 +1030,6 @@ public class MapActivityActions implements DialogProvider { }).createItem()); */ - if (Version.isGooglePlayEnabled() || Version.isHuawei() || Version.isDeveloperVersion(app)) { - optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.purchases, mapActivity) - .setId(DRAWER_OSMAND_LIVE_ID) - .setIcon(R.drawable.ic_action_purchases) - .setListener(new ItemClickListener() { - @Override - public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { - app.logEvent("drawer_osm_live_open"); - Intent intent = new Intent(mapActivity, OsmLiveActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - mapActivity.startActivity(intent); - return true; - } - }).createItem()); - } - optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.shared_string_help, mapActivity) .setId(DRAWER_HELP_ID) .setIcon(R.drawable.ic_action_help) diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index c70b7a8cc4..fccfd40d48 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -32,9 +32,11 @@ import net.osmand.AndroidUtils; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; +import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.base.BaseOsmAndFragment; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; import net.osmand.plus.liveupdates.OsmLiveActivity; @@ -43,6 +45,7 @@ import net.osmand.plus.wikipedia.WikipediaDialogFragment; public class PurchasesFragment extends BaseOsmAndFragment { public static final String TAG = PurchasesFragment.class.getName(); + public static final String KEY_IS_SUBSCRIBER = "action_is_new"; private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; private InAppPurchaseHelper purchaseHelper; @@ -50,6 +53,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { private Context context; private OsmandApplication app; private String url; + private Boolean isSubscriber; public static boolean showInstance(FragmentManager fragmentManager) { try { @@ -74,12 +78,26 @@ public class PurchasesFragment extends BaseOsmAndFragment { app = getMyApplication(); context = requireContext(); purchaseHelper = getInAppPurchaseHelper(); - - + isSubscriber = Version.isPaidVersion(app); final MapActivity mapActivity = (MapActivity) getActivity(); final boolean nightMode = !getMyApplication().getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); - mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); + + if (!isSubscriber) { + mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); + setSubscriptionClick(mapActivity); + } else { + mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); + LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); + osmandLive.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getMyApplication() != null && getMyActivity() != null) { + ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); + } + } + }); + } AndroidUtils.addStatusBarPadding21v(getActivity(), mainView); createToolbar(mainView, nightMode); mainView.setOnTouchListener(new View.OnTouchListener() { @@ -87,7 +105,6 @@ public class PurchasesFragment extends BaseOsmAndFragment { return true; } }); - LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); purchasesRestore.setOnClickListener(new View.OnClickListener() { @Override @@ -97,6 +114,33 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); + LinearLayout newDeviceAccountContainer = mainView.findViewById(R.id.new_device_account_container); + newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + WikipediaDialogFragment.showFullArticle(context, Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"), nightMode); + } + }); + + setFormatLink(); + return mainView; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(KEY_IS_SUBSCRIBER, isSubscriber); + } + + @Override + public void onViewStateRestored(@Nullable Bundle savedInstanceState) { + super.onViewStateRestored(savedInstanceState); + if (savedInstanceState != null) { + savedInstanceState.getBoolean(KEY_IS_SUBSCRIBER); + } + } + + private void setSubscriptionClick(final MapActivity mapActivity) { LinearLayout reportContainer = mainView.findViewById(R.id.report_container); reportContainer.setOnClickListener(new View.OnClickListener() { @Override @@ -118,16 +162,18 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); - LinearLayout newDeviceAccountContainer = mainView.findViewById(R.id.new_device_account_container); - newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { + getSkuAppId(); + LinearLayout manageSubscriptionContainer = mainView.findViewById(R.id.manage_subscription_container); + manageSubscriptionContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - WikipediaDialogFragment.showFullArticle(context, Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"), nightMode); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + if (AndroidUtils.isIntentSafe(context, intent)) { + startActivity(intent); + } } }); - - setFormatLink(); - return mainView; } @Nullable @@ -163,18 +209,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); - getSkuAppId(); - LinearLayout manageSubscriptionContainer = mainView.findViewById(R.id.manage_subscription_container); - manageSubscriptionContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - if (AndroidUtils.isIntentSafe(context, intent)) { - startActivity(intent); - } - } - }); + TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); toolbarTitle.setText(getString(R.string.purchases)); appbar.addView(toolbar); @@ -188,7 +223,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { String urlSupport = "mailto:support@osmand.net"; spannableStringSupport.setSpan(new URLSpan(urlSupport), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - String emailString = getString(R.string.contact_support_mail); + String emailString = "support@osmand.net"; String supportDescriptionString = getString(R.string.contact_support_description, emailString); SpannableString spannableStringMail = new SpannableString(supportDescriptionString); int startIndex = supportDescriptionString.indexOf(emailString); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java deleted file mode 100644 index 8fe8676cdc..0000000000 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragmentEmpty.java +++ /dev/null @@ -1,150 +0,0 @@ -package net.osmand.plus.settings.fragments; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.graphics.Typeface; -import android.net.Uri; -import android.os.Bundle; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.method.LinkMovementMethod; -import android.text.style.StyleSpan; -import android.text.style.URLSpan; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; - -import com.google.android.material.appbar.AppBarLayout; - -import net.osmand.AndroidUtils; -import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.activities.OsmandInAppPurchaseActivity; -import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; -import net.osmand.plus.inapp.InAppPurchaseHelper; - -public class PurchasesFragmentEmpty extends BaseOsmAndFragment { - public static final String TAG = PurchasesFragmentEmpty.class.getName(); - private InAppPurchaseHelper purchaseHelper; - private View mainView; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - Context context = requireContext(); - purchaseHelper = getInAppPurchaseHelper(); - boolean nightMode = !getMyApplication().getSettings().isLightContent(); - LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); - mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); - createToolbar(mainView, nightMode); - LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); - purchasesRestore.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (purchaseHelper != null && !purchaseHelper.hasInventory()) { - purchaseHelper.requestInventory(); - } - } - }); - LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); - osmandLive.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getMyApplication() != null && getMyActivity() != null) { - ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); - } - } - }); - setFormatLink(); - return mainView; - } - - @Nullable - public InAppPurchaseHelper getInAppPurchaseHelper() { - Activity activity = getActivity(); - if (activity instanceof OsmandInAppPurchaseActivity) { - return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper(); - } else { - return null; - } - } - - private void createToolbar(View mainView, boolean nightMode) { - AppBarLayout appbar = mainView.findViewById(R.id.appbar); - View toolbar = UiUtilities.getInflater(getContext(), nightMode).inflate(R.layout.profile_preference_toolbar_with_icon, appbar, false); - - View iconToolbarContainer = toolbar.findViewById(R.id.icon_toolbar); - ImageView icon = iconToolbarContainer.findViewById(R.id.profile_icon); - icon.setImageResource(R.drawable.ic_action_help_online); - icon.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Uri uri = Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivity(intent); - } - }); - ImageButton backButton = toolbar.findViewById(R.id.close_button); - backButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity fragmentActivity = getActivity(); - if (fragmentActivity != null) { - fragmentActivity.onBackPressed(); - } - } - }); - TextView toolbarTitle = toolbar.findViewById(R.id.toolbar_title); - toolbarTitle.setText(getString(R.string.purchases)); - appbar.addView(toolbar); - } - - public void setFormatLink() { - TextView newDeviceAccountLink = mainView.findViewById(R.id.new_device_account_title); - TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); - TextView supportDescription = mainView.findViewById(R.id.support_link_title); - - SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); - String urlSupport = "mailto:support@osmand.net"; - spannableStringSupport.setSpan(new URLSpan(urlSupport), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - SpannableString spannableStringNewDeviceAccount = new SpannableString(getString(R.string.new_device_account)); - String urlNewDeviceAccount = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; - spannableStringNewDeviceAccount.setSpan(new URLSpan(urlNewDeviceAccount), 0, spannableStringNewDeviceAccount.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - String emailString = getString(R.string.contact_support_mail); - String supportDescriptionString = getString(R.string.contact_support_description, emailString); - SpannableString spannableStringMail = new SpannableString(supportDescriptionString); - int startIndex = supportDescriptionString.indexOf(emailString); - int endIndex = startIndex + emailString.length(); - StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); - spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - - contactSupportLink.setText(spannableStringSupport); - newDeviceAccountLink.setText(spannableStringNewDeviceAccount); - supportDescription.setText(spannableStringMail); - - AndroidUtils.removeLinkUnderline(contactSupportLink); - AndroidUtils.removeLinkUnderline(newDeviceAccountLink); - - contactSupportLink.setMovementMethod(LinkMovementMethod.getInstance()); - newDeviceAccountLink.setMovementMethod(LinkMovementMethod.getInstance()); - - } - -} From 294bc53ecde2393e25337226aad07a87c5921fd4 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 23 Mar 2021 14:01:11 +0200 Subject: [PATCH 005/109] Minor addition strings format --- OsmAnd/res/values/strings.xml | 2 +- .../plus/settings/fragments/PurchasesFragment.java | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 30b850dba0..1117181317 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -15,7 +15,7 @@ Please follow this link if you any issues with purchases. Troubleshooting Contact support - If your purchases don\'t show up here, tap on “Restore purchases”, or contact our support team. + If your purchases don\'t show up here, tap on “%1$s”, or contact our support team. If you have any questions, please contact us at %1$s. New device / new account You don\'t have any purchases diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index fccfd40d48..32b0bf2f38 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -122,7 +122,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { } }); - setFormatLink(); + setFormatStrings(); return mainView; } @@ -215,9 +215,14 @@ public class PurchasesFragment extends BaseOsmAndFragment { appbar.addView(toolbar); } - public void setFormatLink() { + public void setFormatStrings() { TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); TextView supportDescription = mainView.findViewById(R.id.support_link_title); + TextView infoDescription = mainView.findViewById(R.id.info_description); + + String restorePurchases = getString(R.string.restore_purchases); + String infoPurchases = String.format(getString(R.string.empty_purchases_description), restorePurchases); + infoDescription.setText(infoPurchases); SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); String urlSupport = "mailto:support@osmand.net"; From edc741e84fcec133bd3b5a553ccdb1f23f7b5ec1 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 23 Mar 2021 14:26:15 +0200 Subject: [PATCH 006/109] NPE fix --- OsmAnd/res/layout/empty_purchases_layout.xml | 8 ++++---- .../plus/settings/fragments/PurchasesFragment.java | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/layout/empty_purchases_layout.xml b/OsmAnd/res/layout/empty_purchases_layout.xml index ca7fdef2dd..56bfb82b6f 100644 --- a/OsmAnd/res/layout/empty_purchases_layout.xml +++ b/OsmAnd/res/layout/empty_purchases_layout.xml @@ -69,7 +69,7 @@ android:id="@+id/restore_purchases" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@android:drawable/list_selector_background" + android:background="?android:attr/selectableItemBackground" android:minHeight="@dimen/list_item_height" android:paddingStart="@dimen/list_content_padding" android:paddingLeft="@dimen/list_content_padding" @@ -115,7 +115,7 @@ android:id="@+id/new_device_account_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@android:drawable/list_selector_background" + android:background="?android:attr/selectableItemBackground" android:minHeight="@dimen/list_item_height" android:paddingStart="@dimen/list_content_padding" android:paddingLeft="@dimen/list_content_padding" @@ -153,7 +153,7 @@ android:id="@+id/support_link_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@android:drawable/list_selector_background" + android:background="?android:attr/selectableItemBackground" android:minHeight="@dimen/list_item_height" android:paddingStart="@dimen/list_content_padding" android:paddingLeft="@dimen/list_content_padding" @@ -189,7 +189,7 @@ android:id="@+id/contact_support_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@android:drawable/list_selector_background" + android:background="?android:attr/selectableItemBackground" android:paddingStart="@dimen/action_bar_image_side_margin" android:paddingLeft="@dimen/action_bar_image_side_margin" android:paddingTop="@dimen/card_padding" diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index 32b0bf2f38..9fb4047ca5 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -97,6 +97,11 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); + TextView infoDescription = mainView.findViewById(R.id.info_description); + + String restorePurchases = getString(R.string.restore_purchases); + String infoPurchases = String.format(getString(R.string.empty_purchases_description), restorePurchases); + infoDescription.setText(infoPurchases); } AndroidUtils.addStatusBarPadding21v(getActivity(), mainView); createToolbar(mainView, nightMode); @@ -174,6 +179,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { } } }); + } @Nullable @@ -218,11 +224,6 @@ public class PurchasesFragment extends BaseOsmAndFragment { public void setFormatStrings() { TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); TextView supportDescription = mainView.findViewById(R.id.support_link_title); - TextView infoDescription = mainView.findViewById(R.id.info_description); - - String restorePurchases = getString(R.string.restore_purchases); - String infoPurchases = String.format(getString(R.string.empty_purchases_description), restorePurchases); - infoDescription.setText(infoPurchases); SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); String urlSupport = "mailto:support@osmand.net"; From 3e4153a5cb885d7957be18ac261ffea4a5c35e9f Mon Sep 17 00:00:00 2001 From: cepprice Date: Tue, 23 Mar 2021 23:36:38 +0500 Subject: [PATCH 007/109] Add subscription card --- OsmAnd/res/drawable/bg_osmand_live_active.xml | 5 + .../res/drawable/bg_osmand_live_cancelled.xml | 5 + OsmAnd/res/drawable/btn_solid_border_dark.xml | 7 + .../res/drawable/btn_solid_border_light.xml | 7 + .../layout/dialog_edit_gpx_description.xml | 4 +- OsmAnd/res/layout/purchases_layout.xml | 586 +++++++++--------- OsmAnd/res/layout/subscription_layout.xml | 108 ++++ OsmAnd/res/layout/subscriptions_card.xml | 5 + OsmAnd/res/values/colors.xml | 2 + OsmAnd/res/values/strings.xml | 10 + .../net/osmand/plus/inapp/InAppPurchases.java | 34 +- .../settings/fragments/PurchasesFragment.java | 39 +- .../settings/fragments/SubscriptionsCard.java | 179 ++++++ .../GpxEditDescriptionDialogFragment.java | 15 +- 14 files changed, 703 insertions(+), 303 deletions(-) create mode 100644 OsmAnd/res/drawable/bg_osmand_live_active.xml create mode 100644 OsmAnd/res/drawable/bg_osmand_live_cancelled.xml create mode 100644 OsmAnd/res/drawable/btn_solid_border_dark.xml create mode 100644 OsmAnd/res/drawable/btn_solid_border_light.xml create mode 100644 OsmAnd/res/layout/subscription_layout.xml create mode 100644 OsmAnd/res/layout/subscriptions_card.xml create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java diff --git a/OsmAnd/res/drawable/bg_osmand_live_active.xml b/OsmAnd/res/drawable/bg_osmand_live_active.xml new file mode 100644 index 0000000000..8544f60004 --- /dev/null +++ b/OsmAnd/res/drawable/bg_osmand_live_active.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable/bg_osmand_live_cancelled.xml b/OsmAnd/res/drawable/bg_osmand_live_cancelled.xml new file mode 100644 index 0000000000..2774bc263a --- /dev/null +++ b/OsmAnd/res/drawable/bg_osmand_live_cancelled.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable/btn_solid_border_dark.xml b/OsmAnd/res/drawable/btn_solid_border_dark.xml new file mode 100644 index 0000000000..5f0ecb368b --- /dev/null +++ b/OsmAnd/res/drawable/btn_solid_border_dark.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/drawable/btn_solid_border_light.xml b/OsmAnd/res/drawable/btn_solid_border_light.xml new file mode 100644 index 0000000000..528f174597 --- /dev/null +++ b/OsmAnd/res/drawable/btn_solid_border_light.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/dialog_edit_gpx_description.xml b/OsmAnd/res/layout/dialog_edit_gpx_description.xml index 66c0d57f0a..a2997960b9 100644 --- a/OsmAnd/res/layout/dialog_edit_gpx_description.xml +++ b/OsmAnd/res/layout/dialog_edit_gpx_description.xml @@ -45,7 +45,7 @@ osmand:typeface="@string/font_roboto_medium" /> - + android:layout_height="match_parent"> - - - + android:orientation="vertical"> - + - + - + - + - + - + - + - + - + - + - + - - + - + - + - + - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/subscription_layout.xml b/OsmAnd/res/layout/subscription_layout.xml new file mode 100644 index 0000000000..de35b80f4a --- /dev/null +++ b/OsmAnd/res/layout/subscription_layout.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OsmAnd/res/layout/subscriptions_card.xml b/OsmAnd/res/layout/subscriptions_card.xml new file mode 100644 index 0000000000..278f381933 --- /dev/null +++ b/OsmAnd/res/layout/subscriptions_card.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/OsmAnd/res/values/colors.xml b/OsmAnd/res/values/colors.xml index 410723dc79..8d9f9dc24a 100644 --- a/OsmAnd/res/values/colors.xml +++ b/OsmAnd/res/values/colors.xml @@ -75,6 +75,8 @@ #d28521 #237bff #d28521 + #14CC70 + #EE5622 #505050 diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 1117181317..3e81d699c3 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,16 @@ --> + Expired + On hold + In grace period + Renew subscription + Cancelled + Next billing date: %1$s + Three months subscription + Monthly subscription + Annual subscription + OsmAnd Live Please follow this link if you any issues with purchases. Troubleshooting Contact support diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java index e6ec431187..8a6d5a0128 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java @@ -8,8 +8,10 @@ import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import net.osmand.AndroidUtils; import net.osmand.Period; @@ -580,24 +582,40 @@ public abstract class InAppPurchases { private InAppSubscriptionIntroductoryInfo introductoryInfo; public enum SubscriptionState { - UNDEFINED("undefined"), - ACTIVE("active"), - CANCELLED("cancelled"), - IN_GRACE_PERIOD("in_grace_period"), - ON_HOLD("on_hold"), - PAUSED("paused"), - EXPIRED("expired"); + UNDEFINED("undefined", 0, 0), + ACTIVE("active", R.string.osm_live_active, R.drawable.bg_osmand_live_active), + CANCELLED("cancelled", R.string.osmand_live_cancelled, R.drawable.bg_osmand_live_cancelled), + IN_GRACE_PERIOD("in_grace_period", R.string.in_grace_period, R.drawable.bg_osmand_live_active), + ON_HOLD("on_hold", R.string.on_hold, R.drawable.bg_osmand_live_cancelled), + PAUSED("paused", R.string.shared_string_paused, R.drawable.bg_osmand_live_cancelled), + EXPIRED("expired", R.string.expired, R.drawable.bg_osmand_live_cancelled); private final String stateStr; + @StringRes + private final int stringRes; + @DrawableRes + private final int backgroundRes; - SubscriptionState(@NonNull String stateStr) { + SubscriptionState(@NonNull String stateStr, @StringRes int stringRes, @DrawableRes int backgroundRes) { this.stateStr = stateStr; + this.stringRes = stringRes; + this.backgroundRes = backgroundRes; } public String getStateStr() { return stateStr; } + @StringRes + public int getStringRes() { + return stringRes; + } + + @DrawableRes + public int getBackgroundRes() { + return backgroundRes; + } + @NonNull public static SubscriptionState getByStateStr(@NonNull String stateStr) { for (SubscriptionState state : SubscriptionState.values()) { diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index 9fb4047ca5..6b5a9c5d5f 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -38,11 +38,12 @@ import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.wikipedia.WikipediaDialogFragment; -public class PurchasesFragment extends BaseOsmAndFragment { +public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurchaseListener { public static final String TAG = PurchasesFragment.class.getName(); public static final String KEY_IS_SUBSCRIBER = "action_is_new"; @@ -50,6 +51,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; private InAppPurchaseHelper purchaseHelper; private View mainView; + private SubscriptionsCard subscriptionsCard; private Context context; private OsmandApplication app; private String url; @@ -83,9 +85,14 @@ public class PurchasesFragment extends BaseOsmAndFragment { final boolean nightMode = !getMyApplication().getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); - if (!isSubscriber) { + if (isSubscriber) { mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); setSubscriptionClick(mapActivity); + if (mapActivity != null && purchaseHelper != null) { + ViewGroup subscriptionsCardContainer = mainView.findViewById(R.id.subscriptions_card_container); + subscriptionsCard = new SubscriptionsCard(mapActivity, purchaseHelper); + subscriptionsCardContainer.addView(subscriptionsCard.build(mapActivity)); + } } else { mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); @@ -114,7 +121,7 @@ public class PurchasesFragment extends BaseOsmAndFragment { purchasesRestore.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (purchaseHelper != null && !purchaseHelper.hasInventory()) { + if (purchaseHelper != null) { purchaseHelper.requestInventory(); } } @@ -255,4 +262,30 @@ public class PurchasesFragment extends BaseOsmAndFragment { url = PLAY_STORE_SUBSCRIPTION_URL; } } + + @Override + public void onError(InAppPurchaseHelper.InAppPurchaseTaskType taskType, String error) { + } + + @Override + public void onGetItems() { + if (subscriptionsCard != null) { + subscriptionsCard.update(); + } + } + + @Override + public void onItemPurchased(String sku, boolean active) { + if (purchaseHelper != null) { + purchaseHelper.requestInventory(); + } + } + + @Override + public void showProgress(InAppPurchaseHelper.InAppPurchaseTaskType taskType) { + } + + @Override + public void dismissProgress(InAppPurchaseHelper.InAppPurchaseTaskType taskType) { + } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java new file mode 100644 index 0000000000..40ef081602 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -0,0 +1,179 @@ +package net.osmand.plus.settings.fragments; + +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import net.osmand.AndroidUtils; +import net.osmand.Period; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.util.Algorithms; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import androidx.annotation.NonNull; +import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.content.ContextCompat; + +public class SubscriptionsCard extends BaseCard { + + private final InAppPurchaseHelper purchaseHelper; + + @Override + public int getCardLayoutId() { + return R.layout.subscriptions_card; + } + + public SubscriptionsCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper) { + super(mapActivity); + this.purchaseHelper = purchaseHelper; + } + + @Override + protected void updateContent() { + if (mapActivity == null) { + return; + } + + List subscriptions = getActiveAndCancelledSubscriptions(); + if (Algorithms.isEmpty(subscriptions)) { + return; + } + + ContextThemeWrapper ctx = new ContextThemeWrapper(mapActivity, !nightMode ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme); + LayoutInflater inflater = LayoutInflater.from(ctx); + ((ViewGroup) view).removeAllViews(); + + for (int i = 0; i < subscriptions.size(); i++) { + InAppSubscription subscription = subscriptions.get(i); + SubscriptionState state = subscription.getState(); + boolean autoRenewed = SubscriptionState.ACTIVE.equals(state) || SubscriptionState.IN_GRACE_PERIOD.equals(state); + + View card = inflater.inflate(R.layout.subscription_layout, null, false); + ((ViewGroup) view).addView(card); + + TextView subscriptionPeriod = card.findViewById(R.id.subscription_type); + String period = getSubscriptionPeriod(subscription.getSubscriptionPeriod()); + if (!Algorithms.isEmpty(period)) { + subscriptionPeriod.setText(period); + AndroidUiHelper.updateVisibility(subscriptionPeriod, true); + } + + if (autoRenewed) { + TextView nextBillingDate = card.findViewById(R.id.next_billing_date); + String date = getHumanDate(subscription.getPurchaseTime(), subscription.getSubscriptionPeriod()); + if (!Algorithms.isEmpty(date)) { + nextBillingDate.setText(app.getString(R.string.next_billing_date, date)); + AndroidUiHelper.updateVisibility(nextBillingDate, true); + } + } + + TextView status = card.findViewById(R.id.status); + status.setText(app.getString(state.getStringRes())); + status.setBackgroundDrawable(ContextCompat.getDrawable(mapActivity, state.getBackgroundRes())); + + if (!autoRenewed) { + View renewContainer = card.findViewById(R.id.renewContainer); + AndroidUiHelper.updateVisibility(renewContainer, true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AndroidUtils.setBackground(ctx, renewContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); + } else { + AndroidUtils.setBackground(ctx, renewContainer, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); + } + final String sku = subscription.getSku(); + renewContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + subscribe(sku); + } + }); + + View renew = card.findViewById(R.id.renew); + AndroidUtils.setBackground(ctx, renew, nightMode, + R.drawable.btn_solid_border_light, R.drawable.btn_solid_border_dark); + } + + int dividerLayout = i + 1 == subscriptions.size() ? R.layout.simple_divider_item : R.layout.divider_half_item; + View divider = inflater.inflate(dividerLayout, (ViewGroup) view, false); + ((ViewGroup) view).addView(divider); + } + } + + private String getHumanDate(long time, Period period) { + Date date = new Date(time); + int monthsCount; + if (period == null || period.getUnit() == null) { + return ""; + } else if (period.getUnit().equals(Period.PeriodUnit.YEAR)) { + monthsCount = 12; + } else { + monthsCount = period.getNumberOfUnits(); + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.MONTH, monthsCount); + date = calendar.getTime(); + SimpleDateFormat format = new SimpleDateFormat("MMM d, yyyy", app.getLocaleHelper().getPreferredLocale()); + return format.format(date); + } + + private void subscribe(String sku) { + if (app == null) { + return; + } + if (!app.getSettings().isInternetConnectionAvailable(true)) { + Toast.makeText(app, R.string.internet_not_available, Toast.LENGTH_LONG).show(); + } else if (mapActivity != null && purchaseHelper != null) { + OsmandSettings settings = app.getSettings(); + purchaseHelper.purchaseLiveUpdates(mapActivity, sku, + settings.BILLING_USER_EMAIL.get(), + settings.BILLING_USER_NAME.get(), + settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(), + settings.BILLING_HIDE_USER_NAME.get()); + } + } + + private String getSubscriptionPeriod(Period period) { + if (period == null || period.getUnit() == null) { + return ""; + } else if (period.getUnit().equals(Period.PeriodUnit.YEAR)) { + return app.getString(R.string.annual_subscription); + } else if (period.getUnit().equals(Period.PeriodUnit.MONTH)) { + int unitsNumber = period.getNumberOfUnits(); + if (unitsNumber == 1) { + return app.getString(R.string.monthly_subscription); + } else if (unitsNumber == 3) { + return app.getString(R.string.three_months_subscription); + } + } + return ""; + } + + private List getActiveAndCancelledSubscriptions() { + List subscriptions = new ArrayList<>(); + for (InAppSubscription subscription : purchaseHelper.getLiveUpdates().getVisibleSubscriptions()) { + if (shouldShowSubscription(subscription)) { + subscriptions.add(subscription); + } + } + return subscriptions; + } + + private boolean shouldShowSubscription(InAppSubscription s) { + return s.getState() != null && !SubscriptionState.UNDEFINED.equals(s.getState()); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java b/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java index b8ef1c24d2..52536316b8 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java @@ -110,9 +110,8 @@ public class GpxEditDescriptionDialogFragment extends BaseOsmAndDialogFragment { } private void setupSaveButton(View view) { - View btnSave = view.findViewById(R.id.btn_save); - - btnSave.setOnClickListener(new View.OnClickListener() { + View btnSaveContainer = view.findViewById(R.id.btn_save_container); + btnSaveContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Editable editable = editableHtml.getText(); @@ -122,12 +121,16 @@ public class GpxEditDescriptionDialogFragment extends BaseOsmAndDialogFragment { } }); - Context ctx = btnSave.getContext(); + Context ctx = btnSaveContainer.getContext(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - AndroidUtils.setBackground(ctx, btnSave, isNightMode(true), R.drawable.ripple_light, R.drawable.ripple_dark); + AndroidUtils.setBackground(ctx, btnSaveContainer, isNightMode(true), R.drawable.ripple_light, R.drawable.ripple_dark); } else { - AndroidUtils.setBackground(ctx, btnSave, isNightMode(true), R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); + AndroidUtils.setBackground(ctx, btnSaveContainer, isNightMode(true), R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); } + + View btnSave = view.findViewById(R.id.btn_save); + int drawableRes = isNightMode(true) ? R.drawable.btn_solid_border_dark : R.drawable.btn_solid_border_light; + btnSave.setBackgroundDrawable(ContextCompat.getDrawable(ctx, drawableRes)); } private void showDismissDialog() { From 03f0f19caef2f496a4630f58b6b436c12c668583 Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 24 Mar 2021 02:41:47 +0500 Subject: [PATCH 008/109] Add UI of support region setting --- OsmAnd/res/layout/purchases_layout.xml | 66 ++++++++++ .../plus/inapp/InAppPurchaseHelper.java | 12 ++ .../liveupdates/CountrySelectionFragment.java | 2 + .../plus/liveupdates/LiveUpdatesFragment.java | 26 +--- .../liveupdates/SubscriptionFragment.java | 2 +- .../settings/fragments/PurchasesFragment.java | 121 +++++++++++++++--- .../settings/fragments/SubscriptionsCard.java | 18 +-- 7 files changed, 192 insertions(+), 55 deletions(-) diff --git a/OsmAnd/res/layout/purchases_layout.xml b/OsmAnd/res/layout/purchases_layout.xml index 306f37f690..2140d2cc5c 100644 --- a/OsmAnd/res/layout/purchases_layout.xml +++ b/OsmAnd/res/layout/purchases_layout.xml @@ -1,6 +1,8 @@ + + + + + + + + + + + + + + + + + + getEverMadeSubscriptions() { + List subscriptions = new ArrayList<>(); + for (InAppSubscription subscription : getLiveUpdates().getVisibleSubscriptions()) { + SubscriptionState state = subscription.getState(); + if (state != null && !SubscriptionState.UNDEFINED.equals(state)) { + subscriptions.add(subscription); + } + } + return subscriptions; + } + public abstract void isInAppPurchaseSupported(@NonNull final Activity activity, @Nullable final InAppPurchaseInitCallback callback); public boolean hasInventory() { diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/CountrySelectionFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/CountrySelectionFragment.java index f070559121..9c29e9762b 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/CountrySelectionFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/CountrySelectionFragment.java @@ -35,6 +35,8 @@ import java.util.List; public class CountrySelectionFragment extends BaseOsmAndDialogFragment { + public static final String TAG = CountrySelectionFragment.class.getSimpleName(); + private List countryItems = new ArrayList<>(); private OnFragmentInteractionListener mListener; diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 02bdad0a43..631b1a7f07 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -49,6 +49,7 @@ import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.resources.IncrementalChangesManager; +import net.osmand.plus.settings.fragments.PurchasesFragment; import net.osmand.util.Algorithms; import java.io.File; @@ -181,28 +182,9 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc statusTextView.setText(getString(R.string.osm_live_active)); statusIcon.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_done)); - regionNameHeaderTextView.setText(R.string.osm_live_support_region); - String countryName = app.getSettings().BILLING_USER_COUNTRY.get(); - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); - if (monthlyPurchased != null && monthlyPurchased.isDonationSupported()) { - if (Algorithms.isEmpty(countryName)) { - if (app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.get().equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER)) { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); - } else { - countryName = getString(R.string.shared_string_world); - } - } - } else { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); - } - } else { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); - } + String countryName = PurchasesFragment.getSupportRegionName(app, getInAppPurchaseHelper()); + String header = PurchasesFragment.getSupportRegionHeader(app, countryName); + regionNameHeaderTextView.setText(header); regionNameTextView.setText(countryName); View subscriptionsButton = subscriptionHeader.findViewById(R.id.button_subscriptions); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java index a2afb3d933..b73bf20c6e 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java @@ -177,7 +177,7 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In CountrySelectionFragment countryCountrySelectionFragment = countrySelectionFragment; countryCountrySelectionFragment - .show(getChildFragmentManager(), "CountriesSearchSelectionFragment"); + .show(getChildFragmentManager(), CountrySelectionFragment.TAG); } return false; } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index 6b5a9c5d5f..af834f73b8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -21,11 +21,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - import com.google.android.material.appbar.AppBarLayout; import net.osmand.AndroidUtils; @@ -39,21 +34,37 @@ import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.liveupdates.CountrySelectionFragment; +import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem; +import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener; import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; import net.osmand.plus.liveupdates.OsmLiveActivity; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.wikipedia.WikipediaDialogFragment; +import net.osmand.util.Algorithms; -public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurchaseListener { +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + +public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurchaseListener, OnFragmentInteractionListener { public static final String TAG = PurchasesFragment.class.getName(); public static final String KEY_IS_SUBSCRIBER = "action_is_new"; private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; + + private OsmandApplication app; + private Context context; private InAppPurchaseHelper purchaseHelper; + private View mainView; private SubscriptionsCard subscriptionsCard; - private Context context; - private OsmandApplication app; + + private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment(); + private String url; private Boolean isSubscriber; @@ -79,20 +90,14 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { app = getMyApplication(); context = requireContext(); - purchaseHelper = getInAppPurchaseHelper(); isSubscriber = Version.isPaidVersion(app); - final MapActivity mapActivity = (MapActivity) getActivity(); - final boolean nightMode = !getMyApplication().getSettings().isLightContent(); + final MapActivity mapActivity = getMapActivity(); + final boolean nightMode = !app.getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); if (isSubscriber) { mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); setSubscriptionClick(mapActivity); - if (mapActivity != null && purchaseHelper != null) { - ViewGroup subscriptionsCardContainer = mainView.findViewById(R.id.subscriptions_card_container); - subscriptionsCard = new SubscriptionsCard(mapActivity, purchaseHelper); - subscriptionsCardContainer.addView(subscriptionsCard.build(mapActivity)); - } } else { mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); @@ -138,6 +143,21 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha return mainView; } + @Override + public void onResume() { + super.onResume(); + purchaseHelper = getInAppPurchaseHelper(); + if (isSubscriber) { + MapActivity mapActivity = getMapActivity(); + if (getMapActivity() != null && purchaseHelper != null) { + ViewGroup subscriptionsCardContainer = mainView.findViewById(R.id.subscriptions_card_container); + subscriptionsCard = new SubscriptionsCard(mapActivity, purchaseHelper); + subscriptionsCardContainer.addView(subscriptionsCard.build(mapActivity)); + } + setupSupportRegion(); + } + } + @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); @@ -189,6 +209,54 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha } + private void setupSupportRegion() { + String region = getSupportRegionName(app, purchaseHelper); + String header = getSupportRegionHeader(app, region); + TextView supportRegionHeader = mainView.findViewById(R.id.support_region_header); + TextView supportRegion = mainView.findViewById(R.id.support_region); + supportRegionHeader.setText(header); + supportRegion.setText(region); + + View supportRegionContainer = mainView.findViewById(R.id.support_region_container); + supportRegionContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CountrySelectionFragment countryCountrySelectionFragment = countrySelectionFragment; + countryCountrySelectionFragment.show(getChildFragmentManager(), CountrySelectionFragment.TAG); + } + }); + + countrySelectionFragment.initCountries(app); + } + + public static String getSupportRegionName(OsmandApplication app, InAppPurchaseHelper purchaseHelper) { + OsmandSettings settings = app.getSettings(); + String countryName = settings.BILLING_USER_COUNTRY.get(); + if (purchaseHelper != null) { + InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); + if (monthlyPurchased != null && monthlyPurchased.isDonationSupported()) { + if (Algorithms.isEmpty(countryName)) { + if (OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER.equals(settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get())) { + countryName = app.getString(R.string.osmand_team); + } else { + countryName = app.getString(R.string.shared_string_world); + } + } + } else { + countryName = app.getString(R.string.osmand_team); + } + } else { + countryName = app.getString(R.string.osmand_team); + } + return countryName; + } + + public static String getSupportRegionHeader(OsmandApplication app, String supportRegion) { + return supportRegion.equals(app.getString(R.string.osmand_team)) ? + app.getString(R.string.default_buttons_support) : + app.getString(R.string.osm_live_support_region); + } + @Nullable public InAppPurchaseHelper getInAppPurchaseHelper() { Activity activity = getActivity(); @@ -263,6 +331,23 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha } } + @Override + public void onSearchResult(CountryItem selectedCountryItem) { + String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : ""; + String countryDownloadName = selectedCountryItem != null ? + selectedCountryItem.getDownloadName() : OsmandSettings.BILLING_USER_DONATION_WORLD_PARAMETER; + + OsmandApplication app = getMyApplication(); + if (app != null) { + TextView supportRegionHeader = mainView.findViewById(R.id.support_region_header); + TextView supportRegion = mainView.findViewById(R.id.support_region); + supportRegionHeader.setText(getSupportRegionHeader(app, countryName)); + supportRegion.setText(countryName); + app.getSettings().BILLING_USER_COUNTRY.set(countryName); + app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName); + } + } + @Override public void onError(InAppPurchaseHelper.InAppPurchaseTaskType taskType, String error) { } @@ -288,4 +373,8 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha @Override public void dismissProgress(InAppPurchaseHelper.InAppPurchaseTaskType taskType) { } + + private MapActivity getMapActivity() { + return (MapActivity) getActivity(); + } } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index 40ef081602..c8c0d5202b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -45,11 +45,11 @@ public class SubscriptionsCard extends BaseCard { @Override protected void updateContent() { - if (mapActivity == null) { + if (mapActivity == null || purchaseHelper == null) { return; } - List subscriptions = getActiveAndCancelledSubscriptions(); + List subscriptions = purchaseHelper.getEverMadeSubscriptions(); if (Algorithms.isEmpty(subscriptions)) { return; } @@ -162,18 +162,4 @@ public class SubscriptionsCard extends BaseCard { } return ""; } - - private List getActiveAndCancelledSubscriptions() { - List subscriptions = new ArrayList<>(); - for (InAppSubscription subscription : purchaseHelper.getLiveUpdates().getVisibleSubscriptions()) { - if (shouldShowSubscription(subscription)) { - subscriptions.add(subscription); - } - } - return subscriptions; - } - - private boolean shouldShowSubscription(InAppSubscription s) { - return s.getState() != null && !SubscriptionState.UNDEFINED.equals(s.getState()); - } } \ No newline at end of file From a8bca97b0b402d1941060e76cf1ed435f79e9c08 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 24 Mar 2021 01:40:52 +0200 Subject: [PATCH 009/109] Rtl fix xml and Announcement time --- .../layout-land/fragment_measurement_tool.xml | 4 +- OsmAnd/res/layout/account_details.xml | 8 +++- .../res/layout/add_new_favorite_category.xml | 8 +++- OsmAnd/res/layout/adjust_speed_slider.xml | 4 +- ...om_sheet_item_description_with_padding.xml | 4 +- ...ttom_sheet_item_edit_with_recyclerview.xml | 4 +- .../res/layout/bottom_sheet_item_progress.xml | 4 +- ...bottom_sheet_item_slider_with_two_text.xml | 8 +++- ...eet_item_with_descr_radio_and_icon_btn.xml | 4 +- ...escr_switch_and_additional_button_56dp.xml | 4 +- OsmAnd/res/layout/custom_color_picker.xml | 4 +- OsmAnd/res/layout/dashboard_toolbar.xml | 24 ++++++++--- OsmAnd/res/layout/dialog_button_with_icon.xml | 3 +- .../layout/download_description_button.xml | 4 +- .../res/layout/enough_space_warning_card.xml | 8 +++- OsmAnd/res/layout/follow_track_card.xml | 4 +- OsmAnd/res/layout/fragment_import.xml | 8 +++- .../res/layout/fragment_measurement_tool.xml | 4 +- OsmAnd/res/layout/fragment_opr_login.xml | 12 ++++-- OsmAnd/res/layout/fragment_terrain.xml | 8 +++- ...global_preferences_toolbar_with_switch.xml | 4 +- OsmAnd/res/layout/gpx_item_list_header.xml | 4 +- .../res/layout/gpx_list_item_tab_content.xml | 4 +- OsmAnd/res/layout/gpx_overview_fragment.xml | 4 +- OsmAnd/res/layout/group_description_item.xml | 8 +++- OsmAnd/res/layout/import_track_card.xml | 4 +- .../layout/item_header_export_expand_list.xml | 4 +- OsmAnd/res/layout/item_info_fragment.xml | 4 +- OsmAnd/res/layout/map_hud_bottom.xml | 4 +- OsmAnd/res/layout/map_marker_item_header.xml | 4 +- .../layout/navigate_track_options_card.xml | 4 +- .../res/layout/navigation_profiles_card.xml | 4 +- .../online_routing_preference_segment.xml | 12 ++++-- OsmAnd/res/layout/opr_add_photo.xml | 4 +- .../layout/plan_route_threshold_slider.xml | 8 +++- .../res/layout/point_editor_fragment_new.xml | 40 ++++++++++++++----- .../layout/profile_data_list_item_group.xml | 8 +++- .../layout/quick_action_add_dialog_header.xml | 4 +- .../layout/quick_action_add_dialog_item.xml | 4 +- OsmAnd/res/layout/quick_action_list_item.xml | 8 +++- .../res/layout/radio_buttons_with_descr.xml | 4 +- .../layout/read_wikipedia_ofline_banner.xml | 8 +++- .../res/layout/recalculation_angle_dialog.xml | 4 +- OsmAnd/res/layout/select_folder_row.xml | 4 +- OsmAnd/res/layout/send_gpx_fragment.xml | 12 ++++-- OsmAnd/res/layout/send_osm_note_fragment.xml | 4 +- OsmAnd/res/layout/send_poi_fragment.xml | 4 +- OsmAnd/res/layout/settings_group_title.xml | 4 +- OsmAnd/res/layout/track_appearance.xml | 4 +- OsmAnd/res/layout/track_menu.xml | 4 +- OsmAnd/res/layout/track_split_interval.xml | 4 +- OsmAnd/res/layout/track_width_card.xml | 4 +- .../res/layout/wikivoyage_travel_gpx_card.xml | 8 +++- OsmAnd/res/layout/zoom_levels_with_descr.xml | 4 +- .../routing/data/AnnounceTimeDistances.java | 25 ++++++------ 55 files changed, 269 insertions(+), 99 deletions(-) diff --git a/OsmAnd/res/layout-land/fragment_measurement_tool.xml b/OsmAnd/res/layout-land/fragment_measurement_tool.xml index 4ed0e425e3..505e680262 100644 --- a/OsmAnd/res/layout-land/fragment_measurement_tool.xml +++ b/OsmAnd/res/layout-land/fragment_measurement_tool.xml @@ -160,7 +160,9 @@ android:paddingRight="@dimen/measurement_tool_text_button_padding_small" android:text="@string/shared_string_options" android:textColor="?attr/color_dialog_buttons" - osmand:typeface="@string/font_roboto_medium" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/measurement_tool_text_button_padding_small" + android:paddingStart="@dimen/measurement_tool_text_button_padding_small" /> + osmand:srcCompat="@drawable/ic_action_user_account" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + android:orientation="vertical" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + android:paddingBottom="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding_small" + android:layout_marginEnd="@dimen/content_padding_small" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml b/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml index b6516e85ff..9a5aec71e8 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_description_with_padding.xml @@ -8,7 +8,9 @@ android:paddingBottom="@dimen/content_padding_small" android:minHeight="@dimen/card_row_min_height" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="wrap_content" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + android:layout_marginRight="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + android:paddingBottom="@dimen/content_padding_small" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml b/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml index f386e8c59f..fc8cb6a41e 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_slider_with_two_text.xml @@ -11,7 +11,9 @@ android:layout_height="wrap_content" android:gravity="center_vertical" android:paddingLeft="@dimen/content_padding" - android:paddingRight="@dimen/content_padding"> + android:paddingRight="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding"> + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml b/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml index c4dc6d4265..c0cacc0b79 100644 --- a/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml +++ b/OsmAnd/res/layout/bottom_sheet_item_with_descr_radio_and_icon_btn.xml @@ -90,7 +90,9 @@ android:paddingLeft="@dimen/content_padding" android:paddingRight="@dimen/content_padding" android:layout_width="wrap_content" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + tools:src="@drawable/ic_action_info_dark" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/custom_color_picker.xml b/OsmAnd/res/layout/custom_color_picker.xml index f2133e410b..c48205c25e 100644 --- a/OsmAnd/res/layout/custom_color_picker.xml +++ b/OsmAnd/res/layout/custom_color_picker.xml @@ -6,7 +6,9 @@ android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="@dimen/content_padding" - android:paddingRight="@dimen/content_padding"> + android:paddingRight="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding"> + tools:visibility="gone" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" /> + app:srcCompat="@drawable/ic_configure_screen_dark" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" /> + app:srcCompat="@drawable/ic_action_done" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" /> + app:srcCompat="@drawable/ic_sort_waypoint_dark" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" /> + android:visibility="gone" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" /> + android:visibility="gone" + android:layout_marginEnd="@dimen/multi_selection_menu_padding_top" + android:layout_marginStart="@dimen/multi_selection_menu_padding_top" /> diff --git a/OsmAnd/res/layout/dialog_button_with_icon.xml b/OsmAnd/res/layout/dialog_button_with_icon.xml index 264f884495..6a80553e49 100644 --- a/OsmAnd/res/layout/dialog_button_with_icon.xml +++ b/OsmAnd/res/layout/dialog_button_with_icon.xml @@ -13,7 +13,8 @@ android:layout_marginRight="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding" android:layout_marginBottom="@dimen/content_padding_small" - tools:ignore="UselessParent"> + tools:ignore="UselessParent" + android:layout_marginEnd="@dimen/content_padding"> \ No newline at end of file + tools:text="@string/read_more" + android:paddingStart="@dimen/content_padding_half" + android:paddingEnd="@dimen/content_padding_half" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/enough_space_warning_card.xml b/OsmAnd/res/layout/enough_space_warning_card.xml index 3fcbb69bac..6b85dcb27c 100644 --- a/OsmAnd/res/layout/enough_space_warning_card.xml +++ b/OsmAnd/res/layout/enough_space_warning_card.xml @@ -20,7 +20,9 @@ android:layout_marginLeft="@dimen/content_padding" android:layout_marginTop="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding" - app:srcCompat="@drawable/ic_action_sdcard_warning_colored" /> + app:srcCompat="@drawable/ic_action_sdcard_warning_colored" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + android:orientation="vertical" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + tools:listitem="@layout/point_editor_icon_category_item" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + tools:visibility="visible" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + android:layout_marginBottom="@dimen/content_padding_half" + android:layout_marginEnd="@dimen/content_padding_half" + android:layout_marginStart="@dimen/content_padding_half"> + android:paddingRight="@dimen/measurement_tool_button_margin" + android:paddingStart="@dimen/measurement_tool_button_margin" + android:paddingEnd="@dimen/measurement_tool_button_margin"> + app:typeface="@string/font_roboto_medium" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + app:typeface="@string/font_roboto_regular" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> @@ -73,7 +77,9 @@ android:layout_marginTop="@dimen/content_padding_small" android:layout_marginRight="@dimen/content_padding" android:layout_marginBottom="@dimen/content_padding_small" - android:orientation="vertical"> + android:orientation="vertical" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + android:stepSize="1" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + android:stepSize="1" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + tools:text="@string/routing_settings_2" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + android:paddingBottom="@dimen/content_padding_half" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + android:paddingTop="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + tools:text="Amsterdam is the Netherlands' capital and financial, cultural and creative centre with more" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> + tools:text="@string/plugin_disabled_descr" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + android:orientation="vertical" + android:layout_marginStart="@dimen/content_padding_half" + android:layout_marginEnd="@dimen/content_padding_half" /> diff --git a/OsmAnd/res/layout/import_track_card.xml b/OsmAnd/res/layout/import_track_card.xml index 24ead3b9a6..108676e545 100644 --- a/OsmAnd/res/layout/import_track_card.xml +++ b/OsmAnd/res/layout/import_track_card.xml @@ -19,7 +19,9 @@ android:text="@string/import_track_descr" android:textAppearance="@style/TextAppearance.ContextMenuSubtitle" android:textColor="?android:textColorSecondary" - osmand:typeface="@string/font_roboto_regular" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/item_header_export_expand_list.xml b/OsmAnd/res/layout/item_header_export_expand_list.xml index a77881d33a..09fc11ad23 100644 --- a/OsmAnd/res/layout/item_header_export_expand_list.xml +++ b/OsmAnd/res/layout/item_header_export_expand_list.xml @@ -22,7 +22,9 @@ android:text="@string/export_profile_dialog_description" android:textColor="?android:textColorPrimary" android:textSize="@dimen/default_list_text_size" - app:typeface="@string/font_roboto_regular" /> + app:typeface="@string/font_roboto_regular" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + tools:text="@string/plugin_disabled_descr" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/map_hud_bottom.xml b/OsmAnd/res/layout/map_hud_bottom.xml index 629f9350a1..30acd574e9 100644 --- a/OsmAnd/res/layout/map_hud_bottom.xml +++ b/OsmAnd/res/layout/map_hud_bottom.xml @@ -76,7 +76,9 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="@dimen/dashPadding" - android:layout_marginRight="@dimen/dashPadding"/> + android:layout_marginRight="@dimen/dashPadding" + android:layout_marginStart="@dimen/dashPadding" + android:layout_marginEnd="@dimen/dashPadding" /> diff --git a/OsmAnd/res/layout/map_marker_item_header.xml b/OsmAnd/res/layout/map_marker_item_header.xml index ab0a14e08b..14e5f8e9f4 100644 --- a/OsmAnd/res/layout/map_marker_item_header.xml +++ b/OsmAnd/res/layout/map_marker_item_header.xml @@ -50,7 +50,9 @@ android:gravity="center" android:visibility="gone" android:background="?android:selectableItemBackground" - android:textColor="?attr/active_color_basic" /> + android:textColor="?attr/active_color_basic" + android:paddingEnd="@dimen/bottom_sheet_content_margin" + android:paddingStart="@dimen/bottom_sheet_content_margin" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + android:text="@string/navigation_profile" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> + android:visibility="gone" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding"> + android:visibility="gone" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + android:visibility="gone" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + android:text="@string/add_photos_descr" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> \ No newline at end of file diff --git a/OsmAnd/res/layout/plan_route_threshold_slider.xml b/OsmAnd/res/layout/plan_route_threshold_slider.xml index 54fd7609d8..6d742b3c47 100644 --- a/OsmAnd/res/layout/plan_route_threshold_slider.xml +++ b/OsmAnd/res/layout/plan_route_threshold_slider.xml @@ -12,7 +12,9 @@ android:layout_height="wrap_content" android:paddingTop="@dimen/content_padding_small" android:paddingLeft="@dimen/content_padding" - android:paddingRight="@dimen/content_padding"> + android:paddingRight="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/point_editor_fragment_new.xml b/OsmAnd/res/layout/point_editor_fragment_new.xml index 6beccf0dd7..b146b2ea1e 100644 --- a/OsmAnd/res/layout/point_editor_fragment_new.xml +++ b/OsmAnd/res/layout/point_editor_fragment_new.xml @@ -58,7 +58,9 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/content_padding" - android:layout_marginRight="@dimen/content_padding"> + android:layout_marginRight="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding"> + app:hintAnimationEnabled="false" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding"> + android:background="?attr/dashboard_divider" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + app:hintAnimationEnabled="false" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_medium" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + osmand:srcCompat="@drawable/ic_action_arrow_down" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> + android:orientation="vertical" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding"> + osmand:typeface="@string/font_roboto_medium" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + android:orientation="horizontal" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding"> + android:padding="@dimen/content_padding_small" + android:layout_marginEnd="@dimen/dashCardMargin" + android:layout_marginStart="@dimen/dashCardMargin"> + android:padding="@dimen/content_padding_small" + android:layout_marginEnd="@dimen/dashCardMargin" + android:layout_marginStart="@dimen/dashCardMargin"> + tools:text="@string/pass_whole_track_descr" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> diff --git a/OsmAnd/res/layout/read_wikipedia_ofline_banner.xml b/OsmAnd/res/layout/read_wikipedia_ofline_banner.xml index 1093ad41f1..4e27debe49 100644 --- a/OsmAnd/res/layout/read_wikipedia_ofline_banner.xml +++ b/OsmAnd/res/layout/read_wikipedia_ofline_banner.xml @@ -16,7 +16,9 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_marginLeft="@dimen/content_padding" - android:layout_marginRight="@dimen/content_padding"> + android:layout_marginRight="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding"> + android:visibility="invisible" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding"> + android:paddingBottom="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding_small" + android:layout_marginStart="@dimen/content_padding_small" /> diff --git a/OsmAnd/res/layout/select_folder_row.xml b/OsmAnd/res/layout/select_folder_row.xml index 1d855ff70f..dccba6c9b8 100644 --- a/OsmAnd/res/layout/select_folder_row.xml +++ b/OsmAnd/res/layout/select_folder_row.xml @@ -20,7 +20,9 @@ android:text="@string/select_folder" android:textColor="?android:textColorSecondary" android:textSize="@dimen/default_desc_text_size" - osmand:typeface="@string/font_roboto_regular" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> + tools:text="@string/gpx_visibility_txt" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" /> @@ -138,7 +142,9 @@ android:paddingBottom="@dimen/context_menu_first_line_top_margin" android:textColor="?android:textColorPrimary" android:textSize="@dimen/default_desc_text_size" - osmand:typeface="@string/font_roboto_regular" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingStart="@dimen/content_padding_small" + android:paddingEnd="@dimen/content_padding_small" /> diff --git a/OsmAnd/res/layout/send_poi_fragment.xml b/OsmAnd/res/layout/send_poi_fragment.xml index 751c0b1fe8..538cc55e0b 100644 --- a/OsmAnd/res/layout/send_poi_fragment.xml +++ b/OsmAnd/res/layout/send_poi_fragment.xml @@ -57,7 +57,9 @@ android:text="@string/close_changeset" android:textColor="?android:textColorPrimary" android:textSize="@dimen/default_list_text_size" - osmand:typeface="@string/font_roboto_regular" /> + osmand:typeface="@string/font_roboto_regular" + android:paddingStart="@dimen/content_padding_small" + android:paddingEnd="@dimen/content_padding_small" /> diff --git a/OsmAnd/res/layout/settings_group_title.xml b/OsmAnd/res/layout/settings_group_title.xml index 456a3aace1..7d4fb811cd 100644 --- a/OsmAnd/res/layout/settings_group_title.xml +++ b/OsmAnd/res/layout/settings_group_title.xml @@ -70,7 +70,9 @@ android:paddingLeft="@dimen/content_padding" android:paddingTop="@dimen/content_padding_small" android:paddingRight="@dimen/content_padding" - android:paddingBottom="@dimen/content_padding_small"> + android:paddingBottom="@dimen/content_padding_small" + android:paddingStart="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding"> + android:paddingRight="@dimen/content_padding" + android:paddingEnd="@dimen/content_padding" + android:paddingStart="@dimen/content_padding"> + tools:visibility="visible" + android:layout_marginStart="@dimen/content_padding_half" + android:layout_marginEnd="@dimen/content_padding_half"> + android:stepSize="1" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> + android:stepSize="1" + android:layout_marginStart="@dimen/content_padding" + android:layout_marginEnd="@dimen/content_padding" /> + tools:text="@string/mapillary_menu_title_username" + android:paddingStart="@dimen/content_padding_small_half" + android:paddingEnd="@dimen/content_padding_small_half" /> + tools:text="@string/shared_string_profiles" + android:paddingStart="@dimen/content_padding_small_half" + android:paddingEnd="@dimen/content_padding_small_half" /> diff --git a/OsmAnd/res/layout/zoom_levels_with_descr.xml b/OsmAnd/res/layout/zoom_levels_with_descr.xml index 5cfbcde5e9..3d5b16a7df 100644 --- a/OsmAnd/res/layout/zoom_levels_with_descr.xml +++ b/OsmAnd/res/layout/zoom_levels_with_descr.xml @@ -78,7 +78,9 @@ android:layout_marginLeft="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding" android:layout_weight="1" - android:stepSize="1" /> + android:stepSize="1" + android:layout_marginEnd="@dimen/content_padding" + android:layout_marginStart="@dimen/content_padding" /> 12 m (capped by POSITIONING_TOLERANCE) - ARRIVAL_DISTANCE = (int) (Math.max(POSITIONING_TOLERANCE, DEFAULT_SPEED * 5.) * arrivalDistanceFactor); + ARRIVAL_DISTANCE = (int) (Math.max(POSITIONING_TOLERANCE, DEFAULT_SPEED * 5.) * arrivalDistanceFactor); // 20 s: car 250 m, bicycle 56 m, pedestrian 22 m OFF_ROUTE_DISTANCE = DEFAULT_SPEED * 20 * arrivalDistanceFactor; // 20 seconds @@ -175,17 +176,14 @@ public class AnnounceTimeDistances { } private boolean isDistanceLess(float currentSpeed, double dist, double etalon, float defSpeed) { - // Check triggers: + // Check triggers: // (1) distance < etalon? if (dist - voicePromptDelayTimeSec * currentSpeed <= etalon) { return true; } // (2) time_with_current_speed < etalon_time_with_default_speed? // check only if speed > 0 - if (currentSpeed > 0 && (dist / currentSpeed - voicePromptDelayTimeSec) <= etalon / defSpeed) { - return true; - } - return false; + return currentSpeed > 0 && (dist / currentSpeed - voicePromptDelayTimeSec) <= etalon / defSpeed; } public float getSpeed(Location loc) { @@ -219,7 +217,8 @@ public class AnnounceTimeDistances { // round to 5 time = (time / 5) * 5; } - builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, meter, time, second)); + BidiFormatter myBidiFormatter = BidiFormatter.getInstance(); + builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, myBidiFormatter.unicodeWrap(meter), time, myBidiFormatter.unicodeWrap(second))); } public Spannable getIntervalsDescription(OsmandApplication app) { From 3c239cae0cc206226c2cb95fa307dc6081f7dadf Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Wed, 24 Mar 2021 11:21:41 +0200 Subject: [PATCH 010/109] Api low --- .../osmand/plus/routing/data/AnnounceTimeDistances.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java index 9285cae0a0..d03d4f2c43 100644 --- a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java +++ b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java @@ -217,8 +217,13 @@ public class AnnounceTimeDistances { // round to 5 time = (time / 5) * 5; } - BidiFormatter myBidiFormatter = BidiFormatter.getInstance(); - builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, myBidiFormatter.unicodeWrap(meter), time, myBidiFormatter.unicodeWrap(second))); + BidiFormatter myBidiFormatter; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { + myBidiFormatter = BidiFormatter.getInstance(); + builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, myBidiFormatter.unicodeWrap(meter), time, myBidiFormatter.unicodeWrap(second))); + }else{ + builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, "\u200F"+meter, time, "\u200F"+second)); + } } public Spannable getIntervalsDescription(OsmandApplication app) { From 4038f430c596fb0966bdf92d5e3e657adbc65501 Mon Sep 17 00:00:00 2001 From: Skalii Date: Wed, 24 Mar 2021 15:09:13 +0200 Subject: [PATCH 011/109] add dynamic update for charts --- .../monitoring/TripRecordingBottomSheet.java | 76 +++++++----- .../TripRecordingClearDataBottomSheet.java | 4 + .../TripRecordingOptionsBottomSheet.java | 12 ++ .../plus/myplaces/GPXItemPagerAdapter.java | 84 ++++++++++++-- .../plus/track/GpxBlockStatisticsBuilder.java | 108 +++++++++--------- 5 files changed, 190 insertions(+), 94 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 8db1508454..2de4293238 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -49,6 +49,7 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.myplaces.GPXItemPagerAdapter; +import net.osmand.plus.myplaces.GPXTabItemType; import net.osmand.plus.myplaces.SegmentActionsListener; import net.osmand.plus.myplaces.SegmentGPXAdapter; import net.osmand.plus.settings.backend.OsmandSettings; @@ -69,18 +70,19 @@ import java.util.List; import static net.osmand.AndroidUtils.getSecondaryTextColorId; import static net.osmand.AndroidUtils.setPadding; import static net.osmand.plus.UiUtilities.CompoundButtonType.GLOBAL; -import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_ALTITUDE; -import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_GENERAL; -import static net.osmand.plus.track.GpxBlockStatisticsBuilder.INIT_BLOCKS_SPEED; +import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_ALTITUDE; +import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_GENERAL; +import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_SPEED; public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment implements SegmentActionsListener { public static final String TAG = TripRecordingBottomSheet.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(TripRecordingBottomSheet.class); public static final String UPDATE_TRACK_ICON = "update_track_icon"; + public static final String UPDATE_DYNAMIC_ITEMS = "update_dynamic_items"; private static final int GPS_UPDATE_INTERVAL = 1000; - private static final String[] INIT_BLOCKS_KEYS = - new String[]{INIT_BLOCKS_GENERAL, INIT_BLOCKS_ALTITUDE, INIT_BLOCKS_SPEED}; + public static final GPXTabItemType[] INIT_TAB_ITEMS = + new GPXTabItemType[]{GPX_TAB_ITEM_GENERAL, GPX_TAB_ITEM_ALTITUDE, GPX_TAB_ITEM_SPEED}; private OsmandApplication app; private OsmandSettings settings; @@ -89,16 +91,18 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl private View statusContainer; private AppCompatImageView trackAppearanceIcon; - private LinearLayout segmentsContainer; private TrackDisplayHelper displayHelper; private TrackChartPoints trackChartPoints; private GPXItemPagerAdapter graphsAdapter; + private int graphTabPosition = 0; + private ViewGroup segmentsTabs; private GpxBlockStatisticsBuilder blockStatisticsBuilder; private SelectedGpxFile selectedGpxFile; private final Handler handler = new Handler(); private Runnable updatingGPS; + private Runnable updatingGraph; private GPXFile getGPXFile() { return selectedGpxFile.getGpxFile(); @@ -151,14 +155,15 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } }); - segmentsContainer = itemView.findViewById(R.id.segments_container); - createSegmentsTabs(segmentsContainer); + setupDisplayHelper(); + segmentsTabs = itemView.findViewById(R.id.segments_container); + createSegmentsTabs(segmentsTabs); RecyclerView statBlocks = itemView.findViewById(R.id.block_statistics); blockStatisticsBuilder = new GpxBlockStatisticsBuilder(app, selectedGpxFile, nightMode); blockStatisticsBuilder.setBlocksView(statBlocks); blockStatisticsBuilder.setBlocksClickable(false); - blockStatisticsBuilder.setInitBlocksKey(INIT_BLOCKS_GENERAL); + blockStatisticsBuilder.setTabItem(GPX_TAB_ITEM_GENERAL); blockStatisticsBuilder.initStatBlocks(null, ContextCompat.getColor(app, getActiveTextColorId(nightMode))); @@ -220,6 +225,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl super.onResume(); blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded(); runUpdatingGPS(); + runUpdatingGraph(); MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(trackChartPoints); @@ -231,25 +237,28 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl super.onPause(); blockStatisticsBuilder.stopUpdatingStatBlocks(); stopUpdatingGPS(); + stopUpdatingGraph(); MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { mapActivity.getMapLayers().getGpxLayer().setTrackChartPoints(null); } } - public void show() { + public void show(String... keys) { Dialog dialog = getDialog(); if (dialog != null) { dialog.show(); } - } - - public void show(String... keys) { - show(); for (String key : keys) { if (key.equals(UPDATE_TRACK_ICON)) { updateTrackIcon(app, trackAppearanceIcon); } + if (key.equals(UPDATE_DYNAMIC_ITEMS)) { + blockStatisticsBuilder.stopUpdatingStatBlocks(); + blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded(); + stopUpdatingGraph(); + runUpdatingGraph(); + } } } @@ -276,26 +285,37 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl handler.post(updatingGPS); } - private void recreateStatBlocks(String initBlocksKey) { - blockStatisticsBuilder.stopUpdatingStatBlocks(); - blockStatisticsBuilder.setInitBlocksKey(initBlocksKey); - blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded(); + public void stopUpdatingGraph() { + handler.removeCallbacks(updatingGraph); + } + + public void runUpdatingGraph() { + updatingGraph = new Runnable() { + @Override + public void run() { + int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); + graphsAdapter.setGpxItem(GpxUiHelper.makeGpxDisplayItem(app, displayHelper.getGpx())); + graphsAdapter.fetchTabTypesIfNeeded(INIT_TAB_ITEMS); + graphsAdapter.updateGraph(graphTabPosition); + AndroidUiHelper.updateVisibility(segmentsTabs, graphsAdapter.isVisible()); + handler.postDelayed(this, Math.max(GPS_UPDATE_INTERVAL, interval)); + } + }; + handler.post(updatingGraph); } private void setupDisplayHelper() { displayHelper = new TrackDisplayHelper(app); + GPXFile gpxFile = getGPXFile(); if (!selectedGpxFile.isShowCurrentTrack()) { - File file = new File(getGPXFile().path); + File file = new File(gpxFile.path); displayHelper.setFile(file); displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); } - displayHelper.setGpx(getGPXFile()); + displayHelper.setGpx(gpxFile); } private void createSegmentsTabs(ViewGroup viewGroup) { - viewGroup.removeAllViews(); - setupDisplayHelper(); - View segmentView = SegmentGPXAdapter.createGpxTabsView(displayHelper, viewGroup, this, nightMode); AndroidUiHelper.setVisibility(View.GONE, segmentView.findViewById(R.id.list_item_divider)); WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager); @@ -303,17 +323,19 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl tabLayout.setOnTabReselectedListener(new PagerSlidingTabStrip.OnTabReselectedListener() { @Override public void onTabSelected(int position) { - recreateStatBlocks(INIT_BLOCKS_KEYS[position]); + graphTabPosition = position; + blockStatisticsBuilder.setTabItem(INIT_TAB_ITEMS[graphTabPosition]); } @Override public void onTabReselected(int position) { - recreateStatBlocks(INIT_BLOCKS_KEYS[position]); + graphTabPosition = position; + blockStatisticsBuilder.setTabItem(INIT_TAB_ITEMS[graphTabPosition]); } }); - graphsAdapter = new GPXItemPagerAdapter(app, GpxUiHelper.makeGpxDisplayItem(app, - displayHelper.getGpx()), displayHelper, nightMode, this, true); + graphsAdapter = new GPXItemPagerAdapter(app, GpxUiHelper.makeGpxDisplayItem(app, displayHelper.getGpx()), + displayHelper, nightMode, this, true); pager.setAdapter(graphsAdapter); tabLayout.setViewPager(pager); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java index 88814e4819..e6b820fae2 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java @@ -18,6 +18,7 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import static net.osmand.AndroidUtils.getPrimaryTextColorId; +import static net.osmand.plus.monitoring.TripRecordingOptionsBottomSheet.ACTION_CLEAR_DATA; public class TripRecordingClearDataBottomSheet extends MenuBottomSheetDialogFragment implements TripRecordingBottomSheet.DismissTargetFragment { @@ -110,6 +111,9 @@ public class TripRecordingClearDataBottomSheet extends MenuBottomSheetDialogFrag @Override public void dismissTarget() { Fragment target = getTargetFragment(); + Bundle args = new Bundle(); + args.putBoolean(ACTION_CLEAR_DATA, true); + target.setArguments(args); if (target instanceof TripRecordingOptionsBottomSheet) { ((TripRecordingOptionsBottomSheet) target).dismiss(); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java index ac42775bd2..f787b5d3f1 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java @@ -34,11 +34,13 @@ import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.util.Algorithms; import static net.osmand.AndroidUtils.getPrimaryTextColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.UPDATE_DYNAMIC_ITEMS; public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragment implements TripRecordingBottomSheet.DismissTargetFragment { public static final String TAG = TripRecordingOptionsBottomSheet.class.getSimpleName(); public static final String ACTION_STOP_AND_DISMISS = "action_stop_and_discard"; + public static final String ACTION_CLEAR_DATA = "action_clear_data"; private static final int SAVE_UPDATE_INTERVAL = 1000; private OsmandApplication app; @@ -283,12 +285,22 @@ public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragme return false; } + private boolean isCleared() { + Bundle args = getArguments(); + if (args != null) { + return args.getBoolean(ACTION_CLEAR_DATA); + } + return false; + } + @Override public void dismissTarget() { Fragment target = getTargetFragment(); if (target instanceof TripRecordingBottomSheet) { if (isDiscard()) { ((TripRecordingBottomSheet) target).dismiss(); + } else if (isCleared()) { + ((TripRecordingBottomSheet) target).show(UPDATE_DYNAMIC_ITEMS); } else { ((TripRecordingBottomSheet) target).show(); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index b8899dd9c7..3f3a05e289 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -49,6 +49,8 @@ import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionI import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; +import org.apache.commons.lang3.ArrayUtils; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -62,10 +64,13 @@ import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.ALTITUDE; import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.SLOPE; import static net.osmand.plus.helpers.GpxUiHelper.LineGraphType.SPEED; import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_ALTITUDE; +import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_GENERAL; import static net.osmand.plus.myplaces.GPXTabItemType.GPX_TAB_ITEM_SPEED; public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvider, ViewAtPositionInterface { + private static final int CHART_LABEL_COUNT = 4; + private OsmandApplication app; private UiUtilities iconsCache; private TrackDisplayHelper displayHelper; @@ -83,6 +88,10 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private boolean nightMode; private boolean onlyGraphs; + public void setGpxItem(GpxDisplayItem gpxItem) { + this.gpxItem = gpxItem; + } + public GPXItemPagerAdapter(@NonNull OsmandApplication app, @NonNull GpxDisplayItem gpxItem, @NonNull TrackDisplayHelper displayHelper, @@ -117,12 +126,17 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private List getDataSets(LineChart chart, GPXTabItemType tabType, LineGraphType firstType, LineGraphType secondType) { List dataSets = dataSetsMap.get(tabType); - if (dataSets == null && chart != null) { + if (gpxItem != null) { GPXTrackAnalysis analysis = gpxItem.analysis; GpxDataItem gpxDataItem = displayHelper.getGpxDataItem(); boolean calcWithoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments(); - dataSets = GpxUiHelper.getDataSets(chart, app, analysis, firstType, secondType, calcWithoutGaps); - dataSetsMap.put(tabType, dataSets); + if (chart != null) { + dataSets = GpxUiHelper.getDataSets(chart, app, analysis, firstType, secondType, calcWithoutGaps); + if (dataSets != null) { + dataSetsMap.remove(tabType); + } + dataSetsMap.put(tabType, dataSets); + } } return dataSets; } @@ -247,7 +261,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private void setupSpeedTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { if (analysis != null && analysis.isSpeedSpecified()) { if (analysis.hasSpeedData) { - GpxUiHelper.setupGPXChart(app, chart, 4); + GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); chart.setData(new LineData(getDataSets(chart, GPX_TAB_ITEM_SPEED, SPEED, null))); updateChart(chart); chart.setVisibility(View.VISIBLE); @@ -319,7 +333,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private void setupAltitudeTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { if (analysis != null) { if (analysis.hasElevationData) { - GpxUiHelper.setupGPXChart(app, chart, 4); + GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); chart.setData(new LineData(getDataSets(chart, GPX_TAB_ITEM_ALTITUDE, ALTITUDE, SLOPE))); updateChart(chart); chart.setVisibility(View.VISIBLE); @@ -386,7 +400,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private void setupGeneralTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { if (analysis != null) { if (analysis.hasElevationData || analysis.hasSpeedData) { - GpxUiHelper.setupGPXChart(app, chart, 4); + GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); chart.setData(new LineData(getDataSets(chart, GPXTabItemType.GPX_TAB_ITEM_GENERAL, ALTITUDE, SPEED))); updateChart(chart); chart.setVisibility(View.VISIBLE); @@ -685,17 +699,65 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid void updateChart(LineChart chart) { if (chart != null && !chart.isEmpty()) { - if (gpxItem.chartMatrix != null) { - chart.getViewPortHandler().refresh(new Matrix(gpxItem.chartMatrix), chart, true); - } - if (gpxItem.chartHighlightPos != -1) { - chart.highlightValue(gpxItem.chartHighlightPos, 0); + if (gpxItem != null) { + if (gpxItem.chartMatrix != null) { + chart.getViewPortHandler().refresh(new Matrix(gpxItem.chartMatrix), chart, true); + } + if (gpxItem.chartHighlightPos != -1) { + chart.highlightValue(gpxItem.chartHighlightPos, 0); + } } else { chart.highlightValue(null); } } } + public boolean isVisible() { + for (int i = 0; i < views.size(); i++) { + if (views.get(i).findViewById(R.id.chart).getVisibility() == View.VISIBLE) { + if (tabTypes[i] == GPX_TAB_ITEM_GENERAL && (gpxItem == null || gpxItem.analysis == null)) { + return false; + } + return true; + } + } + return false; + } + + public void updateGraph(int position) { + LineGraphType firstType = tabTypes[position] == GPX_TAB_ITEM_SPEED ? SPEED : ALTITUDE; + LineGraphType secondType = null; + if (tabTypes[position] == GPX_TAB_ITEM_ALTITUDE) { + secondType = SLOPE; + } else if (tabTypes[position] == GPX_TAB_ITEM_GENERAL) { + secondType = SPEED; + } + + LineChart chart = getViewAtPosition(position).findViewById(R.id.chart); + List dataSets = getDataSets(chart, tabTypes[position], firstType, secondType); + boolean isEmptyDataSets = Algorithms.isEmpty(dataSets); + AndroidUiHelper.updateVisibility(chart, !isEmptyDataSets); + chart.clear(); + if (!isEmptyDataSets) { + chart.setData(new LineData(dataSets)); + } + if (chart.getAxisRight().getLabelCount() != CHART_LABEL_COUNT + || chart.getAxisLeft().getLabelCount() != CHART_LABEL_COUNT) { + GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); + } + updateChart(chart); + notifyDataSetChanged(); + } + + public void fetchTabTypesIfNeeded(GPXTabItemType[] tabTypes) { + if (!ArrayUtils.isEquals(this.tabTypes, tabTypes)) { + fetchTabTypes(); + for (int i = 0; i < this.tabTypes.length; i++) { + updateGraph(i); + } + } + } + private TrkSegment getTrkSegment() { for (Track track : gpxItem.group.getGpx().tracks) { if (!track.generalTrack && !gpxItem.isGeneralTrack() || track.generalTrack && gpxItem.isGeneralTrack()) { diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 96478490bb..4ffd0897f2 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -30,6 +30,7 @@ import net.osmand.plus.R; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetType; +import net.osmand.plus.myplaces.GPXTabItemType; import net.osmand.plus.myplaces.SegmentActionsListener; import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; @@ -49,10 +50,6 @@ public class GpxBlockStatisticsBuilder { private static final Log LOG = PlatformUtil.getLog(GpxBlockStatisticsBuilder.class); private static final int BLOCKS_UPDATE_INTERVAL = 1000; - public static final String INIT_BLOCKS_BASE = "init_blocks_base"; - public static final String INIT_BLOCKS_GENERAL = "init_blocks_general"; - public static final String INIT_BLOCKS_ALTITUDE = "init_blocks_altitude"; - public static final String INIT_BLOCKS_SPEED = "init_blocks_speed"; private final OsmandApplication app; private final boolean nightMode; @@ -64,7 +61,7 @@ public class GpxBlockStatisticsBuilder { private BlockStatisticsAdapter adapter; private final List items = new ArrayList<>(); private boolean blocksClickable = true; - private String initBlocksKey = INIT_BLOCKS_BASE; + private GPXTabItemType tabItem = null; private final Handler handler = new Handler(); private Runnable updatingItems; @@ -88,8 +85,8 @@ public class GpxBlockStatisticsBuilder { this.blocksView = blocksView; } - public void setInitBlocksKey(String initBlocksKey) { - this.initBlocksKey = initBlocksKey; + public void setTabItem(GPXTabItemType tabItem) { + this.tabItem = tabItem; } @Nullable @@ -154,55 +151,54 @@ public class GpxBlockStatisticsBuilder { } items.clear(); if (analysis != null) { - switch (initBlocksKey) { - case INIT_BLOCKS_GENERAL: { - float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; - float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; - Date start = new Date(analysis.startTime); - Date end = new Date(analysis.endTime); - prepareDataDistance(totalDistance); - prepareDataTimeSpan(timeSpan); - prepareDataStartTime(start); - prepareDataEndTime(end); - break; - } - case INIT_BLOCKS_ALTITUDE: { - String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app); - String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app); - String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); - String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); - prepareDataAverageAltitude(); - prepareDataAltitudeRange(min, max); - prepareDataAscent(asc); - prepareDataDescent(desc); - break; - } - case INIT_BLOCKS_SPEED: { - String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); - String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); - long timeMoving = withoutGaps ? analysis.timeMovingWithoutGaps : analysis.timeMoving; - float totalDistanceMoving = withoutGaps ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving; - prepareDataAverageSpeed(avg); - prepareDataMaximumSpeed(max); - prepareDataTimeMoving(timeMoving); - prepareDataDistanceCorrected(totalDistanceMoving); - break; - } - default: - case INIT_BLOCKS_BASE: { - float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; - String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); - String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); - String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); - String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); - float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; - prepareDataDistance(totalDistance); - prepareDataAscent(asc); - prepareDataDescent(desc); - prepareDataAverageSpeed(avg); - prepareDataMaximumSpeed(max); - prepareDataTimeSpan(timeSpan); - break; + if (tabItem == null) { + float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; + String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); + String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); + String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); + float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; + prepareDataDistance(totalDistance); + prepareDataAscent(asc); + prepareDataDescent(desc); + prepareDataAverageSpeed(avg); + prepareDataMaximumSpeed(max); + prepareDataTimeSpan(timeSpan); + } else { + switch (tabItem) { + case GPX_TAB_ITEM_GENERAL: { + float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; + float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; + Date start = new Date(analysis.startTime); + Date end = new Date(analysis.endTime); + prepareDataDistance(totalDistance); + prepareDataTimeSpan(timeSpan); + prepareDataStartTime(start); + prepareDataEndTime(end); + break; + } + case GPX_TAB_ITEM_ALTITUDE: { + String min = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app); + String max = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app); + String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); + String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + prepareDataAverageAltitude(); + prepareDataAltitudeRange(min, max); + prepareDataAscent(asc); + prepareDataDescent(desc); + break; + } + case GPX_TAB_ITEM_SPEED: { + String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); + String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); + long timeMoving = withoutGaps ? analysis.timeMovingWithoutGaps : analysis.timeMoving; + float totalDistanceMoving = withoutGaps ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving; + prepareDataAverageSpeed(avg); + prepareDataMaximumSpeed(max); + prepareDataTimeMoving(timeMoving); + prepareDataDistanceCorrected(totalDistanceMoving); + break; + } } } } From faa8503847864a41b32adfc7fc4336887996211f Mon Sep 17 00:00:00 2001 From: cepprice Date: Wed, 24 Mar 2021 22:02:32 +0500 Subject: [PATCH 012/109] Add border to gradient track line --- .../src/net/osmand/plus/views/Renderable.java | 81 +++++++++++++++---- .../osmand/plus/views/layers/GPXLayer.java | 10 +++ 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index 5053f46a69..27d741d964 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -4,6 +4,7 @@ import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; +import android.graphics.PointF; import android.graphics.Shader; import net.osmand.GPXUtilities; @@ -67,6 +68,7 @@ public class Renderable { protected double zoom = -1; protected AsynchronousResampler culler = null; // The currently active resampler protected Paint paint = null; // MUST be set by 'updateLocalPaint' before use + protected Paint borderPaint; protected GradientScaleType scaleType = null; protected GpxGeometryWay geometryWay; @@ -88,6 +90,10 @@ public class Renderable { paint.setStrokeWidth(p.getStrokeWidth()); } + public void setBorderPaint(@NonNull Paint paint) { + borderPaint = paint; + } + public void setGradientScaleType(GradientScaleType type) { this.scaleType = type; } @@ -177,33 +183,74 @@ public class Renderable { protected void drawGradient(List pts, Paint p, Canvas canvas, RotatedTileBox tileBox) { QuadRect tileBounds = tileBox.getLatLonBounds(); - Path path = new Path(); + Path currentPath = new Path(); + Path nextPath = new Path(); Paint paint = new Paint(this.paint); - WptPt prevPt = pts.get(0); + + WptPt prevWpt = pts.get(0); + WptPt currWpt = pts.get(1); + + PointF prevXY = new PointF(); + PointF currXY = new PointF(); + PointF nextXY = new PointF(); + + boolean currLineVisible = arePointsInsideTile(prevWpt, currWpt, tileBounds); + boolean nextLineVisible; + + if (currLineVisible) { + pixXYFromWptPt(tileBox, prevXY, prevWpt); + pixXYFromWptPt(tileBox, currXY, currWpt); + canvas.drawPath(pathFromStartEnd(currentPath, prevXY, currXY), borderPaint); + } + for (int i = 1; i < pts.size(); i++) { - WptPt currentPt = pts.get(i); - if (arePointsInsideTile(currentPt, prevPt, tileBounds)) { - float startX = tileBox.getPixXFromLatLon(prevPt.lat, prevPt.lon); - float startY = tileBox.getPixYFromLatLon(prevPt.lat, prevPt.lon); - float endX = tileBox.getPixXFromLatLon(currentPt.lat, currentPt.lon); - float endY = tileBox.getPixYFromLatLon(currentPt.lat, currentPt.lon); - int prevColor = prevPt.getColor(scaleType.toColorizationType()); - int currentColor = currentPt.getColor(scaleType.toColorizationType()); - LinearGradient gradient = new LinearGradient(startX, startY, endX, endY, prevColor, currentColor, Shader.TileMode.CLAMP); - paint.setShader(gradient); - path.reset(); - path.moveTo(startX, startY); - path.lineTo(endX, endY); - canvas.drawPath(path, paint); + currWpt = pts.get(i); + WptPt nextWpt = i + 1 == pts.size() ? null : pts.get(i + 1); + + nextLineVisible = arePointsInsideTile(currWpt, nextWpt, tileBounds); + if (nextWpt != null && nextLineVisible) { + pixXYFromWptPt(tileBox, currXY, currWpt); + pixXYFromWptPt(tileBox, nextXY, nextWpt); + canvas.drawPath(pathFromStartEnd(nextPath, currXY, nextXY), borderPaint); } - prevPt = currentPt; + + if (currLineVisible) { + int prevColor = prevWpt.getColor(scaleType.toColorizationType()); + int currentColor = currWpt.getColor(scaleType.toColorizationType()); + LinearGradient gradient = new LinearGradient(prevXY.x, prevXY.y, currXY.x, currXY.y, + prevColor, currentColor, Shader.TileMode.CLAMP); + paint.setShader(gradient); + canvas.drawPath(currentPath, paint); + } + + prevWpt = currWpt; + currentPath.set(nextPath); + prevXY.set(currXY); + currXY.set(nextXY); + currLineVisible = nextLineVisible; } } protected boolean arePointsInsideTile(WptPt first, WptPt second, QuadRect tileBounds) { + if (first == null || second == null) { + return false; + } return Math.min(first.lon, second.lon) < tileBounds.right && Math.max(first.lon, second.lon) > tileBounds.left && Math.min(first.lat, second.lat) < tileBounds.top && Math.max(first.lat, second.lat) > tileBounds.bottom; } + + protected PointF pixXYFromWptPt(RotatedTileBox tileBox, PointF pointF, WptPt wptPt) { + pointF.x = tileBox.getPixXFromLatLon(wptPt.lat, wptPt.lon); + pointF.y = tileBox.getPixYFromLatLon(wptPt.lat, wptPt.lon); + return pointF; + } + + protected Path pathFromStartEnd(Path path, PointF start, PointF end) { + path.reset(); + path.moveTo(start.x, start.y); + path.lineTo(end.x, end.y); + return path; + } } public static class StandardTrack extends RenderableSegment { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java index c55fb675fd..c16d687614 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/GPXLayer.java @@ -95,6 +95,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM private OsmandMapTileView view; private Paint paint; + private Paint borderPaint; private Paint shadowPaint; private Paint paintIcon; @@ -190,6 +191,13 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM paint = new Paint(); paint.setStyle(Style.STROKE); paint.setAntiAlias(true); + + borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + borderPaint.setStyle(Style.STROKE); + borderPaint.setStrokeJoin(Paint.Join.ROUND); + borderPaint.setStrokeCap(Paint.Cap.ROUND); + borderPaint.setColor(0x80000000); + shadowPaint = new Paint(); shadowPaint.setStyle(Style.STROKE); shadowPaint.setAntiAlias(true); @@ -341,6 +349,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM } paint.setColor(color == 0 ? cachedColor : color); paint.setStrokeWidth(getTrackWidth(width, defaultTrackWidth)); + borderPaint.setStrokeWidth(paint.getStrokeWidth() + AndroidUtils.dpToPx(view.getContext(), 2)); } private void acquireTrackWidth(String widthKey, RenderingRulesStorage rrs, RenderingRuleSearchRequest req, RenderingContext rc) { @@ -700,6 +709,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM updatePaints(color, width, selectedGpxFile.isRoutePoints(), currentTrack, settings, tileBox); if (ts.renderer instanceof Renderable.RenderableSegment) { Renderable.RenderableSegment renderableSegment = (Renderable.RenderableSegment) ts.renderer; + renderableSegment.setBorderPaint(borderPaint); renderableSegment.setGradientScaleType(scaleType); renderableSegment.drawSegment(view.getZoom(), paint, canvas, tileBox); } From 4d78fc77de437d60eea2e7282dac39ed1a3827d6 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Thu, 25 Mar 2021 09:52:18 +0200 Subject: [PATCH 013/109] fix replace getNonConditionalTag --- .../src/main/java/net/osmand/binary/RouteDataObject.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index b6dc2f2176..5d0f842021 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -583,8 +583,8 @@ public class RouteDataObject { String nonCondTag = rtr.getTag(); int ks; for (ks = 0; ks < pointTypes[i].length; ks++) { - RouteTypeRule toReplace = region.quickGetEncodingRule(pointTypes[i][j]); - if (toReplace != null && toReplace.getTag().contentEquals(nonCondTag)) { + RouteTypeRule toReplace = region.quickGetEncodingRule(pointTypes[i][ks]); + if (toReplace != null && toReplace.getNonConditionalTag().contentEquals(nonCondTag)) { break; } } From 11d03489cc8c7c7dcf679d24f85d778c8084fe4b Mon Sep 17 00:00:00 2001 From: Skalii Date: Thu, 25 Mar 2021 20:27:16 +0200 Subject: [PATCH 014/109] add new items "Altitude range" and "Time on motion" in gpx block statistics --- .../plus/track/GpxBlockStatisticsBuilder.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 96478490bb..8851507084 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -193,15 +193,20 @@ public class GpxBlockStatisticsBuilder { float totalDistance = withoutGaps ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; String asc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationUp, app); String desc = OsmAndFormatter.getFormattedAlt(analysis.diffElevationDown, app); + String minElevation = OsmAndFormatter.getFormattedAlt(analysis.minElevation, app); + String maxElevation = OsmAndFormatter.getFormattedAlt(analysis.maxElevation, app); String avg = OsmAndFormatter.getFormattedSpeed(analysis.avgSpeed, app); - String max = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); + String maxSpeed = OsmAndFormatter.getFormattedSpeed(analysis.maxSpeed, app); float timeSpan = withoutGaps ? analysis.timeSpanWithoutGaps : analysis.timeSpan; + long timeMoving = withoutGaps ? analysis.timeMovingWithoutGaps : analysis.timeMoving; prepareDataDistance(totalDistance); prepareDataAscent(asc); prepareDataDescent(desc); + prepareDataAltitudeRange(minElevation, maxElevation); prepareDataAverageSpeed(avg); - prepareDataMaximumSpeed(max); + prepareDataMaximumSpeed(maxSpeed); prepareDataTimeSpan(timeSpan); + prepareDataTimeMoving(timeMoving); break; } } @@ -219,8 +224,7 @@ public class GpxBlockStatisticsBuilder { } public void prepareDataAltitudeRange(String min, String max) { - String pattern = app.getString(R.string.ltr_or_rtl_combine_via_dash); - prepareData(app.getString(R.string.altitude_range), String.format(pattern, min, max), + prepareData(app.getString(R.string.altitude_range), min + " - " + max, R.drawable.ic_action_altitude_range_16, GPXDataSetType.ALTITUDE, null, ItemType.ITEM_ALTITUDE); } @@ -247,9 +251,10 @@ public class GpxBlockStatisticsBuilder { } public void prepareDataTimeMoving(long timeMoving) { - prepareData(app.getString(R.string.shared_string_time_moving), + prepareData(app.getString(initBlocksKey.equals(INIT_BLOCKS_SPEED) ? R.string.shared_string_time_moving : R.string.moving_time), Algorithms.formatDuration((int) (timeMoving / 1000), app.accessibilityEnabled()), - R.drawable.ic_action_time_span_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_MOVING); + initBlocksKey.equals(INIT_BLOCKS_SPEED) ? R.drawable.ic_action_time_span_16 : R.drawable.ic_action_time_moving_16, + GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_MOVING); } public void prepareDataDistanceCorrected(float totalDistanceMoving) { From 9cfd0f5e360b8faa5bc44b728ee3b6da17861cf5 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 25 Mar 2021 23:45:29 +0200 Subject: [PATCH 015/109] Directions: Displayed tracks, select segment doesn't show https://github.com/osmandapp/OsmAnd-Issues/issues/518 --- .../routepreparationmenu/cards/TracksCard.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java index 5becff9bad..7170847059 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java @@ -10,6 +10,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.view.ContextThemeWrapper; import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; import net.osmand.AndroidUtils; import net.osmand.GPXUtilities; @@ -20,7 +21,11 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.routepreparationmenu.FollowTrackFragment; +import net.osmand.plus.routepreparationmenu.MapRouteInfoMenuFragment; import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.track.TrackMenuFragment; +import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import java.io.File; import java.util.ArrayList; @@ -30,7 +35,7 @@ import java.util.List; public class TracksCard extends BaseCard { - private List gpxFiles; + private final List gpxFiles; private boolean showLimited = true; private static class GpxItem { @@ -127,8 +132,13 @@ public class TracksCard extends BaseCard { app.initVoiceCommandPlayer(mapActivity, mode, true, null, false, false, true); } } - mapActivity.getMapActions().setGPXRouteParams(item.file); - app.getTargetPointsHelper().updateRouteAndRefresh(true); + if (item.file.getNonEmptySegmentsCount() > 1) { + Fragment f = mapActivity.getSupportFragmentManager().findFragmentByTag(TrackMenuFragment.TAG); + TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), item.file, f); + } else { + mapActivity.getMapActions().setGPXRouteParams(item.file); + app.getTargetPointsHelper().updateRouteAndRefresh(true); + } } }); tracks.addView(v); From 8ee7cd0736ffbe0a916293db06915ea1820ab45d Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 25 Mar 2021 23:47:04 +0200 Subject: [PATCH 016/109] Remove unused import and unnecessary casting --- .../plus/routepreparationmenu/cards/TracksCard.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java index 7170847059..1abccb3382 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java @@ -21,8 +21,6 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; -import net.osmand.plus.routepreparationmenu.FollowTrackFragment; -import net.osmand.plus.routepreparationmenu.MapRouteInfoMenuFragment; import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.track.TrackSelectSegmentBottomSheet; @@ -81,7 +79,7 @@ public class TracksCard extends BaseCard { } }); - LinearLayout tracks = (LinearLayout) view.findViewById(R.id.items); + LinearLayout tracks = view.findViewById(R.id.items); tracks.removeAllViews(); int minCardHeight = app.getResources().getDimensionPixelSize(R.dimen.route_info_card_item_height); @@ -115,10 +113,10 @@ public class TracksCard extends BaseCard { ((TextView) v.findViewById(R.id.points_count)).setTextColor(descriptionColor); ((TextView) v.findViewById(R.id.time)).setTextColor(descriptionColor); - ImageView img = (ImageView) v.findViewById(R.id.icon); + ImageView img = v.findViewById(R.id.icon); img.setImageDrawable(getActiveIcon(R.drawable.ic_action_polygom_dark)); img.setVisibility(View.VISIBLE); - LinearLayout container = (LinearLayout) v.findViewById(R.id.container); + LinearLayout container = v.findViewById(R.id.container); container.setMinimumHeight(minCardHeight); AndroidUtils.setPadding(container, listContentPadding, 0, 0, 0); v.setOnClickListener(new View.OnClickListener() { @@ -134,7 +132,7 @@ public class TracksCard extends BaseCard { } if (item.file.getNonEmptySegmentsCount() > 1) { Fragment f = mapActivity.getSupportFragmentManager().findFragmentByTag(TrackMenuFragment.TAG); - TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), item.file, f); + TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), item.file, f); } else { mapActivity.getMapActions().setGPXRouteParams(item.file); app.getTargetPointsHelper().updateRouteAndRefresh(true); From eeaf45ea98a68518e4ce0d38bf70ae62daaaf79b Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Thu, 25 Mar 2021 23:56:08 +0200 Subject: [PATCH 017/109] RTL issue - Applying correct text direction (ltr or rtl) https://github.com/osmandapp/OsmAnd/issues/11212 --- .../src/net/osmand/plus/OsmAndFormatter.java | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java index 883cc908c5..10838339d0 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java @@ -3,6 +3,8 @@ package net.osmand.plus; import android.content.Context; import android.text.format.DateUtils; +import androidx.core.text.TextUtilsCompat; +import androidx.core.view.ViewCompat; import com.jwetherell.openmap.common.LatLonPoint; import com.jwetherell.openmap.common.MGRSPoint; import com.jwetherell.openmap.common.UTMPoint; @@ -37,7 +39,7 @@ public class OsmAndFormatter { public final static float METERS_IN_KILOMETER = 1000f; public final static float METERS_IN_ONE_MILE = 1609.344f; // 1609.344 public final static float METERS_IN_ONE_NAUTICALMILE = 1852f; // 1852 - + public final static float YARDS_IN_ONE_METER = 1.0936f; public final static float FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f; private static final DecimalFormat fixed2 = new DecimalFormat("0.00"); @@ -175,7 +177,7 @@ public class OsmAndFormatter { } else { generator *= 2; } - + if (point == mainUnitInMeter && metersInSecondUnit * mainUnitInMeter * 0.9f <= generator) { point = 1 / metersInSecondUnit; generator = 1; @@ -198,14 +200,14 @@ public class OsmAndFormatter { } return roundDist; } - + public static String getFormattedRoundDistanceKm(float meters, int digits, OsmandApplication ctx) { int mainUnitStr = R.string.km; float mainUnitInMeters = METERS_IN_KILOMETER; if (digits == 0) { return (int) (meters / mainUnitInMeters + 0.5) + " " + ctx.getString(mainUnitStr); //$NON-NLS-1$ } else if (digits == 1) { - return fixed1.format(((float) meters) / mainUnitInMeters) + " " + ctx.getString(mainUnitStr); + return fixed1.format(((float) meters) / mainUnitInMeters) + " " + ctx.getString(mainUnitStr); } else { return fixed2.format(((float) meters) / mainUnitInMeters) + " " + ctx.getString(mainUnitStr); } @@ -225,10 +227,10 @@ public class OsmAndFormatter { } public static String getFormattedAzimuth(float bearing, AngularConstants angularConstant) { - while(bearing < -180.0) { + while (bearing < -180.0) { bearing += 360; } - while(bearing > 360.0) { + while (bearing > 360.0) { bearing -= 360; } switch (angularConstant) { @@ -315,7 +317,7 @@ public class OsmAndFormatter { return ((int) (alt * FEET_IN_ONE_METER + 0.5)) + " " + ctx.getString(R.string.foot); } } - + public static String getFormattedSpeed(float metersperseconds, OsmandApplication ctx) { OsmandSettings settings = ctx.getSettings(); SpeedConstants mc = settings.SPEED_SYSTEM.get(); @@ -376,22 +378,22 @@ public class OsmAndFormatter { return (kmh10 / 10f) + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx); } } - - + + public static String toPublicString(CityType t, Context ctx) { switch (t) { - case CITY: - return ctx.getString(R.string.city_type_city); - case HAMLET: - return ctx.getString(R.string.city_type_hamlet); - case TOWN: - return ctx.getString(R.string.city_type_town); - case VILLAGE: - return ctx.getString(R.string.city_type_village); - case SUBURB: - return ctx.getString(R.string.city_type_suburb); - default: - break; + case CITY: + return ctx.getString(R.string.city_type_city); + case HAMLET: + return ctx.getString(R.string.city_type_hamlet); + case TOWN: + return ctx.getString(R.string.city_type_town); + case VILLAGE: + return ctx.getString(R.string.city_type_village); + case SUBURB: + return ctx.getString(R.string.city_type_suburb); + default: + break; } return ""; } @@ -402,7 +404,7 @@ public class OsmAndFormatter { String typeName = amenity.getSubType(); if (pt != null) { typeName = pt.getTranslation(); - } else if(typeName != null){ + } else if (typeName != null) { typeName = Algorithms.capitalizeFirstLetterAndLowercase(typeName.replace('_', ' ')); } String localName = amenity.getName(locale, transliterate); @@ -506,18 +508,27 @@ public class OsmAndFormatter { if (outputFormat == FORMAT_DEGREES_SHORT) { result.append(formatCoordinate(lat, outputFormat)).append(" ").append(formatCoordinate(lon, outputFormat)); } else if (outputFormat == FORMAT_DEGREES || outputFormat == FORMAT_MINUTES || outputFormat == FORMAT_SECONDS) { - result - .append(formatCoordinate(lat, outputFormat)).append(" ") - .append(lat > 0 ? NORTH : SOUTH).append(", ") - .append(formatCoordinate(lon, outputFormat)).append(" ") - .append(lon > 0 ? EAST : WEST); - } else if (outputFormat == UTM_FORMAT) { + boolean isLeftToRight = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_LTR; + if (isLeftToRight) { + result + .append(formatCoordinate(lat, outputFormat)).append(" ") + .append(lat > 0 ? NORTH : SOUTH).append(", ") + .append(formatCoordinate(lon, outputFormat)).append(" ") + .append(lon > 0 ? EAST : WEST); + } else { + result + .append(formatCoordinate(lat, outputFormat)).append(" ") + .append(lon > 0 ? EAST : WEST).append(" ") + .append(formatCoordinate(lon, outputFormat)).append(", ") + .append(lat > 0 ? NORTH : SOUTH); + } + } else if (outputFormat == UTM_FORMAT) { UTMPoint pnt = new UTMPoint(new LatLonPoint(lat, lon)); result - .append(pnt.zone_number) - .append(pnt.zone_letter).append(" ") - .append((long) pnt.easting).append(" ") - .append((long) pnt.northing); + .append(pnt.zone_number) + .append(pnt.zone_letter).append(" ") + .append((long) pnt.easting).append(" ") + .append((long) pnt.northing); } else if (outputFormat == OLC_FORMAT) { String r; try { @@ -536,21 +547,21 @@ public class OsmAndFormatter { } return result.toString(); } - + private static String formatCoordinate(double coordinate, int outputType) { - + if (coordinate < -180.0 || coordinate > 180.0 || Double.isNaN(coordinate)) { return "Error. Wrong coordinates data!"; } if ((outputType != FORMAT_DEGREES) && (outputType != FORMAT_MINUTES) && (outputType - != FORMAT_SECONDS) && (outputType != FORMAT_DEGREES_SHORT)) { - return "Unknown Output Format!"; + != FORMAT_SECONDS) && (outputType != FORMAT_DEGREES_SHORT)) { + return "Unknown Output Format!"; } DecimalFormat degDf = new DecimalFormat("##0.00000", new DecimalFormatSymbols(Locale.US)); DecimalFormat minDf = new DecimalFormat("00.000", new DecimalFormatSymbols(Locale.US)); DecimalFormat secDf = new DecimalFormat("00.0", new DecimalFormatSymbols(Locale.US)); - + StringBuilder sb = new StringBuilder(); if (coordinate < 0) { @@ -566,11 +577,11 @@ public class OsmAndFormatter { sb.append(degDf.format(coordinate)).append(DELIMITER_DEGREES); } else if (outputType == FORMAT_MINUTES) { sb.append(minDf.format(formatCoordinate(coordinate, sb, DELIMITER_DEGREES))) - .append(DELIMITER_MINUTES); + .append(DELIMITER_MINUTES); } else { sb.append(secDf.format(formatCoordinate( - formatCoordinate(coordinate, sb, DELIMITER_DEGREES), sb, DELIMITER_MINUTES))) - .append(DELIMITER_SECONDS); + formatCoordinate(coordinate, sb, DELIMITER_DEGREES), sb, DELIMITER_MINUTES))) + .append(DELIMITER_SECONDS); } return sb.toString(); } From f1aedd7ef0210881fe86736dca328f4ee6a8ce4e Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Fri, 26 Mar 2021 00:34:12 +0200 Subject: [PATCH 018/109] Fix #11045 --- .../src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java index b43171e632..be88b777a7 100644 --- a/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java +++ b/OsmAnd/src/net/osmand/plus/rastermaps/OsmandRasterMapsPlugin.java @@ -369,8 +369,10 @@ public class OsmandRasterMapsPlugin extends OsmandPlugin { settings.MAP_OVERLAY_PREVIOUS.set(null); } if (underlayLayer.getMap() == null) { + settings.MAP_UNDERLAY.removeListener(underlayListener); settings.MAP_UNDERLAY.set(null); settings.MAP_UNDERLAY_PREVIOUS.set(null); + settings.MAP_UNDERLAY.addListener(underlayListener); } String overlayMapDescr = settings.MAP_OVERLAY.get(); if (overlayMapDescr!=null && overlayMapDescr.contains(".sqlitedb")) { From 27002fd152146b33210c51203a5f73e03d3d3313 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Fri, 26 Mar 2021 01:03:37 +0200 Subject: [PATCH 019/109] Here please use ltr_or_rtl_combine_via_comma for text parts after colon (There's nothing to do with colon itself). --- .../routing/data/AnnounceTimeDistances.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java index d03d4f2c43..ea50cdf1e5 100644 --- a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java +++ b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java @@ -1,11 +1,13 @@ package net.osmand.plus.routing.data; import android.graphics.Typeface; -import android.text.BidiFormatter; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.StyleSpan; +import androidx.core.text.TextUtilsCompat; +import androidx.core.view.ViewCompat; + import net.osmand.Location; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; @@ -13,6 +15,8 @@ import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.voice.AbstractPrologCommandPlayer; +import java.util.Locale; + public class AnnounceTimeDistances { // Avoids false negatives: Pre-pone close announcements by this distance to allow for the possible over-estimation of the 'true' lead distance due to positioning error. // A smaller value will increase the timing precision, but at the risk of missing prompts which do not meet the precision limit. @@ -217,12 +221,12 @@ public class AnnounceTimeDistances { // round to 5 time = (time / 5) * 5; } - BidiFormatter myBidiFormatter; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { - myBidiFormatter = BidiFormatter.getInstance(); - builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, myBidiFormatter.unicodeWrap(meter), time, myBidiFormatter.unicodeWrap(second))); - }else{ - builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, "\u200F"+meter, time, "\u200F"+second)); + boolean isLeftToRight = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_LTR; + if (isLeftToRight) { + builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, meter, time, second)); + } else { + builder.append(String.format("\n%s: %s %d, %s %d - %d.", name, second, time, meter, minDist, minDist + 5)); + } } From 33968534fa8d63e8c181c196e2acd61059f56ba9 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Fri, 26 Mar 2021 01:55:38 +0200 Subject: [PATCH 020/109] MGRS number translate fix --- .../java/com/jwetherell/openmap/common/MGRSPoint.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java b/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java index 6e99eec8b5..be6793bef8 100644 --- a/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java +++ b/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java @@ -17,6 +17,7 @@ package com.jwetherell.openmap.common; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; public class MGRSPoint extends ZonedUTMPoint { @@ -697,10 +698,9 @@ public class MGRSPoint extends ZonedUTMPoint { all.set(1, shiftChar(all.get(1), eastShift, northShift)); String zero = ""; } - - - all.add(String.format("%0" + accuracy + "d", roundedEasting)); - all.add(String.format("%0" + accuracy + "d", roundedNorthing)); + + all.add(String.format(java.util.Locale.US,"%0" + accuracy + "d", roundedEasting)); + all.add(String.format(java.util.Locale.US,"%0" + accuracy + "d", roundedNorthing)); break; } } From ca03a530ffd4f7144f7ea8d0833587a8ed0552e8 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 03:30:28 +0200 Subject: [PATCH 021/109] some fixes; delete old fragments; fix all area after divider with switch now tappable and change switch behavior; change help icon; add new dialog "Update all maps" --- OsmAnd/res/layout/fragment_live_updates.xml | 2 +- .../list_item_triple_row_icon_and_menu.xml | 10 +- OsmAnd/res/values/strings.xml | 1 + .../download/ui/UpdatesIndexFragment.java | 12 +- ....java => LiveUpdatesClearBottomSheet.java} | 8 +- .../plus/liveupdates/LiveUpdatesFragment.java | 1011 ++++++++--------- .../liveupdates/LiveUpdatesFragmentNew.java | 706 ------------ ...va => LiveUpdatesSettingsBottomSheet.java} | 15 +- .../LiveUpdatesSettingsDialogFragment.java | 288 ----- .../LiveUpdatesUpdateAllBottomSheet.java | 132 +++ .../PerformLiveUpdateAsyncTask.java | 2 +- .../liveupdates/SubscriptionFragment.java | 6 - .../BooleanPreferenceBottomSheet.java | 2 +- .../plus/track/GpxBlockStatisticsBuilder.java | 2 +- 14 files changed, 643 insertions(+), 1554 deletions(-) rename OsmAnd/src/net/osmand/plus/liveupdates/{LiveUpdatesClearDialogFragment.java => LiveUpdatesClearBottomSheet.java} (93%) delete mode 100644 OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java rename OsmAnd/src/net/osmand/plus/liveupdates/{LiveUpdatesSettingsDialogFragmentNew.java => LiveUpdatesSettingsBottomSheet.java} (97%) delete mode 100644 OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java diff --git a/OsmAnd/res/layout/fragment_live_updates.xml b/OsmAnd/res/layout/fragment_live_updates.xml index e0fd41c95e..0f3894de1e 100644 --- a/OsmAnd/res/layout/fragment_live_updates.xml +++ b/OsmAnd/res/layout/fragment_live_updates.xml @@ -60,7 +60,7 @@ android:groupIndicator="@null" android:headerDividersEnabled="false" android:orientation="vertical" - tools:context=".liveupdates.LiveUpdatesFragmentNew" /> + tools:context=".liveupdates.LiveUpdatesFragment" /> diff --git a/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml b/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml index 1f179b8178..c030d97625 100644 --- a/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml +++ b/OsmAnd/res/layout/list_item_triple_row_icon_and_menu.xml @@ -84,12 +84,12 @@ \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index bfb443020a..5311d58c27 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ --> + Update all maps added to \"OsmAnd Live\"? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n • Tracks now could be colorizing by altitude, speed, or slope.\n\n diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index f6cf6b03cc..3bcafdbee3 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -38,8 +38,8 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; -import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesFragment; import net.osmand.plus.liveupdates.LoadLiveMapsTask; import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; @@ -58,8 +58,8 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.updateCountEnabled; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.showUpdateDialog; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.updateCountEnabled; public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates { private static final int RELOAD_ID = 5; @@ -236,7 +236,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download DownloadActivity activity = getMyActivity(); if (activity != null) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { - LiveUpdatesFragmentNew.showInstance(activity.getSupportFragmentManager(), this); + LiveUpdatesFragment.showInstance(activity.getSupportFragmentManager(), this); } } } else { @@ -397,7 +397,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download @Override public void onClick(View v) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { - showUpdateDialog(getActivity(), getMyApplication().getSettings(), + showUpdateDialog(getActivity(), getFragmentManager(), listAdapter.mapsList, listAdapter.countEnabled, null); } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java similarity index 93% rename from OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java rename to OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java index c54daada1a..dc199d61de 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesClearBottomSheet.java @@ -31,10 +31,10 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; -public class LiveUpdatesClearDialogFragment extends MenuBottomSheetDialogFragment { +public class LiveUpdatesClearBottomSheet extends MenuBottomSheetDialogFragment { - public static final String TAG = LiveUpdatesClearDialogFragment.class.getSimpleName(); - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesClearDialogFragment.class); + public static final String TAG = LiveUpdatesClearBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesClearBottomSheet.class); private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; private OsmandApplication app; @@ -44,7 +44,7 @@ public class LiveUpdatesClearDialogFragment extends MenuBottomSheetDialogFragmen public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) { if (!fragmentManager.isStateSaved()) { - LiveUpdatesClearDialogFragment fragment = new LiveUpdatesClearDialogFragment(); + LiveUpdatesClearBottomSheet fragment = new LiveUpdatesClearBottomSheet(); fragment.setTargetFragment(target, 0); fragment.fileName = fileName; fragment.show(fragmentManager, TAG); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 02bdad0a43..2536c4693f 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -4,149 +4,180 @@ import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; -import android.content.res.Resources; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.ExpandableListView; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.DrawableRes; +import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.SwitchCompat; +import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; -import androidx.fragment.app.FragmentActivity; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import net.osmand.AndroidNetworkUtils; +import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; -import net.osmand.plus.Version; -import net.osmand.plus.activities.LocalIndexHelper; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.UiUtilities.CompoundButtonType; import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; -import net.osmand.plus.activities.OsmandInAppPurchaseActivity; -import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; -import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; +import net.osmand.plus.base.BaseOsmAndDialogFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.helpers.FontCache; import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; -import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; -import net.osmand.plus.resources.IncrementalChangesManager; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; +import net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.OnLiveUpdatesForLocalChange; +import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; +import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; -import java.io.File; +import org.apache.commons.logging.Log; + +import java.lang.ref.WeakReference; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; +import java.util.Date; import java.util.List; -import java.util.Set; +import java.util.Locale; +import java.util.TimeZone; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatDateTime; +import static net.osmand.AndroidUtils.getSecondaryTextColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; +import static net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.getTertiaryTextColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getActiveTextColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getOsmandIconColorId; +import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; -public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurchaseListener { - public static final int TITLE = R.string.live_updates; - private static final int SUBSCRIPTION_SETTINGS = 5; - public static final Comparator LOCAL_INDEX_INFO_COMPARATOR = new Comparator() { +public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange { + + public static final String URL = "https://osmand.net/api/osmlive_status"; + public static final String TAG = LiveUpdatesFragment.class.getSimpleName(); + private final static Log LOG = PlatformUtil.getLog(LiveUpdatesFragment.class); + private static final String SUBSCRIPTION_URL = "https://osmand.net/features/subscription"; + + private OsmandApplication app; + private OsmandSettings settings; + private boolean nightMode; + + private View toolbarSwitchContainer; + private ExpandableListView listView; + private TextViewEx descriptionTime; + private LiveMapsAdapter adapter; + + private GetLastUpdateDateTask getLastUpdateDateTask; + private LoadLiveMapsTask loadLiveMapsTask; + + private final LiveUpdateListener liveUpdateListener = new LiveUpdateListener() { @Override - public int compare(LocalIndexInfo lhs, LocalIndexInfo rhs) { - return lhs.getName().compareTo(rhs.getName()); + public void processFinish() { + adapter.notifyDataSetChanged(); } }; - private OsmandApplication app; - private View subscriptionHeader; - private ExpandableListView listView; - private LocalIndexesAdapter adapter; - private AsyncTask> loadLocalIndexesTask; - private boolean showSettingsOnly; - - private ProgressBar progressBar; - private boolean processing; - - @Nullable - public InAppPurchaseHelper getInAppPurchaseHelper() { - Activity activity = getActivity(); - if (activity instanceof OsmandInAppPurchaseActivity) { - return ((OsmandInAppPurchaseActivity) activity).getPurchaseHelper(); - } else { - return null; + public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { + if (!fragmentManager.isStateSaved()) { + LiveUpdatesFragment fragment = new LiveUpdatesFragment(); + fragment.setTargetFragment(target, 0); + fragment.show(fragmentManager, TAG); } } - private boolean isProcessing() { - return processing; - } - @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setHasOptionsMenu(true); app = getMyApplication(); - if (getActivity() instanceof OsmLiveActivity) { - showSettingsOnly = ((OsmLiveActivity) getActivity()).isShowSettingOnly(); - } + settings = getSettings(); + nightMode = isNightMode(false); + setHasOptionsMenu(true); } @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_live_updates, container, false); - listView = (ExpandableListView) view.findViewById(android.R.id.list); - boolean nightMode = !app.getSettings().isLightContent(); - final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); - int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); - swipeRefresh.setColorSchemeColors(swipeColor); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); + toolbar.setTitle(R.string.osm_live); + int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; + Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), iconColorResId); + DrawableCompat.setTint(icBack, ContextCompat.getColor(app, iconColorResId)); + toolbar.setNavigationIcon(icBack); + toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override - public void onRefresh() { - showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null); - swipeRefresh.setRefreshing(false); + public void onClick(View v) { + dismiss(); + } + }); + ImageButton iconHelp = toolbar.findViewById(R.id.toolbar_action); + Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help_online, iconColorResId); + iconHelp.setImageDrawable(helpDrawable); + iconHelp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SUBSCRIPTION_URL)); + if (AndroidUtils.isIntentSafe(app, intent)) { + startActivity(intent); + } } }); + listView = (ExpandableListView) view.findViewById(android.R.id.list); + adapter = new LiveMapsAdapter(); + listView.setAdapter(adapter); + expandAllGroups(); + View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); - if (!showSettingsOnly) { - listView.addFooterView(bottomShadowView); - } - adapter = new LocalIndexesAdapter(this); + listView.addFooterView(bottomShadowView); listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - if (!processing && InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - final FragmentManager fragmentManager = getChildFragmentManager(); - LiveUpdatesSettingsDialogFragment - .createInstance(adapter.getChild(groupPosition, childPosition).getFileName()) - .show(fragmentManager, "settings"); + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app) && settings.IS_LIVE_UPDATES_ON.get()) { + if (getFragmentManager() != null) { + LiveUpdatesSettingsBottomSheet + .showInstance(getFragmentManager(), LiveUpdatesFragment.this, + adapter.getChild(groupPosition, childPosition).getFileName()); + } return true; } else { return false; @@ -154,345 +185,288 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc } }); - progressBar = (ProgressBar) view.findViewById(R.id.progress); - - if (!Version.isDeveloperVersion(app)) { - subscriptionHeader = inflater.inflate(R.layout.live_updates_header, listView, false); - updateSubscriptionHeader(); - listView.addHeaderView(subscriptionHeader, "subscriptionHeader", false); - } - listView.setAdapter(adapter); - - if (!showSettingsOnly) { - loadLocalIndexesTask = new LoadLocalIndexTask(adapter, this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - return view; - } - - public void updateSubscriptionHeader() { - if (getActivity() instanceof OsmLiveActivity && subscriptionHeader != null) { - View subscriptionBanner = subscriptionHeader.findViewById(R.id.subscription_banner); - View subscriptionInfo = subscriptionHeader.findViewById(R.id.subscription_info); - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - ImageView statusIcon = (ImageView) subscriptionHeader.findViewById(R.id.statusIcon); - TextView statusTextView = (TextView) subscriptionHeader.findViewById(R.id.statusTextView); - TextView regionNameHeaderTextView = (TextView) subscriptionHeader.findViewById(R.id.regionHeaderTextView); - TextView regionNameTextView = (TextView) subscriptionHeader.findViewById(R.id.regionTextView); - statusTextView.setText(getString(R.string.osm_live_active)); - statusIcon.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_done)); - - regionNameHeaderTextView.setText(R.string.osm_live_support_region); - String countryName = app.getSettings().BILLING_USER_COUNTRY.get(); - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); - if (monthlyPurchased != null && monthlyPurchased.isDonationSupported()) { - if (Algorithms.isEmpty(countryName)) { - if (app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.get().equals(OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER)) { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); - } else { - countryName = getString(R.string.shared_string_world); - } - } - } else { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); - } - } else { - regionNameHeaderTextView.setText(R.string.default_buttons_support); - countryName = getString(R.string.osmand_team); + final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); + int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); + swipeRefresh.setColorSchemeColors(swipeColor); + swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + @Override + public void onRefresh() { + if (settings.IS_LIVE_UPDATES_ON.get()) { + showUpdateDialog(getActivity(), getFragmentManager(), adapter.mapsList, + adapter.countEnabled, liveUpdateListener); + startUpdateDateAsyncTask(); } - regionNameTextView.setText(countryName); - - View subscriptionsButton = subscriptionHeader.findViewById(R.id.button_subscriptions); - View settingsButtonContainer = subscriptionHeader.findViewById(R.id.button_settings_container); - View settingsButton = subscriptionHeader.findViewById(R.id.button_settings); - subscriptionsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ChoosePlanDialogFragment.showDialogInstance(app, getActivity().getSupportFragmentManager(), ChoosePlanDialogType.OSM_LIVE); - } - }); - if (isDonationSupported()) { - settingsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - showDonationSettings(); - } - }); - settingsButtonContainer.setVisibility(View.VISIBLE); - } else { - settingsButton.setOnClickListener(null); - settingsButtonContainer.setVisibility(View.GONE); - } - - subscriptionBanner.setVisibility(View.GONE); - subscriptionInfo.setVisibility(View.VISIBLE); - } else { - Button readMoreBtn = (Button) subscriptionHeader.findViewById(R.id.read_more_button); - readMoreBtn.setEnabled(!processing); - readMoreBtn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Uri uri = Uri.parse("https://osmand.net/osm_live"); - Intent goToOsmLive = new Intent(Intent.ACTION_VIEW, uri); - startActivity(goToOsmLive); - } - }); - Button subscriptionButton = (Button) subscriptionHeader.findViewById(R.id.subscription_button); - subscriptionButton.setEnabled(!processing); - subscriptionButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity activity = getActivity(); - if (activity != null) { - ChoosePlanDialogFragment.showDialogInstance(app, activity.getSupportFragmentManager(), ChoosePlanDialogType.OSM_LIVE); - } - } - }); - - subscriptionBanner.setVisibility(View.VISIBLE); - subscriptionInfo.setVisibility(View.GONE); + swipeRefresh.setRefreshing(false); } + }); + + toolbarSwitchContainer = view.findViewById(R.id.toolbar_switch_container); + updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get()); + + View timeContainer = view.findViewById(R.id.item_import_container); + AndroidUtils.setListItemBackground(app, timeContainer, nightMode); + + AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon); + Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time, + ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); + descriptionIcon.setImageDrawable(icon); + + TextViewEx title = timeContainer.findViewById(R.id.title); + AndroidUtils.setTextSecondaryColor(app, title, nightMode); + title.setText(R.string.latest_openstreetmap_update); + title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + title.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); } + + descriptionTime = timeContainer.findViewById(R.id.sub_title); + AndroidUtils.setTextPrimaryColor(app, descriptionTime, nightMode); + Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); + descriptionTime.setTypeface(typeface); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + descriptionTime.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); + } + + return view; } @Override public void onResume() { super.onResume(); - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - if (purchaseHelper.getActiveTask() == InAppPurchaseTaskType.REQUEST_INVENTORY) { - enableProgress(); - } - } + startUpdateDateAsyncTask(); + startLoadLiveMapsAsyncTask(); } @Override - public void onDestroyView() { - super.onDestroyView(); - if (loadLocalIndexesTask != null) { - loadLocalIndexesTask.cancel(true); + public void onPause() { + super.onPause(); + stopUpdateDateAsyncTask(); + stopLoadLiveMapsAsyncTask(); + } + + @Override + public void onDismiss(@NonNull DialogInterface dialog) { + super.onDismiss(dialog); + Fragment target = getTargetFragment(); + if (target instanceof RefreshLiveUpdates) { + ((RefreshLiveUpdates) target).onUpdateStates(app); } } - public void notifyLiveUpdatesChanged() { - if (getActivity() != null && adapter != null) { - adapter.notifyLiveUpdatesChanged(); + private void startUpdateDateAsyncTask() { + getLastUpdateDateTask = new GetLastUpdateDateTask(this); + getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + private void stopUpdateDateAsyncTask() { + if (getLastUpdateDateTask != null) { + getLastUpdateDateTask.cancel(true); } } - private boolean isDonationSupported() { - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null) { - InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); - return monthlyPurchased != null && monthlyPurchased.isDonationSupported(); + private void startLoadLiveMapsAsyncTask() { + if (loadLiveMapsTask == null) { + loadLiveMapsTask = new LoadLiveMapsTask(adapter, app); + loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - return false; } - private void showDonationSettings() { - SubscriptionFragment subscriptionFragment = new SubscriptionFragment(); - subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG); + private void stopLoadLiveMapsAsyncTask() { + if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) { + loadLiveMapsTask.cancel(false); + } } - protected class LocalIndexesAdapter extends OsmandBaseExpandableListAdapter { - public static final int SHOULD_UPDATE_GROUP_POSITION = 0; - public static final int SHOULD_NOT_UPDATE_GROUP_POSITION = 1; - final ArrayList dataShouldUpdate = new ArrayList<>(); - final ArrayList dataShouldNotUpdate = new ArrayList<>(); - final LiveUpdatesFragment fragment; - final Context ctx; + private void updateToolbarSwitch(final boolean isChecked) { + int switchColor = ContextCompat.getColor(app, + isChecked ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode)); + AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(switchColor)); - public LocalIndexesAdapter(LiveUpdatesFragment fragment) { - this.fragment = fragment; - ctx = fragment.getActivity(); - } + SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); + switchView.setChecked(isChecked); + UiUtilities.setupCompoundButton(switchView, nightMode, CompoundButtonType.TOOLBAR); - public void add(LocalIndexInfo info) { - CommonPreference preference = preferenceLiveUpdatesOn( - info.getFileName(), app.getSettings()); - if (preference.get()) { - dataShouldUpdate.add(info); - } else { - dataShouldNotUpdate.add(info); + toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + boolean visible = !isChecked; + if (visible) { + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { + switchOnLiveUpdates(); + updateToolbarSwitch(true); + } else { + app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); + updateToolbarSwitch(false); + } + } else { + settings.IS_LIVE_UPDATES_ON.set(false); + enableLiveUpdates(false); + updateToolbarSwitch(false); + } + updateList(); + } + }); + + TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText); + title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled); + } + + private void switchOnLiveUpdates() { + settings.IS_LIVE_UPDATES_ON.set(true); + enableLiveUpdates(true); + showUpdateDialog(getMyActivity(), getFragmentManager(), adapter.mapsList, adapter.countEnabled, liveUpdateListener); + startUpdateDateAsyncTask(); + } + + public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, List mapsList, + int countEnabled, @Nullable LiveUpdateListener listener) { + if (!Algorithms.isEmpty(mapsList)) { + if (countEnabled == 1) { + LocalIndexInfo li = mapsList.get(0); + runLiveUpdate(context, li.getFileName(), false, listener); + } else if (countEnabled > 1) { + LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, mapsList, listener); } } + } - public void notifyLiveUpdatesChanged() { - Set changedSet = new HashSet<>(); - for (LocalIndexInfo localIndexInfo : dataShouldUpdate) { - CommonPreference preference = - preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); - if (!preference.get()) { - changedSet.add(localIndexInfo); + private void enableLiveUpdates(boolean enable) { + if (!Algorithms.isEmpty(adapter.mapsList)) { + AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); + for (LocalIndexInfo li : adapter.mapsList) { + CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); + if (localUpdateOn.get()) { + String fileName = li.getFileName(); + PendingIntent alarmIntent = getPendingIntent(app, fileName); + if (enable) { + final CommonPreference updateFrequencyPreference = + preferenceUpdateFrequency(fileName, settings); + final CommonPreference timeOfDayPreference = + preferenceTimeOfDayToUpdate(fileName, settings); + UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; + TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; + setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); + } else { + alarmMgr.cancel(alarmIntent); + } } } - dataShouldUpdate.removeAll(changedSet); - dataShouldNotUpdate.addAll(changedSet); - changedSet.clear(); - for (LocalIndexInfo localIndexInfo : dataShouldNotUpdate) { - CommonPreference preference = - preferenceLiveUpdatesOn(localIndexInfo.getFileName(), getSettings()); + } + } + + private void expandAllGroups() { + for (int i = 0; i < adapter.getGroupCount(); i++) { + listView.expandGroup(i); + } + } + + public static int updateCountEnabled(TextView countView, ArrayList mapsList, OsmandSettings settings) { + int countEnabled = 0; + if (countView != null) { + for (LocalIndexInfo map : mapsList) { + CommonPreference preference = preferenceForLocalIndex(map.getFileName(), settings); if (preference.get()) { - changedSet.add(localIndexInfo); + countEnabled++; } } - dataShouldUpdate.addAll(changedSet); - dataShouldNotUpdate.removeAll(changedSet); - notifyDataSetChanged(); - expandAllGroups(); + String countText = countEnabled + "/" + mapsList.size(); + countView.setText(countText); + } + return countEnabled; + } + + protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { + private final ArrayList mapsList = new ArrayList<>(); + private int countEnabled = 0; + private TextViewEx countView; + + @Override + public void addData(LocalIndexInfo info) { + mapsList.add(info); + } + + @Override + public void clearData() { + mapsList.clear(); + } + + @Override + public void onDataUpdated() { + sort(); + countEnabled = updateCountEnabled(countView, mapsList, settings); } public void sort() { - Collections.sort(dataShouldUpdate, LOCAL_INDEX_INFO_COMPARATOR); - Collections.sort(dataShouldNotUpdate, LOCAL_INDEX_INFO_COMPARATOR); + Collections.sort(mapsList); + Collections.sort(mapsList, new Comparator() { + @Override + public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { + CommonPreference preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings()); + CommonPreference preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings()); + return preference2.get().compareTo(preference1.get()); + } + }); + notifyDataSetInvalidated(); } @Override public LocalIndexInfo getChild(int groupPosition, int childPosition) { - if (groupPosition == 0) { - return dataShouldUpdate.get(childPosition); - } else if (groupPosition == 1) { - return dataShouldNotUpdate.get(childPosition); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } + return mapsList.get(childPosition); } @Override public long getChildId(int groupPosition, int childPosition) { - // it would be unusable to have 10000 local indexes - return groupPosition * 10000 + childPosition; + return groupPosition * 10000 + childPosition; // it would be unusable to have 10000 local indexes } @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { - LocalFullMapsViewHolder viewHolder; - if (convertView == null) { - LayoutInflater inflater = LayoutInflater.from(ctx); - convertView = inflater.inflate(R.layout.local_index_live_updates_list_item, parent, false); - viewHolder = new LocalFullMapsViewHolder(convertView, fragment); - convertView.setTag(viewHolder); - } else { - viewHolder = (LocalFullMapsViewHolder) convertView.getTag(); - } - viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName(), isLastChild); + LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); + convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); + LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); + convertView.setTag(viewHolder); + viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); return convertView; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { View view = convertView; - String group = getGroup(groupPosition); if (view == null) { - LayoutInflater inflater = LayoutInflater.from(ctx); - view = inflater.inflate(R.layout.list_group_title_with_switch, parent, false); + LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); + view = inflater.inflate(R.layout.list_group_title_with_right_descr, parent, false); } - TextView nameView = ((TextView) view.findViewById(R.id.title)); - nameView.setText(group); - view.setOnClickListener(null); - - final SwitchCompat liveUpdatesSwitch = (SwitchCompat) view.findViewById(R.id.toggle_item); View topShadowView = view.findViewById(R.id.bottomShadowView); - if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { + if (groupPosition == 0) { topShadowView.setVisibility(View.GONE); - liveUpdatesSwitch.setVisibility(View.VISIBLE); - OsmandApplication application = (OsmandApplication) ctx.getApplicationContext(); - final OsmandSettings settings = application.getSettings(); - liveUpdatesSwitch.setChecked(settings.IS_LIVE_UPDATES_ON.get()); - liveUpdatesSwitch.setEnabled(!processing); - liveUpdatesSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (isChecked) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - switchOnLiveUpdates(settings); - } else { - liveUpdatesSwitch.setChecked(false); - app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); - } - } else { - settings.IS_LIVE_UPDATES_ON.set(false); - enableLiveUpdates(false); - } - } - - - }); } else { topShadowView.setVisibility(View.VISIBLE); - liveUpdatesSwitch.setVisibility(View.GONE); } - View divider = view.findViewById(R.id.divider); - if (getChildrenCount(groupPosition) == 0) { - divider.setVisibility(View.GONE); - } else { - divider.setVisibility(View.VISIBLE); - } + TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title)); + titleView.setText(getGroup(groupPosition)); + + countView = ((TextViewEx) view.findViewById(R.id.description)); + AndroidUtils.setTextSecondaryColor(app, countView, nightMode); + return view; } - private void switchOnLiveUpdates(final OsmandSettings settings) { - settings.IS_LIVE_UPDATES_ON.set(true); - enableLiveUpdates(true); - showUpdateDialog(getActivity(), getSettings(), adapter.dataShouldUpdate, adapter.dataShouldUpdate.size(), null); - } - - private void enableLiveUpdates(boolean enable) { - AlarmManager alarmMgr = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE); - for (LocalIndexInfo li : dataShouldUpdate) { - String fileName = li.getFileName(); - PendingIntent alarmIntent = getPendingIntent(ctx, fileName); - if (enable) { - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, getSettings()); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, getSettings()); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - } - } - @Override public int getChildrenCount(int groupPosition) { - if (showSettingsOnly) { - return 0; - } else if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { - return dataShouldUpdate.size(); - } else if (groupPosition == SHOULD_NOT_UPDATE_GROUP_POSITION) { - return dataShouldNotUpdate.size(); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } + return mapsList.size(); } @Override public String getGroup(int groupPosition) { - if (groupPosition == SHOULD_UPDATE_GROUP_POSITION) { - return getString(R.string.download_live_updates); - } else if (groupPosition == SHOULD_NOT_UPDATE_GROUP_POSITION) { - return getString(R.string.available_maps); - } else { - throw new IllegalArgumentException("unexpected group position:" + groupPosition); - } + return getString(R.string.available_maps); } @Override public int getGroupCount() { - if (showSettingsOnly) { - return 0; - } else { - return dataShouldNotUpdate.size() == 0 ? 1 : 2; - } + return 1; } @Override @@ -509,226 +483,209 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } - - } - private void expandAllGroups() { - for (int i = 0; i < adapter.getGroupCount(); i++) { - listView.expandGroup(i); - } - } + private class LiveMapsViewHolder { + private final ImageView statusIcon; + private final TextView title; + private final TextView subTitle; + private final TextView description; + private final CompoundButton compoundButton; - private static class LocalFullMapsViewHolder { - private final ImageView icon; - private final TextView nameTextView; - private final TextView subheaderTextView; - private final TextView descriptionTextView; - private final ImageButton options; - private final LiveUpdatesFragment fragment; - private final int secondaryColor; - private final View divider; - - private LocalFullMapsViewHolder(View view, LiveUpdatesFragment context) { - icon = (ImageView) view.findViewById(R.id.icon); - nameTextView = (TextView) view.findViewById(R.id.nameTextView); - subheaderTextView = (TextView) view.findViewById(R.id.subheaderTextView); - descriptionTextView = (TextView) view.findViewById(R.id.descriptionTextView); - options = (ImageButton) view.findViewById(R.id.options); - this.fragment = context; - - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = context.getActivity().getTheme(); - theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true); - secondaryColor = typedValue.data; - divider = view.findViewById(R.id.divider); + private LiveMapsViewHolder(View view) { + statusIcon = (AppCompatImageView) view.findViewById(R.id.icon); + title = (TextView) view.findViewById(R.id.title); + subTitle = (TextView) view.findViewById(R.id.sub_title); + description = (TextView) view.findViewById(R.id.description); + compoundButton = (CompoundButton) view.findViewById(R.id.compound_button); } - public void bindLocalIndexInfo(@NonNull final String item, boolean isLastChild) { - OsmandApplication context = fragment.getMyActivity().getMyApplication(); - final CommonPreference shouldUpdatePreference = - preferenceLiveUpdatesOn(item, fragment.getSettings()); - IncrementalChangesManager changesManager = context.getResourceManager().getChangesManager(); + public void bindLocalIndexInfo(@NonNull final String item) { + boolean liveUpdateOn = settings.IS_LIVE_UPDATES_ON.get(); + CommonPreference localUpdateOn = preferenceForLocalIndex(item, settings); +// IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager(); + compoundButton.setChecked(localUpdateOn.get()); + if (!liveUpdateOn && localUpdateOn.get()) { + UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)), compoundButton); + } else { + UiUtilities.setupCompoundButton(compoundButton, nightMode, CompoundButtonType.GLOBAL); + } - nameTextView.setText(getNameToDisplay(item, context)); - if (shouldUpdatePreference.get()) { - final Integer frequencyId = preferenceUpdateFrequency(item, fragment.getSettings()).get(); - final Integer timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, fragment.getSettings()).get(); + title.setText(getNameToDisplay(item, app)); + + AndroidUiHelper.updateVisibility(subTitle, localUpdateOn.get()); + if (localUpdateOn.get()) { + int frequencyId = preferenceUpdateFrequency(item, settings).get(); final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId]; + String subTitleText = getString(frequency.getLocalizedId()); + /*int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, settings).get(); final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId]; - subheaderTextView.setVisibility(View.VISIBLE); - String subheaderText = fragment.getString(frequency.getLocalizedId()); if (frequency != UpdateFrequency.HOURLY) { - subheaderText += " • " + fragment.getString(timeOfDay.getLocalizedId()); - } - subheaderTextView.setText(subheaderText); - subheaderTextView.setTextColor(fragment.getActivity().getResources() - .getColor(R.color.osmand_orange)); - icon.setImageDrawable(fragment.getIcon(R.drawable.ic_map, R.color.osmand_orange)); - options.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_overflow_menu_white)); - } else { - subheaderTextView.setVisibility(View.GONE); - icon.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_map)); - options.setImageDrawable(getSecondaryColorPaintedIcon(R.drawable.ic_action_plus)); + subTitleText += " • " + getString(timeOfDay.getLocalizedId()); + }*/ + subTitle.setText(subTitleText); + subTitle.setTextColor(ContextCompat.getColor(app, liveUpdateOn + ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); + Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); + subTitle.setTypeface(typeface); } - final String fileNameWithoutExtension = - Algorithms.getFileNameWithoutExtension(new File(item)); - final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension); - final long lastCheck = preferenceLastCheck(item, fragment.getSettings()).get(); - CommonPreference liveUpdateOn = preferenceLiveUpdatesOn(item, fragment.getSettings()); - if (liveUpdateOn.get() && lastCheck != DEFAULT_LAST_CHECK) { - String lastCheckString = formatDateTime(fragment.getActivity(), lastCheck); - descriptionTextView.setText(context.getString(R.string.last_update, lastCheckString)); - } else { - String lastCheckString = formatDateTime(fragment.getActivity(), timestamp); - descriptionTextView.setText(context.getString(R.string.last_map_change, lastCheckString)); + Drawable statusDrawable = AppCompatResources.getDrawable(app, R.drawable.ic_map); + int resColorId = !localUpdateOn.get() ? getSecondaryIconColorId(nightMode) : + !liveUpdateOn ? getDefaultIconColorId(nightMode) : getOsmandIconColorId(nightMode); + int statusColor = ContextCompat.getColor(app, resColorId); + if (statusDrawable != null) { + DrawableCompat.setTint(statusDrawable, statusColor); } + statusIcon.setImageDrawable(statusDrawable); - if (!fragment.isProcessing() && InAppPurchaseHelper.isSubscribedToLiveUpdates(context)) { - final View.OnClickListener clickListener = new View.OnClickListener() { + description.setText(getLastCheckString(item, app)); + + if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { + compoundButton.setEnabled(liveUpdateOn); + compoundButton.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() { @Override - public void onClick(View v) { - final FragmentManager fragmentManager = fragment.getChildFragmentManager(); - LiveUpdatesSettingsDialogFragment.createInstance(item).show(fragmentManager, "settings"); + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + onUpdateLocalIndex(item, isChecked, null); } - }; - options.setOnClickListener(clickListener); - options.setEnabled(true); + }); } else { - options.setEnabled(false); + compoundButton.setEnabled(false); } - - if (isLastChild) { - divider.setVisibility(View.GONE); - } else { - divider.setVisibility(View.VISIBLE); - } - } - - private Drawable getSecondaryColorPaintedIcon(@DrawableRes int drawable) { - return fragment.getMyActivity().getMyApplication().getUIUtilities() - .getPaintedIcon(drawable, secondaryColor); } } - public static class LoadLocalIndexTask - extends AsyncTask> - implements AbstractLoadLocalIndexTask { + public static class GetLastUpdateDateTask extends AsyncTask { - //private List result; - private LocalIndexesAdapter adapter; - private LiveUpdatesFragment fragment; - private LocalIndexHelper helper; + private final OsmandApplication app; + private final WeakReference fragment; - public LoadLocalIndexTask(LocalIndexesAdapter adapter, - LiveUpdatesFragment fragment) { - this.adapter = adapter; - this.fragment = fragment; - helper = new LocalIndexHelper(fragment.getMyActivity().getMyApplication()); + GetLastUpdateDateTask(LiveUpdatesFragment fragment) { + this.fragment = new WeakReference<>(fragment); + app = fragment.getMyApplication(); } @Override - protected List doInBackground(Void... params) { - return helper.getLocalFullMaps(this); + protected String doInBackground(Void... params) { + try { + return AndroidNetworkUtils.sendRequest(app, URL, null, + "Requesting map updates info...", false, false); + } catch (Exception e) { + LOG.error("Error: " + "Requesting map updates info error", e); + return null; + } } @Override - public void loadFile(LocalIndexInfo... loaded) { - publishProgress(loaded); - } - - @Override - protected void onProgressUpdate(LocalIndexInfo... values) { - String fileNameL; - for (LocalIndexInfo localIndexInfo : values) { - fileNameL = localIndexInfo.getFileName().toLowerCase(); - if (localIndexInfo.getType() == LocalIndexHelper.LocalIndexType.MAP_DATA - && !fileNameL.contains("world") && !fileNameL.startsWith("depth_")) { - adapter.add(localIndexInfo); + protected void onPostExecute(String response) { + LiveUpdatesFragment f = fragment.get(); + if (response != null && f != null) { + TextViewEx descriptionTime = f.descriptionTime; + if (descriptionTime != null) { + SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + source.setTimeZone(TimeZone.getTimeZone("UTC")); + SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); + dest.setTimeZone(TimeZone.getDefault()); + try { + LOG.debug("response = " + response); + Date parsed = source.parse(response); + if (parsed != null) { + long dateTime = parsed.getTime(); + LOG.debug("dateTime = " + dateTime); + descriptionTime.setText(dest.format(parsed)); + } + } catch (ParseException e) { + LOG.error(e.getMessage()); + } } } + } + } + + protected static String getLastCheckString(String fileName, OsmandApplication app) { + return getLastCheckString(fileName, app, false); + } + + protected static String getLastCheckString(String fileName, OsmandApplication app, boolean lastTimeChecked) { + OsmandSettings settings = app.getSettings(); + + final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); + String lastUpdateString = formatShortDateTime(app, lastUpdate); + String description = app.getString(R.string.updated, lastUpdateString); + + if (lastTimeChecked) { + final long lastCheck = preferenceLastCheck(fileName, settings).get(); + String lastCheckString = formatShortDateTime(app, lastCheck); + if (!lastUpdateString.equals(app.getString(R.string.shared_string_never))) { + description = description.concat("\n" + app.getString(R.string.last_time_checked, lastCheckString)); + } + } + return description; + } + + @Override + public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { + + int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); + int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get(); + final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); + final PendingIntent alarmIntent = getPendingIntent(app, fileName); + + final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, settings); + liveUpdatePreference.set(newValue); + if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) { + runLiveUpdate(getActivity(), fileName, true, new LiveUpdateListener() { + @Override + public void processFinish() { + runSort(); + if (callback != null) { + callback.run(); + } + } + }); + UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId]; + TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId]; + setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate); + } else { + alarmManager.cancel(alarmIntent); + runSort(); + } + + return true; + } + + @Override + public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) { + if (settings.IS_LIVE_UPDATES_ON.get()) { + runLiveUpdate(getActivity(), fileName, userRequested, new LiveUpdateListener() { + @Override + public void processFinish() { + updateList(); + if (callback != null) { + callback.run(); + } + } + }); + } + } + + @Override + public void runSort() { + if (adapter != null) { + adapter.onDataUpdated(); + } + } + + @Override + public void updateList() { + if (adapter != null) { adapter.notifyDataSetChanged(); - fragment.expandAllGroups(); - } - - @Override - protected void onPostExecute(List result) { - //this.result = result; - adapter.sort(); - adapter.notifyLiveUpdatesChanged(); - adapter.notifyDataSetInvalidated(); } } - private void enableProgress() { - processing = true; - progressBar.setVisibility(View.VISIBLE); - updateSubscriptionHeader(); - adapter.notifyDataSetChanged(); + @ColorRes + public static int getDefaultIconColorId(boolean nightMode) { + return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; } - private void disableProgress() { - processing = false; - progressBar.setVisibility(View.INVISIBLE); - updateSubscriptionHeader(); - adapter.notifyDataSetChanged(); - } - - @Override - public void onError(InAppPurchaseTaskType taskType, String error) { - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseErrorOnFragments(getChildFragmentManager(), taskType, error); - } - } - - @Override - public void onGetItems() { - if (!InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - app.getSettings().IS_LIVE_UPDATES_ON.set(false); - adapter.enableLiveUpdates(false); - } - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseGetItemsOnFragments(getChildFragmentManager()); - } - } - - @Override - public void onItemPurchased(String sku, boolean active) { - InAppPurchaseHelper purchaseHelper = getInAppPurchaseHelper(); - if (purchaseHelper != null && purchaseHelper.getLiveUpdates().containsSku(sku)) { - updateSubscriptionHeader(); - } - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseItemPurchasedOnFragments(getChildFragmentManager(), sku, active); - } - } - - @Override - public void showProgress(InAppPurchaseTaskType taskType) { - enableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseShowProgressOnFragments(getChildFragmentManager(), taskType); - } - } - - @Override - public void dismissProgress(InAppPurchaseTaskType taskType) { - disableProgress(); - - OsmandInAppPurchaseActivity activity = getInAppPurchaseActivity(); - if (activity != null) { - activity.fireInAppPurchaseDismissProgressOnFragments(getChildFragmentManager(), taskType); - } - } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java deleted file mode 100644 index 243362ea98..0000000000 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragmentNew.java +++ /dev/null @@ -1,706 +0,0 @@ -package net.osmand.plus.liveupdates; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.graphics.Typeface; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CompoundButton; -import android.widget.ExpandableListView; -import android.widget.ImageButton; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.ColorRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.AppCompatImageView; -import androidx.appcompat.widget.SwitchCompat; -import androidx.appcompat.widget.Toolbar; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import net.osmand.AndroidNetworkUtils; -import net.osmand.AndroidUtils; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; -import net.osmand.plus.UiUtilities.CompoundButtonType; -import net.osmand.plus.activities.LocalIndexInfo; -import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; -import net.osmand.plus.base.BaseOsmAndDialogFragment; -import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.OnLiveUpdatesForLocalChange; -import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.widgets.TextViewEx; -import net.osmand.util.Algorithms; - -import org.apache.commons.logging.Log; - -import java.lang.ref.WeakReference; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; - -import static net.osmand.AndroidUtils.getSecondaryTextColorId; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatShortDateTime; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLatestUpdateAvailable; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getTertiaryTextColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getActiveTextColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getOsmandIconColorId; -import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; - -public class LiveUpdatesFragmentNew extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange { - - public static final String URL = "https://osmand.net/api/osmlive_status"; - public static final String TAG = LiveUpdatesFragmentNew.class.getSimpleName(); - private final static Log LOG = PlatformUtil.getLog(LiveUpdatesFragmentNew.class); - private static final String SUBSCRIPTION_URL = "https://osmand.net/features/subscription"; - - private OsmandApplication app; - private OsmandSettings settings; - private boolean nightMode; - - private View toolbarSwitchContainer; - private ExpandableListView listView; - private TextViewEx descriptionTime; - private LiveMapsAdapter adapter; - - private GetLastUpdateDateTask getLastUpdateDateTask; - private LoadLiveMapsTask loadLiveMapsTask; - - private final LiveUpdateListener liveUpdateListener = new LiveUpdateListener() { - @Override - public void processFinish() { - adapter.notifyDataSetChanged(); - } - }; - - public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { - if (!fragmentManager.isStateSaved()) { - LiveUpdatesFragmentNew fragment = new LiveUpdatesFragmentNew(); - fragment.setTargetFragment(target, 0); - fragment.show(fragmentManager, TAG); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - app = getMyApplication(); - settings = getSettings(); - nightMode = isNightMode(false); - setHasOptionsMenu(true); - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_live_updates, container, false); - - Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); - toolbar.setTitle(R.string.osm_live); - int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; - Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), iconColorResId); - DrawableCompat.setTint(icBack, ContextCompat.getColor(app, iconColorResId)); - toolbar.setNavigationIcon(icBack); - toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - ImageButton iconHelp = toolbar.findViewById(R.id.toolbar_action); - Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help, iconColorResId); - iconHelp.setImageDrawable(helpDrawable); - iconHelp.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SUBSCRIPTION_URL)); - if (AndroidUtils.isIntentSafe(app, intent)) { - startActivity(intent); - } - } - }); - - listView = (ExpandableListView) view.findViewById(android.R.id.list); - adapter = new LiveMapsAdapter(); - listView.setAdapter(adapter); - expandAllGroups(); - - View bottomShadowView = inflater.inflate(R.layout.card_bottom_divider, listView, false); - listView.addFooterView(bottomShadowView); - listView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { - @Override - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app) && settings.IS_LIVE_UPDATES_ON.get()) { - if (getFragmentManager() != null) { - LiveUpdatesSettingsDialogFragmentNew - .showInstance(getFragmentManager(), LiveUpdatesFragmentNew.this, - adapter.getChild(groupPosition, childPosition).getFileName()); - } - return true; - } else { - return false; - } - } - }); - - final SwipeRefreshLayout swipeRefresh = view.findViewById(R.id.swipe_refresh); - int swipeColor = ContextCompat.getColor(app, nightMode ? R.color.osmand_orange_dark : R.color.osmand_orange); - swipeRefresh.setColorSchemeColors(swipeColor); - swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - @Override - public void onRefresh() { - if (settings.IS_LIVE_UPDATES_ON.get()) { - showUpdateDialog(getActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener); - startUpdateDateAsyncTask(); - } - swipeRefresh.setRefreshing(false); - } - }); - - toolbarSwitchContainer = view.findViewById(R.id.toolbar_switch_container); - updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get()); - - View timeContainer = view.findViewById(R.id.item_import_container); - AndroidUtils.setListItemBackground(app, timeContainer, nightMode); - - AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon); - Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time, - ContextCompat.getColor(app, nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light)); - descriptionIcon.setImageDrawable(icon); - - TextViewEx title = timeContainer.findViewById(R.id.title); - AndroidUtils.setTextSecondaryColor(app, title, nightMode); - title.setText(R.string.latest_openstreetmap_update); - title.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_desc_text_size)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - title.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); - } - - descriptionTime = timeContainer.findViewById(R.id.sub_title); - AndroidUtils.setTextPrimaryColor(app, descriptionTime, nightMode); - Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); - descriptionTime.setTypeface(typeface); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - descriptionTime.setLetterSpacing(AndroidUtils.getFloatValueFromRes(app, R.dimen.description_letter_spacing)); - } - - return view; - } - - @Override - public void onResume() { - super.onResume(); - startUpdateDateAsyncTask(); - startLoadLiveMapsAsyncTask(); - } - - @Override - public void onPause() { - super.onPause(); - stopUpdateDateAsyncTask(); - stopLoadLiveMapsAsyncTask(); - } - - @Override - public void onDismiss(@NonNull DialogInterface dialog) { - super.onDismiss(dialog); - Fragment target = getTargetFragment(); - if (target instanceof RefreshLiveUpdates) { - ((RefreshLiveUpdates) target).onUpdateStates(app); - } - } - - private void startUpdateDateAsyncTask() { - getLastUpdateDateTask = new GetLastUpdateDateTask(this); - getLastUpdateDateTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - private void stopUpdateDateAsyncTask() { - if (getLastUpdateDateTask != null) { - getLastUpdateDateTask.cancel(true); - } - } - - private void startLoadLiveMapsAsyncTask() { - if (loadLiveMapsTask == null) { - loadLiveMapsTask = new LoadLiveMapsTask(adapter, app); - loadLiveMapsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - } - - private void stopLoadLiveMapsAsyncTask() { - if (loadLiveMapsTask != null && loadLiveMapsTask.getStatus() == AsyncTask.Status.RUNNING) { - loadLiveMapsTask.cancel(false); - } - } - - private void updateToolbarSwitch(final boolean isChecked) { - int switchColor = ContextCompat.getColor(app, - isChecked ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode)); - AndroidUtils.setBackground(toolbarSwitchContainer, new ColorDrawable(switchColor)); - - SwitchCompat switchView = toolbarSwitchContainer.findViewById(R.id.switchWidget); - switchView.setChecked(isChecked); - UiUtilities.setupCompoundButton(switchView, nightMode, CompoundButtonType.TOOLBAR); - - toolbarSwitchContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - boolean visible = !isChecked; - if (visible) { - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - switchOnLiveUpdates(); - updateToolbarSwitch(true); - } else { - app.showToastMessage(getString(R.string.osm_live_ask_for_purchase)); - updateToolbarSwitch(false); - } - } else { - settings.IS_LIVE_UPDATES_ON.set(false); - enableLiveUpdates(false); - updateToolbarSwitch(false); - } - updateList(); - } - }); - - TextView title = toolbarSwitchContainer.findViewById(R.id.switchButtonText); - title.setText(isChecked ? R.string.shared_string_enabled : R.string.shared_string_disabled); - } - - private void switchOnLiveUpdates() { - settings.IS_LIVE_UPDATES_ON.set(true); - enableLiveUpdates(true); - showUpdateDialog(getMyActivity(), settings, adapter.mapsList, adapter.countEnabled, liveUpdateListener); - startUpdateDateAsyncTask(); - } - - public static void showUpdateDialog(final Activity context, final OsmandSettings settings, - final ArrayList mapsList, int countEnabled, - @Nullable final LiveUpdateListener listener) { - if (!Algorithms.isEmpty(mapsList)) { - if (countEnabled == 1) { - LocalIndexInfo li = mapsList.get(0); - runLiveUpdate(context, li.getFileName(), false, listener); - } else if (countEnabled > 1) { - AlertDialog.Builder bld = new AlertDialog.Builder(context); - bld.setMessage(R.string.update_all_maps_now); - bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - for (LocalIndexInfo li : mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - runLiveUpdate(context, li.getFileName(), false, listener); - } - } - } - }); - bld.setNegativeButton(R.string.shared_string_no, null); - bld.show(); - } - } - } - - private void enableLiveUpdates(boolean enable) { - if (!Algorithms.isEmpty(adapter.mapsList)) { - AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - for (LocalIndexInfo li : adapter.mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - String fileName = li.getFileName(); - PendingIntent alarmIntent = getPendingIntent(app, fileName); - if (enable) { - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, settings); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, settings); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - } - } - } - } - - private void expandAllGroups() { - for (int i = 0; i < adapter.getGroupCount(); i++) { - listView.expandGroup(i); - } - } - - public static int updateCountEnabled(TextView countView, ArrayList mapsList, OsmandSettings settings) { - int countEnabled = 0; - if (countView != null) { - for (LocalIndexInfo map : mapsList) { - CommonPreference preference = preferenceForLocalIndex(map.getFileName(), settings); - if (preference.get()) { - countEnabled++; - } - } - String countText = countEnabled + "/" + mapsList.size(); - countView.setText(countText); - } - return countEnabled; - } - - protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { - private final ArrayList mapsList = new ArrayList<>(); - private int countEnabled = 0; - private TextViewEx countView; - - @Override - public void addData(LocalIndexInfo info) { - mapsList.add(info); - } - - @Override - public void clearData() { - mapsList.clear(); - } - - @Override - public void onDataUpdated() { - sort(); - countEnabled = updateCountEnabled(countView, mapsList, settings); - } - - public void sort() { - Collections.sort(mapsList); - Collections.sort(mapsList, new Comparator() { - @Override - public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { - CommonPreference preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings()); - CommonPreference preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings()); - return preference2.get().compareTo(preference1.get()); - } - }); - notifyDataSetInvalidated(); - } - - @Override - public LocalIndexInfo getChild(int groupPosition, int childPosition) { - return mapsList.get(childPosition); - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return groupPosition * 10000 + childPosition; // it would be unusable to have 10000 local indexes - } - - @Override - public View getChildView(final int groupPosition, final int childPosition, - boolean isLastChild, View convertView, ViewGroup parent) { - LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); - convertView = inflater.inflate(R.layout.list_item_triple_row_icon_and_menu, parent, false); - LiveMapsViewHolder viewHolder = new LiveMapsViewHolder(convertView); - convertView.setTag(viewHolder); - viewHolder.bindLocalIndexInfo(getChild(groupPosition, childPosition).getFileName()); - return convertView; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - View view = convertView; - if (view == null) { - LayoutInflater inflater = UiUtilities.getInflater(app, nightMode); - view = inflater.inflate(R.layout.list_group_title_with_right_descr, parent, false); - } - view.setOnClickListener(null); - View topShadowView = view.findViewById(R.id.bottomShadowView); - if (groupPosition == 0) { - topShadowView.setVisibility(View.GONE); - } else { - topShadowView.setVisibility(View.VISIBLE); - } - - TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title)); - titleView.setText(getGroup(groupPosition)); - - countView = ((TextViewEx) view.findViewById(R.id.description)); - AndroidUtils.setTextSecondaryColor(app, countView, nightMode); - - return view; - } - - @Override - public int getChildrenCount(int groupPosition) { - return mapsList.size(); - } - - @Override - public String getGroup(int groupPosition) { - return getString(R.string.available_maps); - } - - @Override - public int getGroupCount() { - return 1; - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public boolean hasStableIds() { - return false; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - } - - private class LiveMapsViewHolder { - private final ImageView statusIcon; - private final TextView title; - private final TextView subTitle; - private final TextView description; - private final CompoundButton option; - - private LiveMapsViewHolder(View view) { - statusIcon = (AppCompatImageView) view.findViewById(R.id.icon); - title = (TextView) view.findViewById(R.id.title); - subTitle = (TextView) view.findViewById(R.id.sub_title); - description = (TextView) view.findViewById(R.id.description); - option = (CompoundButton) view.findViewById(R.id.compound_button); - } - - public void bindLocalIndexInfo(@NonNull final String item) { - boolean liveUpdateOn = settings.IS_LIVE_UPDATES_ON.get(); - CommonPreference localUpdateOn = preferenceForLocalIndex(item, settings); -// IncrementalChangesManager changesManager = app.getResourceManager().getChangesManager(); - option.setChecked(localUpdateOn.get()); - if (!liveUpdateOn && localUpdateOn.get()) { - UiUtilities.setupCompoundButton(nightMode, ContextCompat.getColor(app, getTertiaryTextColorId(nightMode)), option); - } else { - UiUtilities.setupCompoundButton(option, nightMode, CompoundButtonType.GLOBAL); - } - - title.setText(getNameToDisplay(item, app)); - - AndroidUiHelper.updateVisibility(subTitle, localUpdateOn.get()); - if (localUpdateOn.get()) { - int frequencyId = preferenceUpdateFrequency(item, settings).get(); - final UpdateFrequency frequency = UpdateFrequency.values()[frequencyId]; - String subTitleText = getString(frequency.getLocalizedId()); - /*int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(item, settings).get(); - final TimeOfDay timeOfDay = TimeOfDay.values()[timeOfDateToUpdateId]; - if (frequency != UpdateFrequency.HOURLY) { - subTitleText += " • " + getString(timeOfDay.getLocalizedId()); - }*/ - subTitle.setText(subTitleText); - subTitle.setTextColor(ContextCompat.getColor(app, liveUpdateOn - ? getActiveTextColorId(nightMode) : getSecondaryTextColorId(nightMode))); - Typeface typeface = FontCache.getFont(app, getString(R.string.font_roboto_medium)); - subTitle.setTypeface(typeface); - } - - Drawable statusDrawable = AppCompatResources.getDrawable(app, R.drawable.ic_map); - int resColorId = !localUpdateOn.get() ? getSecondaryIconColorId(nightMode) : - !liveUpdateOn ? getDefaultIconColorId(nightMode) : getOsmandIconColorId(nightMode); - int statusColor = ContextCompat.getColor(app, resColorId); - if (statusDrawable != null) { - DrawableCompat.setTint(statusDrawable, statusColor); - } - statusIcon.setImageDrawable(statusDrawable); - - description.setText(getLastCheckString(item, app)); - - if (InAppPurchaseHelper.isSubscribedToLiveUpdates(app)) { - option.setEnabled(liveUpdateOn); - option.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - onUpdateLocalIndex(item, isChecked, null); - } - }); - } else { - option.setEnabled(false); - } - } - } - - public static class GetLastUpdateDateTask extends AsyncTask { - - private final OsmandApplication app; - private final WeakReference fragment; - - GetLastUpdateDateTask(LiveUpdatesFragmentNew fragment) { - this.fragment = new WeakReference<>(fragment); - app = fragment.getMyApplication(); - } - - @Override - protected String doInBackground(Void... params) { - try { - return AndroidNetworkUtils.sendRequest(app, URL, null, - "Requesting map updates info...", false, false); - } catch (Exception e) { - LOG.error("Error: " + "Requesting map updates info error", e); - return null; - } - } - - @Override - protected void onPostExecute(String response) { - LiveUpdatesFragmentNew f = fragment.get(); - if (response != null && f != null) { - TextViewEx descriptionTime = f.descriptionTime; - if (descriptionTime != null) { - SimpleDateFormat source = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - source.setTimeZone(TimeZone.getTimeZone("UTC")); - SimpleDateFormat dest = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US); - dest.setTimeZone(TimeZone.getDefault()); - try { - LOG.debug("response = " + response); - Date parsed = source.parse(response); - if (parsed != null) { - long dateTime = parsed.getTime(); - LOG.debug("dateTime = " + dateTime); - descriptionTime.setText(dest.format(parsed)); - } - } catch (ParseException e) { - LOG.error(e.getMessage()); - } - } - } - } - } - - protected static String getLastCheckString(String fileName, OsmandApplication app) { - return getLastCheckString(fileName, app, false); - } - - protected static String getLastCheckString(String fileName, OsmandApplication app, boolean lastTimeChecked) { - OsmandSettings settings = app.getSettings(); - - final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); - String lastUpdateString = formatShortDateTime(app, lastUpdate); - String description = app.getString(R.string.updated, lastUpdateString); - - if (lastTimeChecked) { - final long lastCheck = preferenceLastCheck(fileName, settings).get(); - String lastCheckString = formatShortDateTime(app, lastCheck); - if (!lastUpdateString.equals(app.getString(R.string.shared_string_never))) { - description = description.concat("\n" + app.getString(R.string.last_time_checked, lastCheckString)); - } - } - return description; - } - - @Override - public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { - - int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); - int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get(); - final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - final PendingIntent alarmIntent = getPendingIntent(app, fileName); - - final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, settings); - liveUpdatePreference.set(newValue); - if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) { - runLiveUpdate(getActivity(), fileName, true, new LiveUpdateListener() { - @Override - public void processFinish() { - runSort(); - if (callback != null) { - callback.run(); - } - } - }); - UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId]; - setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate); - } else { - alarmManager.cancel(alarmIntent); - runSort(); - } - - return true; - } - - @Override - public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) { - if (settings.IS_LIVE_UPDATES_ON.get()) { - runLiveUpdate(getActivity(), fileName, userRequested, new LiveUpdateListener() { - @Override - public void processFinish() { - updateList(); - if (callback != null) { - callback.run(); - } - } - }); - } - } - - @Override - public void runSort() { - if (adapter != null) { - adapter.onDataUpdated(); - } - } - - @Override - public void updateList() { - if (adapter != null) { - adapter.notifyDataSetChanged(); - } - } - - @ColorRes - public static int getDefaultIconColorId(boolean nightMode) { - return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; - } - -} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java similarity index 97% rename from OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java rename to OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index 776368e6a7..910ad7da1e 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -36,7 +36,7 @@ import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.ShortDescriptionItem; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; -import net.osmand.plus.liveupdates.LiveUpdatesClearDialogFragment.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; import net.osmand.plus.resources.IncrementalChangesManager; @@ -68,10 +68,10 @@ import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFreq import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.getCustomButtonView; import static net.osmand.plus.settings.bottomsheets.BooleanPreferenceBottomSheet.updateCustomButtonView; -public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogFragment implements RefreshLiveUpdates { +public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragment implements RefreshLiveUpdates { - public static final String TAG = LiveUpdatesSettingsDialogFragmentNew.class.getSimpleName(); - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsDialogFragmentNew.class); + public static final String TAG = LiveUpdatesSettingsBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsBottomSheet.class); private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; private OsmandApplication app; @@ -89,7 +89,7 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) { if (!fragmentManager.isStateSaved()) { - LiveUpdatesSettingsDialogFragmentNew fragment = new LiveUpdatesSettingsDialogFragmentNew(); + LiveUpdatesSettingsBottomSheet fragment = new LiveUpdatesSettingsBottomSheet(); fragment.setTargetFragment(target, 0); fragment.fileName = fileName; fragment.show(fragmentManager, TAG); @@ -292,9 +292,8 @@ public class LiveUpdatesSettingsDialogFragmentNew extends MenuBottomSheetDialogF public void onClick(View v) { if (getUpdatesSize() > 0) { if (getFragmentManager() != null) { - LiveUpdatesClearDialogFragment - .showInstance(getFragmentManager(), - LiveUpdatesSettingsDialogFragmentNew.this, fileName); + LiveUpdatesClearBottomSheet.showInstance(getFragmentManager(), + LiveUpdatesSettingsBottomSheet.this, fileName); } } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java deleted file mode 100644 index 242f44f83a..0000000000 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsDialogFragment.java +++ /dev/null @@ -1,288 +0,0 @@ -package net.osmand.plus.liveupdates; - -import android.app.AlarmManager; -import android.app.Dialog; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.widget.SwitchCompat; -import androidx.fragment.app.DialogFragment; - -import net.osmand.AndroidUtils; -import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; -import net.osmand.plus.R; -import net.osmand.plus.download.AbstractDownloadActivity; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; -import net.osmand.plus.resources.IncrementalChangesManager; -import net.osmand.util.Algorithms; - -import org.apache.commons.logging.Log; - -import java.io.File; - -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.formatDateTime; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getNameToDisplay; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.getPendingIntent; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceDownloadViaWiFi; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLastCheck; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceLiveUpdatesOn; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceTimeOfDayToUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceUpdateFrequency; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.setAlarmForPendingIntent; - -public class LiveUpdatesSettingsDialogFragment extends DialogFragment { - private static final Log LOG = PlatformUtil.getLog(LiveUpdatesSettingsDialogFragment.class); - private static final String LOCAL_INDEX_FILE_NAME = "local_index_file_name"; - - private TextView sizeTextView; - - private String fileName; - private String fileNameWithoutExtension; - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - fileName = getArguments().getString(LOCAL_INDEX_FILE_NAME); - assert fileName != null; - - View view = LayoutInflater.from(getActivity()) - .inflate(R.layout.dialog_live_updates_item_settings, null); - final TextView regionNameTextView = (TextView) view.findViewById(R.id.regionNameTextView); - final TextView lastMapChangeTextView = (TextView) view.findViewById(R.id.lastMapChangeTextView); - final TextView lastUpdateTextView = (TextView) view.findViewById(R.id.lastUpdateTextView); - final SwitchCompat liveUpdatesSwitch = (SwitchCompat) view.findViewById(R.id.toggle_item); - final CheckBox downloadOverWiFiCheckBox = (CheckBox) view.findViewById(R.id.downloadOverWiFiSwitch); - final Spinner updateFrequencySpinner = (Spinner) view.findViewById(R.id.updateFrequencySpinner); - final Spinner updateTimesOfDaySpinner = (Spinner) view.findViewById(R.id.updateTimesOfDaySpinner); - final View updateTimesOfDayLayout = view.findViewById(R.id.updateTimesOfDayLayout); - sizeTextView = (TextView) view.findViewById(R.id.sizeTextView); - - regionNameTextView.setText(getNameToDisplay(fileName, getMyActivity().getMyApplication())); - fileNameWithoutExtension = Algorithms.getFileNameWithoutExtension(new File(fileName)); - final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager(); - final long timestamp = changesManager.getTimestamp(fileNameWithoutExtension); - String lastUpdateDate = formatDateTime(getActivity(), timestamp); - lastMapChangeTextView.setText(getString(R.string.last_map_change, lastUpdateDate)); - final long lastCheck = preferenceLastCheck(fileName, getSettings()).get(); - - - CommonPreference preference = preferenceLiveUpdatesOn(fileName, - getSettings()); - if (preference.get() && lastCheck != DEFAULT_LAST_CHECK) { - String lastCheckString = formatDateTime(getActivity(), lastCheck); - lastUpdateTextView.setText(getString(R.string.last_update, lastCheckString)); - } else { - lastUpdateTextView.setVisibility(View.GONE); - } - - final CommonPreference liveUpdatePreference = - preferenceForLocalIndex(fileName, getSettings()); - final CommonPreference downloadViaWiFiPreference = - preferenceDownloadViaWiFi(fileName, getSettings()); - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, getSettings()); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, getSettings()); - - downloadOverWiFiCheckBox.setChecked(!liveUpdatePreference.get() || downloadViaWiFiPreference.get()); - - sizeTextView.setText(getUpdatesSize(getMyActivity(), fileNameWithoutExtension, changesManager)); - - TimeOfDay[] timeOfDays = TimeOfDay.values(); - String[] timeOfDaysStrings = new String[timeOfDays.length]; - for (int i = 0; i < timeOfDays.length; i++) { - timeOfDaysStrings[i] = getString(timeOfDays[i].getLocalizedId()); - } - updateTimesOfDaySpinner.setAdapter(new ArrayAdapter<>(getActivity(), - R.layout.action_spinner_item, timeOfDaysStrings)); - updateTimesOfDaySpinner.setSelection(timeOfDayPreference.get()); - - UpdateFrequency[] updateFrequencies = UpdateFrequency.values(); - String[] updateFrequenciesStrings = new String[updateFrequencies.length]; - for (int i = 0; i < updateFrequencies.length; i++) { - updateFrequenciesStrings[i] = getString(updateFrequencies[i].getLocalizedId()); - } - - refreshTimeOfDayLayout(UpdateFrequency.values()[updateFrequencyPreference.get()], - updateTimesOfDayLayout); - updateFrequencySpinner.setAdapter(new ArrayAdapter<>(getActivity(), - R.layout.action_spinner_item, updateFrequenciesStrings)); - updateFrequencySpinner.setSelection(updateFrequencyPreference.get()); - updateFrequencySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - refreshTimeOfDayLayout(UpdateFrequency.values()[position], updateTimesOfDayLayout); - } - - @Override - public void onNothingSelected(AdapterView parent) { - - } - }); - - builder.setView(view) - .setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (liveUpdatePreference.get() != liveUpdatesSwitch.isChecked()) { - liveUpdatePreference.set(liveUpdatesSwitch.isChecked()); - if (!liveUpdatesSwitch.isChecked()) { - long updatesSize = changesManager.getUpdatesSize(fileNameWithoutExtension); - if (updatesSize != 0) { - ClearUpdatesDialogFragment.createInstance(fileName) - .show(getParentFragment().getChildFragmentManager(), null); - } - } - } - downloadViaWiFiPreference.set(downloadOverWiFiCheckBox.isChecked()); - - final int updateFrequencyInt = updateFrequencySpinner.getSelectedItemPosition(); - updateFrequencyPreference.set(updateFrequencyInt); - - AlarmManager alarmMgr = (AlarmManager) getActivity() - .getSystemService(Context.ALARM_SERVICE); - PendingIntent alarmIntent = getPendingIntent(getActivity(), fileName); - - final int timeOfDayInt = updateTimesOfDaySpinner.getSelectedItemPosition(); - timeOfDayPreference.set(timeOfDayInt); - - if (liveUpdatesSwitch.isChecked() && getSettings().IS_LIVE_UPDATES_ON.get()) { - runLiveUpdate(getActivity(), fileName, false, null); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyInt]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayInt]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } - getLiveUpdatesFragment().notifyLiveUpdatesChanged(); - } - }) - .setNegativeButton(R.string.shared_string_cancel, null) - .setNeutralButton(R.string.update_now, null); - return builder.create(); - } - - @Override - public void onResume() { - super.onResume(); - final AlertDialog dialog = (AlertDialog) getDialog(); - if (dialog != null) { - Button neutralButton = (Button) dialog.getButton(Dialog.BUTTON_NEUTRAL); - neutralButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (!getSettings().isInternetConnectionAvailable()) { - getMyApplication().showShortToastMessage(R.string.no_internet_connection); - } else { - runLiveUpdate(getActivity(), fileName, true, null); - final IncrementalChangesManager changesManager = getMyApplication().getResourceManager().getChangesManager(); - sizeTextView.setText(getUpdatesSize(getMyActivity(), fileNameWithoutExtension, changesManager)); - dialog.dismiss(); - } - } - }); - } - } - - private void refreshTimeOfDayLayout(UpdateFrequency updateFrequency, View updateTimesOfDayLayout) { - switch (updateFrequency) { - case HOURLY: - updateTimesOfDayLayout.setVisibility(View.GONE); - break; - case DAILY: - case WEEKLY: - updateTimesOfDayLayout.setVisibility(View.VISIBLE); - break; - } - } - - private static String getUpdatesSize(Context ctx, String fileNameWithoutExtension, - IncrementalChangesManager changesManager) { - long updatesSize = changesManager.getUpdatesSize(fileNameWithoutExtension); - return AndroidUtils.formatSize(ctx, updatesSize); - } - - private LiveUpdatesFragment getLiveUpdatesFragment() { - return (LiveUpdatesFragment) getParentFragment(); - } - - private OsmandSettings getSettings() { - return getMyApplication().getSettings(); - } - - private OsmandApplication getMyApplication() { - return getMyActivity().getMyApplication(); - } - - private AbstractDownloadActivity getMyActivity() { - return (AbstractDownloadActivity) this.getActivity(); - } - - public static LiveUpdatesSettingsDialogFragment createInstance(String fileName) { - LiveUpdatesSettingsDialogFragment fragment = new LiveUpdatesSettingsDialogFragment(); - Bundle args = new Bundle(); - args.putString(LOCAL_INDEX_FILE_NAME, fileName); - fragment.setArguments(args); - return fragment; - } - - public static class ClearUpdatesDialogFragment extends DialogFragment { - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - final String localIndexInfo = getArguments().getString(LOCAL_INDEX_FILE_NAME); - assert localIndexInfo != null; - - final IncrementalChangesManager changesManager = - getMyApplication().getResourceManager().getChangesManager(); - final String fileNameWithoutExtension = - Algorithms.getFileNameWithoutExtension(new File(localIndexInfo)); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage( - getString(R.string.ltr_or_rtl_combine_via_space, - getString(R.string.clear_updates_proposition_message), - getUpdatesSize(getContext(), fileNameWithoutExtension, changesManager))) - .setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - changesManager.deleteUpdates(fileNameWithoutExtension); - preferenceLastCheck(localIndexInfo, getMyApplication().getSettings()).resetToDefault(); - } - }) - .setNegativeButton(R.string.shared_string_cancel, null); - return builder.create(); - } - - private OsmandApplication getMyApplication() { - return (OsmandApplication) getActivity().getApplication(); - } - - public static ClearUpdatesDialogFragment createInstance(String fileName) { - ClearUpdatesDialogFragment fragment = new ClearUpdatesDialogFragment(); - Bundle args = new Bundle(); - args.putString(LOCAL_INDEX_FILE_NAME, fileName); - fragment.setArguments(args); - return fragment; - } - } -} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java new file mode 100644 index 0000000000..8cef25af27 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java @@ -0,0 +1,132 @@ +package net.osmand.plus.liveupdates; + +import android.os.Bundle; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentManager; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities.DialogButtonType; +import net.osmand.plus.activities.LocalIndexInfo; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem; +import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.widgets.TextViewEx; + +import org.apache.commons.logging.Log; + +import java.util.List; + +import static net.osmand.AndroidUtils.getPrimaryTextColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; +import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; + +public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragment { + + public static final String TAG = LiveUpdatesUpdateAllBottomSheet.class.getSimpleName(); + private static final Log LOG = PlatformUtil.getLog(LiveUpdatesUpdateAllBottomSheet.class); + + private OsmandApplication app; + private OsmandSettings settings; + + private List mapsList; + private LiveUpdateListener listener; + + public void setMapsList(List mapsList) { + this.mapsList = mapsList; + } + + public void setListener(LiveUpdateListener listener) { + this.listener = listener; + } + + public static void showInstance(@NonNull FragmentManager fragmentManager, + List mapsList, LiveUpdateListener listener) { + if (!fragmentManager.isStateSaved()) { + LiveUpdatesUpdateAllBottomSheet fragment = new LiveUpdatesUpdateAllBottomSheet(); + fragment.setMapsList(mapsList); + fragment.setListener(listener); + fragment.show(fragmentManager, TAG); + } + } + + BaseBottomSheetItem itemTitle; + BaseBottomSheetItem itemDescription; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + app = getMyApplication(); + settings = app.getSettings(); + + updateBottomButtons(); + + itemTitle = new SimpleBottomSheetItem.Builder() + .setTitle(getString(R.string.update_all_maps_now)) + .setTitleColorId(getPrimaryTextColorId(nightMode)) + .setLayoutId(R.layout.bottom_sheet_item_title) + .create(); + items.add(itemTitle); + + itemDescription = new LongDescriptionItem.Builder() + .setDescription(getString(R.string.live_update_all_maps)) + .setDescriptionMaxLines(5) + .setDescriptionColorId(getPrimaryTextColorId(nightMode)) + .setLayoutId(R.layout.bottom_sheet_item_description_long) + .create(); + items.add(itemDescription); + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + View view = super.onCreateView(inflater, parent, savedInstanceState); + ((TextViewEx) itemTitle.getView()).setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_list_text_size)); + TextView textDescription = (TextView) itemDescription.getView(); + textDescription.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.default_list_text_size)); + textDescription.setMinHeight(getResources().getDimensionPixelSize(R.dimen.context_menu_sub_info_height)); + return view; + } + + private void updateAll() { + if (settings != null) { + for (LocalIndexInfo li : mapsList) { + CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); + if (localUpdateOn.get()) { + runLiveUpdate(getActivity(), li.getFileName(), false, listener); + } + } + } + } + + @Override + protected void onRightBottomButtonClick() { + updateAll(); + dismiss(); + } + + @Override + protected int getDismissButtonTextId() { + return R.string.shared_string_cancel; + } + + @Override + protected int getRightBottomButtonTextId() { + return R.string.update_now; + } + + @Override + protected DialogButtonType getRightBottomButtonType() { + return DialogButtonType.PRIMARY; + } + +} diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java index d148e8c697..07e533640b 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java @@ -201,7 +201,7 @@ public class PerformLiveUpdateAsyncTask private void updateLatestAvailability(OsmandApplication app, @NonNull final String localIndexFileName) { final OsmandSettings settings = app.getSettings(); AndroidNetworkUtils.sendRequestAsync( - app, LiveUpdatesFragmentNew.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() { + app, LiveUpdatesFragment.URL, null, "Requesting map updates info...", false, false, new OnRequestResultListener() { @Override public void onResult(String result) { if (!Algorithms.isEmpty(result)) { diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java index a2afb3d933..85554cf24a 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/SubscriptionFragment.java @@ -228,12 +228,6 @@ public class SubscriptionFragment extends BaseOsmAndDialogFragment implements In } String preferredCountry = obj.getString("preferredCountry"); app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(preferredCountry); - - Fragment parent = getParentFragment(); - if (parent instanceof LiveUpdatesFragment) { - ((LiveUpdatesFragment) parent).updateSubscriptionHeader(); - } - dismiss(); } else { app.showToastMessage("Error: " + obj.getString("error")); diff --git a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java index 2f4ca39f84..858e32c962 100644 --- a/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/settings/bottomsheets/BooleanPreferenceBottomSheet.java @@ -33,7 +33,7 @@ import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import org.apache.commons.logging.Log; -import static net.osmand.plus.liveupdates.LiveUpdatesSettingsDialogFragmentNew.getActivePrimaryColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.getActivePrimaryColorId; import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; public class BooleanPreferenceBottomSheet extends BasePreferenceBottomSheet { diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 96478490bb..334d3398b1 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -43,7 +43,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.getDefaultIconColorId; +import static net.osmand.plus.liveupdates.LiveUpdatesFragment.getDefaultIconColorId; public class GpxBlockStatisticsBuilder { From 67449365b482eba07447e26d1946f7a8357ed3b0 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 26 Mar 2021 11:01:37 +0500 Subject: [PATCH 022/109] Small fixes and corrections --- .../src/main/java/net/osmand/Period.java | 17 ++-- OsmAnd/res/layout/purchases_layout.xml | 2 +- OsmAnd/res/layout/subscription_layout.xml | 1 - .../osmand/plus/inapp/InAppPurchasesImpl.java | 11 ++- .../chooseplan/ChoosePlanDialogFragment.java | 38 ++++---- .../plus/inapp/InAppPurchaseHelper.java | 8 +- .../net/osmand/plus/inapp/InAppPurchases.java | 30 +++++-- .../settings/fragments/PurchasesFragment.java | 45 +++++----- .../settings/fragments/SubscriptionsCard.java | 90 +++++-------------- .../GpxEditDescriptionDialogFragment.java | 2 +- 10 files changed, 119 insertions(+), 125 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/Period.java b/OsmAnd-java/src/main/java/net/osmand/Period.java index d6bd911257..b529fdb6db 100644 --- a/OsmAnd-java/src/main/java/net/osmand/Period.java +++ b/OsmAnd-java/src/main/java/net/osmand/Period.java @@ -1,20 +1,23 @@ package net.osmand; import java.text.ParseException; +import java.util.Calendar; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Period { public enum PeriodUnit { - YEAR("Y"), - MONTH("M"), - WEEK("W"), - DAY("D"); + YEAR("Y", Calendar.YEAR), + MONTH("M", Calendar.MONTH), + WEEK("W", Calendar.WEEK_OF_YEAR), + DAY("D", Calendar.DATE); private String unitStr; + private int calendarIdx; - PeriodUnit(String unitStr) { + PeriodUnit(String unitStr, int calendarIdx) { + this.calendarIdx = calendarIdx; this.unitStr = unitStr; } @@ -22,6 +25,10 @@ public class Period { return unitStr; } + public int getCalendarIdx() { + return calendarIdx; + } + public double getMonthsValue() { switch (this) { case YEAR: diff --git a/OsmAnd/res/layout/purchases_layout.xml b/OsmAnd/res/layout/purchases_layout.xml index 2140d2cc5c..d4bb5a3465 100644 --- a/OsmAnd/res/layout/purchases_layout.xml +++ b/OsmAnd/res/layout/purchases_layout.xml @@ -4,7 +4,7 @@ xmlns:osmand="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="match_parent" android:background="?attr/bg_color" android:orientation="vertical"> diff --git a/OsmAnd/res/layout/subscription_layout.xml b/OsmAnd/res/layout/subscription_layout.xml index de35b80f4a..411e49db31 100644 --- a/OsmAnd/res/layout/subscription_layout.xml +++ b/OsmAnd/res/layout/subscription_layout.xml @@ -7,7 +7,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:background="@android:drawable/list_selector_background" android:paddingStart="@dimen/content_padding" android:paddingLeft="@dimen/content_padding" android:paddingRight="@dimen/content_padding" diff --git a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java index a2a0f8d680..9c7ee92758 100644 --- a/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java +++ b/OsmAnd/src-google/net/osmand/plus/inapp/InAppPurchasesImpl.java @@ -2,15 +2,15 @@ package net.osmand.plus.inapp; import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import com.android.billingclient.api.SkuDetails; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.Version; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + public class InAppPurchasesImpl extends InAppPurchases { private static final InAppPurchase FULL_VERSION = new InAppPurchaseFullVersion(); @@ -285,6 +285,11 @@ public class InAppPurchasesImpl extends InAppPurchases { this.details = details; } + @Override + public int getPeriodTypeString() { + return R.string.monthly_subscription; + } + @Override public String getDefaultPrice(Context ctx) { return ""; diff --git a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java index 8488daf0f5..814fe15871 100644 --- a/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/chooseplan/ChoosePlanDialogFragment.java @@ -22,17 +22,6 @@ import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; -import androidx.annotation.ColorRes; -import androidx.annotation.DrawableRes; -import androidx.annotation.LayoutRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.AppCompatImageView; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - import net.osmand.AndroidUtils; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; @@ -59,6 +48,17 @@ import org.apache.commons.logging.Log; import java.util.List; +import androidx.annotation.ColorRes; +import androidx.annotation.DrawableRes; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.AppCompatImageView; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; + public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment implements InAppPurchaseListener { public static final String TAG = ChoosePlanDialogFragment.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(ChoosePlanDialogFragment.class); @@ -489,14 +489,18 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment buttonView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - subscribe(s.getSku()); + if (getActivity() != null) { + subscribe(app, getActivity(), purchaseHelper, s.getSku()); + } } }); } else { buttonExView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - subscribe(s.getSku()); + if (getActivity() != null) { + subscribe(app, getActivity(), purchaseHelper, s.getSku()); + } } }); } @@ -526,14 +530,14 @@ public abstract class ChoosePlanDialogFragment extends BaseOsmAndDialogFragment } } - private void subscribe(String sku) { + public static void subscribe(@NonNull OsmandApplication app, Activity activity, + InAppPurchaseHelper purchaseHelper, String sku) { if (!app.getSettings().isInternetConnectionAvailable(true)) { Toast.makeText(app, R.string.internet_not_available, Toast.LENGTH_LONG).show(); } else { - FragmentActivity ctx = getActivity(); - if (ctx != null && purchaseHelper != null) { + if (activity != null && purchaseHelper != null) { OsmandSettings settings = app.getSettings(); - purchaseHelper.purchaseLiveUpdates(ctx, sku, + purchaseHelper.purchaseLiveUpdates(activity, sku, settings.BILLING_USER_EMAIL.get(), settings.BILLING_USER_NAME.get(), settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(), diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java index dfa3f55c84..5136cd1f73 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchaseHelper.java @@ -8,9 +8,6 @@ import android.os.AsyncTask; import android.text.TextUtils; import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils.OnRequestResultListener; import net.osmand.AndroidNetworkUtils.OnRequestsResultListener; @@ -43,6 +40,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + public abstract class InAppPurchaseHelper { // Debug tag, for logging protected static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(InAppPurchaseHelper.class); @@ -203,7 +203,7 @@ public abstract class InAppPurchaseHelper { List subscriptions = new ArrayList<>(); for (InAppSubscription subscription : getLiveUpdates().getVisibleSubscriptions()) { SubscriptionState state = subscription.getState(); - if (state != null && !SubscriptionState.UNDEFINED.equals(state)) { + if (state != SubscriptionState.UNDEFINED) { subscriptions.add(subscription); } } diff --git a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java index 8a6d5a0128..27d359630e 100644 --- a/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java +++ b/OsmAnd/src/net/osmand/plus/inapp/InAppPurchases.java @@ -7,12 +7,6 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; -import androidx.annotation.ColorInt; -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.StringRes; - import net.osmand.AndroidUtils; import net.osmand.Period; import net.osmand.Period.PeriodUnit; @@ -34,6 +28,12 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import androidx.annotation.ColorInt; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + public abstract class InAppPurchases { protected InAppPurchase fullVersion; @@ -645,6 +645,9 @@ public abstract class InAppPurchases { this.skuNoVersion = sku; } + @StringRes + public abstract int getPeriodTypeString(); + @NonNull private List getUpgrades() { return new ArrayList<>(upgrades.values()); @@ -835,6 +838,11 @@ public abstract class InAppPurchases { this(sku, false); } + @Override + public int getPeriodTypeString() { + return R.string.monthly_subscription; + } + @Override public void setPriceValue(double priceValue) { super.setPriceValue(priceValue); @@ -883,6 +891,11 @@ public abstract class InAppPurchases { super(sku, false); } + @Override + public int getPeriodTypeString() { + return R.string.three_months_subscription; + } + @Override public void setPriceValue(double priceValue) { super.setPriceValue(priceValue); @@ -926,6 +939,11 @@ public abstract class InAppPurchases { super(sku, false); } + @Override + public int getPeriodTypeString() { + return R.string.annual_subscription; + } + @Override public void setPriceValue(double priceValue) { super.setPriceValue(priceValue); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index af834f73b8..00a15b3071 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -24,6 +24,7 @@ import android.widget.TextView; import com.google.android.material.appbar.AppBarLayout; import net.osmand.AndroidUtils; +import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; @@ -44,6 +45,8 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.util.Algorithms; +import org.apache.commons.logging.Log; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; @@ -51,10 +54,17 @@ import androidx.fragment.app.FragmentManager; public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurchaseListener, OnFragmentInteractionListener { + private static final Log log = PlatformUtil.getLog(PurchasesFragment.class); public static final String TAG = PurchasesFragment.class.getName(); + public static final String KEY_IS_SUBSCRIBER = "action_is_new"; + private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; + private static final String EMAIL_DEEPLINK_URI = "mailto:support@osmand.net"; + private static final String OSMAND_EMAIL = "support@osmand.net"; + private static final String OSMAND_NEW_DEVICE_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; + private static final String OSMAND_PURCHASES_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases"; private OsmandApplication app; private Context context; @@ -66,17 +76,18 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment(); private String url; - private Boolean isSubscriber; + private Boolean isPaidVersion; public static boolean showInstance(FragmentManager fragmentManager) { try { PurchasesFragment fragment = new PurchasesFragment(); fragmentManager.beginTransaction() - .add(R.id.fragmentContainer, fragment, TAG) + .replace(R.id.fragmentContainer, fragment, TAG) .addToBackStack(TAG) .commitAllowingStateLoss(); return true; } catch (Exception e) { + log.error(e); return false; } } @@ -90,12 +101,12 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { app = getMyApplication(); context = requireContext(); - isSubscriber = Version.isPaidVersion(app); + isPaidVersion = Version.isPaidVersion(app); final MapActivity mapActivity = getMapActivity(); final boolean nightMode = !app.getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); - if (isSubscriber) { + if (isPaidVersion) { mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); setSubscriptionClick(mapActivity); } else { @@ -117,11 +128,6 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha } AndroidUtils.addStatusBarPadding21v(getActivity(), mainView); createToolbar(mainView, nightMode); - mainView.setOnTouchListener(new View.OnTouchListener() { - public boolean onTouch(View v, MotionEvent event) { - return true; - } - }); LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); purchasesRestore.setOnClickListener(new View.OnClickListener() { @Override @@ -135,7 +141,7 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - WikipediaDialogFragment.showFullArticle(context, Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"), nightMode); + WikipediaDialogFragment.showFullArticle(context, Uri.parse(OSMAND_NEW_DEVICE_URL), nightMode); } }); @@ -147,10 +153,11 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public void onResume() { super.onResume(); purchaseHelper = getInAppPurchaseHelper(); - if (isSubscriber) { + if (isPaidVersion) { MapActivity mapActivity = getMapActivity(); if (getMapActivity() != null && purchaseHelper != null) { ViewGroup subscriptionsCardContainer = mainView.findViewById(R.id.subscriptions_card_container); + subscriptionsCardContainer.removeAllViews(); subscriptionsCard = new SubscriptionsCard(mapActivity, purchaseHelper); subscriptionsCardContainer.addView(subscriptionsCard.build(mapActivity)); } @@ -161,7 +168,7 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); - outState.putBoolean(KEY_IS_SUBSCRIBER, isSubscriber); + outState.putBoolean(KEY_IS_SUBSCRIBER, isPaidVersion); } @Override @@ -277,7 +284,7 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha icon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - WikipediaDialogFragment.showFullArticle(context, Uri.parse("https://docs.osmand.net/en/main@latest/osmand/purchases"), nightMode); + WikipediaDialogFragment.showFullArticle(context, Uri.parse(OSMAND_PURCHASES_URL), nightMode); } }); ImageButton backButton = toolbar.findViewById(R.id.close_button); @@ -301,14 +308,12 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha TextView supportDescription = mainView.findViewById(R.id.support_link_title); SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); - String urlSupport = "mailto:support@osmand.net"; - spannableStringSupport.setSpan(new URLSpan(urlSupport), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + spannableStringSupport.setSpan(new URLSpan(EMAIL_DEEPLINK_URI), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - String emailString = "support@osmand.net"; - String supportDescriptionString = getString(R.string.contact_support_description, emailString); + String supportDescriptionString = getString(R.string.contact_support_description, OSMAND_EMAIL); SpannableString spannableStringMail = new SpannableString(supportDescriptionString); - int startIndex = supportDescriptionString.indexOf(emailString); - int endIndex = startIndex + emailString.length(); + int startIndex = supportDescriptionString.indexOf(OSMAND_EMAIL); + int endIndex = startIndex + OSMAND_EMAIL.length(); StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -322,7 +327,7 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha private void getSkuAppId() { InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); - if (purchaseHelper != null) { + if (purchaseHelper != null && purchaseHelper.getFullVersion() != null) { String sku = purchaseHelper.getFullVersion().getSku(); url = String.format(PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL, sku, context.getPackageName()); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index c8c0d5202b..1cc422b3ff 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -5,34 +5,34 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import android.widget.Toast; import net.osmand.AndroidUtils; import net.osmand.Period; import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState; import net.osmand.plus.routepreparationmenu.cards.BaseCard; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.Locale; import androidx.annotation.NonNull; -import androidx.appcompat.view.ContextThemeWrapper; -import androidx.core.content.ContextCompat; public class SubscriptionsCard extends BaseCard { private final InAppPurchaseHelper purchaseHelper; + private final SimpleDateFormat dateFormat; + @Override public int getCardLayoutId() { return R.layout.subscriptions_card; @@ -41,33 +41,29 @@ public class SubscriptionsCard extends BaseCard { public SubscriptionsCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper) { super(mapActivity); this.purchaseHelper = purchaseHelper; + this.dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.getDefault()); } @Override protected void updateContent() { - if (mapActivity == null || purchaseHelper == null) { + if (purchaseHelper == null || Algorithms.isEmpty(purchaseHelper.getEverMadeSubscriptions())) { return; } - List subscriptions = purchaseHelper.getEverMadeSubscriptions(); - if (Algorithms.isEmpty(subscriptions)) { - return; - } - - ContextThemeWrapper ctx = new ContextThemeWrapper(mapActivity, !nightMode ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme); - LayoutInflater inflater = LayoutInflater.from(ctx); + LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode); ((ViewGroup) view).removeAllViews(); + List subscriptions = purchaseHelper.getEverMadeSubscriptions(); for (int i = 0; i < subscriptions.size(); i++) { InAppSubscription subscription = subscriptions.get(i); SubscriptionState state = subscription.getState(); - boolean autoRenewed = SubscriptionState.ACTIVE.equals(state) || SubscriptionState.IN_GRACE_PERIOD.equals(state); + boolean autoRenewed = state == SubscriptionState.ACTIVE || state == SubscriptionState.IN_GRACE_PERIOD; View card = inflater.inflate(R.layout.subscription_layout, null, false); ((ViewGroup) view).addView(card); TextView subscriptionPeriod = card.findViewById(R.id.subscription_type); - String period = getSubscriptionPeriod(subscription.getSubscriptionPeriod()); + String period = app.getString(subscription.getPeriodTypeString()); if (!Algorithms.isEmpty(period)) { subscriptionPeriod.setText(period); AndroidUiHelper.updateVisibility(subscriptionPeriod, true); @@ -80,33 +76,31 @@ public class SubscriptionsCard extends BaseCard { nextBillingDate.setText(app.getString(R.string.next_billing_date, date)); AndroidUiHelper.updateVisibility(nextBillingDate, true); } - } - - TextView status = card.findViewById(R.id.status); - status.setText(app.getString(state.getStringRes())); - status.setBackgroundDrawable(ContextCompat.getDrawable(mapActivity, state.getBackgroundRes())); - - if (!autoRenewed) { + } else { View renewContainer = card.findViewById(R.id.renewContainer); AndroidUiHelper.updateVisibility(renewContainer, true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - AndroidUtils.setBackground(ctx, renewContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); + AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); } else { - AndroidUtils.setBackground(ctx, renewContainer, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); + AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); } final String sku = subscription.getSku(); renewContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - subscribe(sku); + ChoosePlanDialogFragment.subscribe(app, mapActivity, purchaseHelper, sku); } }); View renew = card.findViewById(R.id.renew); - AndroidUtils.setBackground(ctx, renew, nightMode, + AndroidUtils.setBackground(mapActivity, renew, nightMode, R.drawable.btn_solid_border_light, R.drawable.btn_solid_border_dark); } + TextView status = card.findViewById(R.id.status); + status.setText(app.getString(state.getStringRes())); + AndroidUtils.setBackground(status, app.getUIUtilities().getIcon(state.getBackgroundRes())); + int dividerLayout = i + 1 == subscriptions.size() ? R.layout.simple_divider_item : R.layout.divider_half_item; View divider = inflater.inflate(dividerLayout, (ViewGroup) view, false); ((ViewGroup) view).addView(divider); @@ -114,52 +108,14 @@ public class SubscriptionsCard extends BaseCard { } private String getHumanDate(long time, Period period) { - Date date = new Date(time); - int monthsCount; if (period == null || period.getUnit() == null) { return ""; - } else if (period.getUnit().equals(Period.PeriodUnit.YEAR)) { - monthsCount = 12; - } else { - monthsCount = period.getNumberOfUnits(); } + Date date = new Date(time); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); - calendar.add(Calendar.MONTH, monthsCount); + calendar.add(period.getUnit().getCalendarIdx(), period.getNumberOfUnits()); date = calendar.getTime(); - SimpleDateFormat format = new SimpleDateFormat("MMM d, yyyy", app.getLocaleHelper().getPreferredLocale()); - return format.format(date); - } - - private void subscribe(String sku) { - if (app == null) { - return; - } - if (!app.getSettings().isInternetConnectionAvailable(true)) { - Toast.makeText(app, R.string.internet_not_available, Toast.LENGTH_LONG).show(); - } else if (mapActivity != null && purchaseHelper != null) { - OsmandSettings settings = app.getSettings(); - purchaseHelper.purchaseLiveUpdates(mapActivity, sku, - settings.BILLING_USER_EMAIL.get(), - settings.BILLING_USER_NAME.get(), - settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get(), - settings.BILLING_HIDE_USER_NAME.get()); - } - } - - private String getSubscriptionPeriod(Period period) { - if (period == null || period.getUnit() == null) { - return ""; - } else if (period.getUnit().equals(Period.PeriodUnit.YEAR)) { - return app.getString(R.string.annual_subscription); - } else if (period.getUnit().equals(Period.PeriodUnit.MONTH)) { - int unitsNumber = period.getNumberOfUnits(); - if (unitsNumber == 1) { - return app.getString(R.string.monthly_subscription); - } else if (unitsNumber == 3) { - return app.getString(R.string.three_months_subscription); - } - } - return ""; + return dateFormat.format(date); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java b/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java index 52536316b8..0d8e91e26c 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxEditDescriptionDialogFragment.java @@ -130,7 +130,7 @@ public class GpxEditDescriptionDialogFragment extends BaseOsmAndDialogFragment { View btnSave = view.findViewById(R.id.btn_save); int drawableRes = isNightMode(true) ? R.drawable.btn_solid_border_dark : R.drawable.btn_solid_border_light; - btnSave.setBackgroundDrawable(ContextCompat.getDrawable(ctx, drawableRes)); + AndroidUtils.setBackground(btnSave, getMyApplication().getUIUtilities().getIcon(drawableRes)); } private void showDismissDialog() { From 4da71a3734e9b02ce6fad721a3cc876a2d64ea5f Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Fri, 26 Mar 2021 05:55:53 +0000 Subject: [PATCH 023/109] Translated using Weblate (Japanese) Currently translated at 97.6% (3609 of 3695 strings) --- OsmAnd/res/values-ja/strings.xml | 42 +++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 9820354ce7..c619818f9b 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -3082,7 +3082,7 @@ POIの更新は利用できません 『クイックアクション』のリストに最低ひとつは項目を設定する必要があります アルペン/ダウンヒルスキー アルペンスキーまたはダウンヒルスキーに用の斜面(ゲレンデ)やスキーリフトへの道 - クロスカントリー/ノルディックスキー + クロスカントリースキーとノルディックスキー ノルディックスキーやクロスカントリースキー用コースやそれらに用いられる小道などです。 スキーツーリング スキーツーリング用ルートです。 @@ -3354,9 +3354,9 @@ POIの更新は利用できません ルート再計算 案内 ユーザー名とパスワード - これらの設定はアプリ全般に関するもので、すべてのプロファイルに適用されます + これらのプラグイン設定はアプリ全般に関するもので、すべてのプロファイルに適用されます OSM編集 - まだアップロードしていない編集やOSMバグを%1$sで表示できます。アップロードされた後にはOsmAndに表示されません。 + まだアップロードしていない編集やOSMバグを%1$sで表示できます。アップロードされた変更部分は表示されなくなります。 OSM ナビゲーションまたは移動中に表示されるアイコンです。 静止時に表示されるアイコンです。 @@ -3799,8 +3799,8 @@ POIの更新は利用できません 最終更新日 名称: 降順(Z-A) 名称: 昇順(A-Z) - Java(セーフモード)での公共交通機関ルーティング計算に切り替えます - OsmEdit機能を利用するには、OAuthでのログインが必要です。 + Java(セーフモード)での公共交通機関ルート計算に切り替えます + OsmEdit機能を利用するには、OAuth方式でのログインが必要です。 OAuthでログイン OpenStreetMapOAuthトークンを消去する ログアウトしました @@ -3832,20 +3832,20 @@ POIの更新は利用できません ユーザー名とパスワードを使用する ログイン サブスクリプションの管理 - サブスクリプションに際し問題が発生しています。ボタンをタップしてGooglePlayサブスクリプション設定に移動し、お支払い方法を確認してください。 + ボタンをタップしてGoogle Playで支払い方法を設定し、サブスクリプションを修正します。 OsmAndLiveサブスクリプションの有効期限が切れました OsmAndLiveサブスクリプションが一時停止されました OsmAndLiveサブスクリプションは保留中です マーカーの履歴 GPXファイルをOpenStreetMapに送信 タグはカンマで区切って入力してください。 - パブリック状態は、経路がGPS経路およびGPS経路リストに公開を目的として表示されることを示唆しています。 APIを介して提供されるデータは、経路ページを参照していません。経路ポイントのタイムスタンプは、パブリックGPS APIからは入手できず、各地点は時系列で並べられることはありません。ただし他のユーザーは、公開経路リストとその中のタイムスタンプから生の経路データをダウンロードすることができます。 - 識別可能状態は、経路がGPS経路およびパブリックGPS経路リストに表示されることを示唆しています。他のユーザーは現在の経路をダウンロードして、ユーザー名とリンクできます。 trackpoints APIを介して配信されるデータは、元の経路追跡ページを参照します。経路ポイントのタイムスタンプは、パブリックGPSAPIを介して入手できます。 - プライベート状態は、経路がパブリックリストに表示されないことを示唆しています。経路ポイントは、タイムスタンプなしでパブリックGPS APIを介して引き続き利用できますが、時系列で並べられることはありません。 - 追跡可能状態にある場合は経路が公開リストに表示されないことを示唆していますが、経路ポイントは自体はタイムスタンプ付きの公開GPSAPIを介して引き続き利用できます。他のユーザーからはあなたに直接関連付けることはできず、自身の処理済み経路ポイントのみをダウンロードできます。 + \"公開 \"状態は、追跡機能にてユーザーのGPS追跡、公開GPS追跡リスト、および生データのタイムスタンプ付き公開追跡リストに公開されることを意味します。APIを介して提供されるデータはユーザーの追跡ページを参照しません。追跡ポイントのタイムスタンプはパブリックGPS APIでは利用できず、また追跡ポイントは時系列に並んでいません。 + \"識別可能\"状態は、経路がGPS経路およびパブリックGPS経路リストに表示されることを示唆しています。他のユーザーは現在の経路をダウンロードして、ユーザー名とリンクできます。経路ポイント APIを介して配信されるデータは、元の経路追跡ページを参照します。経路ポイントのタイムスタンプは、公開されているGPS APIを通じて入手できます。 + \"プライベート\"状態は、経路が公開リストに表示されないことを示唆しています。経路ポイントはタイムスタンプなしでパブリックGPS APIを介して引き続き利用できますが、時系列で並べられることはありません。 + \"追跡可能\"状態は、経路が公開リストに表示されることはありませんが、公開されているGPS APIからのダウンロードを通じて、タイムスタンプ付きの経路ポイント(個人と直接関連付けることはできません)を処理出来ることを意味します。 アカウント - ルートが再計算されるのを待ちます。 -\nグラフは再計算後に利用できるようになります。 + しばらくお待ち下さい。 +\nグラフはルートが再計算された後に利用できるようになります。 OSM通知/ POI / GPXのアップロードをテストする場合、openstreetmap.orgではなくdev.openstreetmap.orgを使用するよう切り替えます。 dev.openstreetmap.orgを使用 次々回案内(中距離) @@ -4034,4 +4034,22 @@ POIの更新は利用できません フォルダーの変更 開始ダイアログを表示 無効にした場合、ウィジェットまたはメニュー項目をタップするとすぐに記録が始まり、確認のダイアログは表示されません。 + ネイティブ公共交通機関モードの展開 + グラフ + %1$sデータは道路でのみ利用可能です。グラフを表示するには、\"地点間ルート\"を使用してルートを計算する必要があります。 + ギャップ + 音声アナウンスの間隔 + ルートラインのカスタマイズ + ルートライン + ルートライン指定は%1$s、選択したマップスタイルは:%2$s + マップモードの色指定: %1$s + • OsmAndLiveのアップデートは\"ダウンロード\">\"更新\"に移動 +\n +\n• 経路は、高度、速度、または傾斜によって色付けされる可能性あり +\n +\n• ナビゲーションルートラインの外観を変更するオプションが追加 +\n +\n• \"旅程記録\"ダイアログを更新 +\n +\n \ No newline at end of file From 3f62b5cc1a763230e4fed9dd4967c14926cc137c Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Thu, 25 Mar 2021 20:31:59 +0000 Subject: [PATCH 024/109] Translated using Weblate (French) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-fr/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 5dc5f5fc88..72e77075b4 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -4040,4 +4040,17 @@ Toutes les données non enregistrées seront perdues. Afficher la boîte de dialogue de démarrage Si désactivé, l\'enregistrement débutera dès appui sur le gadget ou dans le menu (sans demande de confirmation). + - Les mises à jour d\'OsmAnd Live ont été déplacées vers \"Téléchargements > Mises à jour\" +\n +\n - Les traces peuvent maintenant être colorées par altitude, vitesse ou pente. +\n +\n - Ajout d\'une option pour modifier l\'apparence de la ligne d\'itinéraire en navigation +\n +\n - Mise à jour de la fenêtre \"Enregistrement du trajet\". +\n +\n + La ligne d\'itinéraire utilisera le %1$s pour le style de carte : %2$s. + Personnaliser la ligne d\'itinéraire + Ligne d\'itinéraire + Définissez une couleur pour le mode de carte : %1$s. \ No newline at end of file From 6c439350c49ab7e8c3bb0bf4562c514e708fce61 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 25 Mar 2021 17:31:40 +0000 Subject: [PATCH 025/109] Translated using Weblate (German) Currently translated at 99.9% (3693 of 3695 strings) --- OsmAnd/res/values-de/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OsmAnd/res/values-de/strings.xml b/OsmAnd/res/values-de/strings.xml index 4be82a75ce..1f6d915238 100644 --- a/OsmAnd/res/values-de/strings.xml +++ b/OsmAnd/res/values-de/strings.xml @@ -4054,4 +4054,16 @@ Alle nicht gespeicherten Daten gehen verloren. Startdialog anzeigen Wenn deaktiviert, beginnt die Aufnahme direkt nach dem Tippen auf das Widget oder den Menüpunkt und überspringt den Bestätigungsdialog. + Routenlinie anpassen + Routenlinie + Legen Sie die Farbe für den Kartenmodus fest: %1$s. + • OsmAnd Live-Updates nach \"Downloads > Updates\" verschoben +\n +\n• Tracks können nun nach Höhe, Geschwindigkeit oder Steigung eingefärbt werden. +\n +\n• Option zugefügt, um das Aussehen der Navigationsrouten-Linie zu ändern +\n +\n• Dialog \"Streckenaufzeichnung\" aktualisiert +\n +\n \ No newline at end of file From 3f011367086cf65853f86cb840de5ee29f6efa64 Mon Sep 17 00:00:00 2001 From: solokot Date: Thu, 25 Mar 2021 07:37:36 +0000 Subject: [PATCH 026/109] Translated using Weblate (Russian) Currently translated at 100.0% (3690 of 3690 strings) --- OsmAnd/res/values-ru/strings.xml | 45 +++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml index 8ed1ef86a1..ada07660d2 100644 --- a/OsmAnd/res/values-ru/strings.xml +++ b/OsmAnd/res/values-ru/strings.xml @@ -597,7 +597,7 @@ Чтение кешированных растровых карт… Недостаточно памяти для локальной карты «{0}» Версия локальной карты «{0}» не поддерживается - Офлайн-навигация OsmAnd — это экспериментальная функция, и она не работает на дистанциях больше 20 км. + Локальная навигация OsmAnd — это экспериментальная функция, и она не работает на дистанциях больше 20 км. \n \nНавигация временно переключена на онлайн-сервис CloudMade. Невозможно найти указанную папку. @@ -1528,7 +1528,7 @@ Линии метро Продолжить навигацию Приостановить навигацию - Отрисовка дорог cогласно шкале SAC. + Отрисовка дорог согласно шкале SAC. Отрисовка дорог согласно трассам OSMC. Раннее По умолчанию @@ -1580,7 +1580,10 @@ Размер текста Нажмите на любой элемент списка для просмотра более подробной информации, долго удерживайте, чтобы поместить в архив или удалить. Текущие данные на устройстве (%1$s свободно): Анонимный пользователь - Анонимному пользователю недоступно:\n- создание групп;\n- синхронизация групп и устройств с сервером;\n- управление группами и устройствами в личном кабинете. + Анонимному пользователю недоступно: +\n— создание групп; +\n— синхронизация групп и устройств с сервером; +\n— управление группами и устройствами в личном кабинете. Вы вошли как %1$s Маршруты Детали @@ -1894,7 +1897,7 @@ Пропустить OsmAnd Плагины - Офлайн-карты + Локальные карты \nи навигация Номер дома Тип лыжной трассы @@ -2385,7 +2388,7 @@ Дорога Показывать направляющие линии Тёмно-жёлтый - OsmAnd — это активно развивающийся проект с открытым исходным кодом. Благодаря открытости, каждый может внести свой вклад в приложение, сообщая об ошибках, совершенствуя перевод или разрабатывая новые возможности. Кроме того, проект финансируется за счет денежных взносов с целью разработки и тестирования новых функций. + OsmAnd — это активно развивающийся проект с открытым исходным кодом. Благодаря открытости, каждый может внести свой вклад в приложение, сообщая об ошибках, совершенствуя перевод или разрабатывая новые возможности. Кроме того, проект финансируется за счёт денежных взносов с целью разработки и тестирования новых функций. \nПримерное покрытие и качество карт: \n • Западная Европа: **** \n • Восточная Европа: *** @@ -2398,7 +2401,7 @@ \n • Африка: ** \n • Антарктида: \nДля скачивания доступно большинство стран мира! -\n Получите надежный навигатор в своей стране — будь то Франция, Германия, Мексика, Великобритания, Испания, Нидерланды, США, Россия, Бразилия или любая другая. +\n Получите надёжный навигатор в своей стране — будь то Франция, Германия, Мексика, Великобритания, Испания, Нидерланды, США, Россия, Бразилия или любая другая. Примерная карта покрытия и качество: \n • Западная Европа: **** \n • Восточная Европа: *** @@ -2519,11 +2522,11 @@ \n• Просмотр вашей скорости и высоты над уровнем моря \n• Функция записи GPX позволяет вам записывать ваше путешествие и делиться им \n• Через приложение вы можете включить отображение контурных линий и затемнение рельефа - Прогулки, пеший туризм, экскурсии -\n• Карта показывает пешеходные и треккинговые тропы -\n• Википедия на предпочитаемом вами языке может многое рассказать вам во время экскурсии по городу -\n• Остановки общественного транспорта (автобус, трамвай, поезд), включая названия маршрутов, помогут ориентироваться в новом городе -\n• GPS навигация в пешеходном режиме высчитывает маршрут, используя пешеходные тропы + Прогулки, пеший туризм, экскурсии +\n• Карта показывает пешеходные и трекинговые тропы +\n• Википедия на предпочитаемом вами языке может многое рассказать вам во время экскурсии по городу +\n• Остановки общественного транспорта (автобус, трамвай, поезд), включая названия маршрутов, помогут ориентироваться в новом городе +\n• GPS навигация в пешеходном режиме высчитывает маршрут, используя пешеходные тропы \n• Отправьте и следуйте по маршруту GPX или запишите и поделитесь своим собственным \n Внесение вклада в OSM @@ -2944,7 +2947,7 @@ Без паромов Исключить паромы Отправить журнал - К сожалению OsmAnd не смог найти подходящий для вас маршрут. + К сожалению, OsmAnd не смог найти подходящий для вас маршрут. Попробуйте пройти навигацию пешком. Попробуйте изменить настройки. Рассчитать маршрут ходьбы @@ -3772,7 +3775,7 @@ Все предыдущие сегменты будут пересчитаны с использованием выбранного профиля. Открыть сохранённый трек Остановка записи GPX при принудительном закрытии (через последние приложения). (Из панели уведомлений Android исчезнет значок фонового режима.) - сохранен + сохранён Добавьте хотя бы две точки. Повторить • Обновлённая функция планирования маршрута позволяет применять к сегментам разные режимы навигации и настраивать привязку к дорогам @@ -3794,7 +3797,7 @@ Имя: Я - А Имя: А - Я Значки старта и финиша - Спасибо за покупку \'Контурных линий\' + Спасибо за покупку «Контурных линий» Избегать пешеходных дорожек Избегать пешеходных дорожек Подписка оплачивается за выбранный период. Отмените её в AppGallery в любое время. @@ -3863,7 +3866,7 @@ Добавить в OpenPlaceReviews Добавить в Mapillary OsmAnd показывает фотографии из нескольких источников: -\nOpenPlaceReviews — фотогорафии POI; +\nOpenPlaceReviews — фотографии POI; \nMapillary — изображения улиц; \nWeb / Wikimedia — фотографии POI по данным OpenStreetMap. Ресурсы @@ -3885,7 +3888,7 @@ Каяк %1$s * %2$s Немецкий (повседневный) - Легкий самолет + Лёгкий самолёт Добавить новый сегмент Объединить сегменты Разделить до @@ -4008,7 +4011,7 @@ Обновления карт будут проверяться каждый день. Следующий раз %1$s в %2$s. Обновления карт будут проверяться каждый час. Следующий раз %1$s в %2$s. Удалить обновления - Вы уверены, что хотите удалить все live обновления для %s\? + Вы уверены, что хотите удалить все live-обновления для %s\? Покупки Показать/скрыть Природные границы @@ -4029,9 +4032,9 @@ Сохранить и остановить запись Запись трека остановлена Вы уверены, что хотите остановить запись\? -\nВсе несохраненные данные будут потеряны. +\nВсе несохранённые данные будут потеряны. На паузе - Позволяет избегать больших подъемов при навигации. + Позволяет избегать больших подъёмов при навигации. Переключатель для отображения или скрытия виджета координат. Выберите категорию или добавьте новую Копировать имя POI @@ -4044,8 +4047,8 @@ Выберите цель, чтобы проложить к ней короткий, быстрый или безопасный маршрут Удалить %1$d файлов\? Сохранить и продолжить - Все несохраненные данные будут потеряны. + Все несохранённые данные будут потеряны. Показывать начальный диалог - Если выключено, запись начнется сразу после нажатия на виджет или пункт меню, пропуская диалоговое окно подтверждения. + Если выключено, запись начнётся сразу после нажатия на виджет или пункт меню, пропуская диалоговое окно подтверждения. Интервал записи трека указывает период времени, через который OsmAnd будет запрашивать данные о текущем местоположении. \ No newline at end of file From 15bd1b01fef7368d788807cd086100119cc08b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Thu, 25 Mar 2021 10:55:55 +0000 Subject: [PATCH 027/109] Translated using Weblate (Hungarian) Currently translated at 99.9% (3694 of 3695 strings) --- OsmAnd/res/values-hu/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OsmAnd/res/values-hu/strings.xml b/OsmAnd/res/values-hu/strings.xml index e95128dd82..9796e64f4c 100644 --- a/OsmAnd/res/values-hu/strings.xml +++ b/OsmAnd/res/values-hu/strings.xml @@ -4044,4 +4044,16 @@ Minden nem mentett adat törlődni fog. Kezdő párbeszéd megjelenítése Ha le van tiltva, akkor a felvétel közvetlenül a widget vagy a menüelem megérintése után elindul, kihagyva a megerősítő párbeszédpanelt. + • Az OsmAnd Live frissítések átköltöztek a „Letöltések> Frissítések” helyre +\n +\n• A nyomvonalak színezhetők magasság, sebesség vagy lejtés szerint. +\n +\n• Módoítható a navigációs útvonal megjelenése +\n +\n• Frissült az „Utazás felvétele” párbeszédpanel +\n +\n + Útvonal + Útvonal testreszabása + Szín meghatározása a következő térképmódhoz: %1$s. \ No newline at end of file From 94a78b636ab4092581c88de7f9edfdcfd6f5c913 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Thu, 25 Mar 2021 22:52:17 +0000 Subject: [PATCH 028/109] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-uk/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index 6e7fab1d5f..a2fcf4cd0e 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -4049,4 +4049,17 @@ Усі незбережені дані буде втрачено. Показати діалогове вікно запуску Якщо вимкнено, запис почнеться відразу після торкання до віджета або пункту меню, пропускаючи діалогове вікно підтвердження. + Налаштувати лінію маршруту + Лінія маршруту + Лінія маршруту застосовуватиме %1$s, вказаний у вибраному стилі мапи: %2$s. + Вкажіть колір для режиму мапи: %1$s. + • Оновлення OsmAnd Live переміщено до «Завантаження >Оновлення» +\n +\n• Тепер треки можуть бути забарвлені за висотою, швидкістю або нахилом. +\n +\n• Додано можливість зміни зовнішнього вигляду лінії навігації маршрутом +\n +\n• Оновлено діалогове вікно «Запис поїздки» +\n +\n \ No newline at end of file From b4b32853260e950dfb1602a01b4084efc477a5ba Mon Sep 17 00:00:00 2001 From: ace shadow Date: Thu, 25 Mar 2021 22:32:35 +0000 Subject: [PATCH 029/109] Translated using Weblate (Slovak) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-sk/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-sk/strings.xml b/OsmAnd/res/values-sk/strings.xml index 6c12a3f3b0..4d855b855a 100644 --- a/OsmAnd/res/values-sk/strings.xml +++ b/OsmAnd/res/values-sk/strings.xml @@ -4045,4 +4045,17 @@ Všetky neuložené údaje budú stratené. Zobraziť úvodné okno Ak je vypnuté, záznam začne hneď po stlačení nástroja alebo položky v menu a preskočí okno nastavenia. + • Aktualizácie OsmAnd Live presunuté do \"Sťahovania > Aktualizácie\" +\n +\n • Stopy je teraz možné vyfarbiť podľa nadmorskej výšky, rýchlosti alebo sklonu svahu. +\n +\n • Pridaná možnosť zmeny vzhľadu navigačnej trasy +\n +\n • Vylepšené okno \"Záznam výletu\" +\n +\n + Upraviť navigačnú trasu + Navigačná trasa + Navigačná trasa použije %1$s, zadané na zvolenom štýle mapy: %2$s. + Zadajte farbu pre režim mapy: %1$s. \ No newline at end of file From 17964af6e73faa811cae37c5bba57ae2447f888a Mon Sep 17 00:00:00 2001 From: Yaron Shahrabani Date: Thu, 25 Mar 2021 07:53:48 +0000 Subject: [PATCH 030/109] Translated using Weblate (Hebrew) Currently translated at 99.9% (3693 of 3695 strings) --- OsmAnd/res/values-iw/strings.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OsmAnd/res/values-iw/strings.xml b/OsmAnd/res/values-iw/strings.xml index c320b44aa6..456c757f3c 100644 --- a/OsmAnd/res/values-iw/strings.xml +++ b/OsmAnd/res/values-iw/strings.xml @@ -4053,4 +4053,16 @@ כל הנתונים שלא נשמרו יאבדו. להציג חלונית פתיחה אם האפשרות מושבתת, ההקלטה תתחיל מיד לאחר הנגיעה בווידג׳ט או בפריט שבתפריט תוך דילוג על חלונית האישור. + להתאים קו מסלול אישית + קו מסלול + לציין צבע למצב מפה: %1$s. + • העדכונים החיים של OsmAnd הועברו אל „הורדות > עדכונים” +\n +\n • אפשר לצבוע מסלולים לפי גובה, מהירות או שיפוע. +\n +\n • נוספה אפשרות לשנות את מראה קו מסלול הניווט +\n +\n • החלונית „הקלטת מסלול” עודכנה +\n +\n \ No newline at end of file From cf217b425b44521581acc213f9be7795fe0b8c6d Mon Sep 17 00:00:00 2001 From: Softmap Date: Thu, 25 Mar 2021 22:20:59 +0000 Subject: [PATCH 031/109] Translated using Weblate (Arabic) Currently translated at 99.9% (3693 of 3695 strings) --- OsmAnd/res/values-ar/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index 475178ebc4..d697e4909f 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -4119,4 +4119,17 @@ سيتم فقدان كافة البيانات غير المحفوظة. إظهار مربع حوار البدء حفظ ومتابعة + تخصيص خط المسار + خط المسار + سيستخدم خط الطريق %1$s المحدد في نمط الخريطة المحدد: %2$s. + حدد لونًا لوضع الخريطة: %1$s. + • تم نقل تحديثات OsmAnd Live إلى \"التنزيلات> التحديثات\" +\n +\n • يمكن تلوين المسارات الآن حسب الارتفاع، السرعة أو المنحدر. +\n +\n • خيار مضاف لتغيير مظهر خط مسار الملاحة +\n +\n • تحديث مربع حوار \"تسجيل الرحلة\" +\n +\n \ No newline at end of file From a919a99a892b764a705312d8afb130764d05e191 Mon Sep 17 00:00:00 2001 From: iman Date: Thu, 25 Mar 2021 10:01:39 +0000 Subject: [PATCH 032/109] Translated using Weblate (Persian) Currently translated at 99.9% (3692 of 3695 strings) --- OsmAnd/res/values-fa/strings.xml | 44 +++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index 5196513604..92ceed2233 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -594,8 +594,8 @@ ویرایش OpenStreetMap رد جاری را همین حالا در قالب فایل GPX ذخیره کن. ذخیرهٔ رد جاری - بازهٔ زمانی ثبت هنگام ناوبری - مشخص کنید برای ضبط رد در هنگام ناوبری، فاصلهٔ زمانی ردنگاری چقدر باشد + تناوب ردنگاری هنگام ناوبری + مشخص کنید برای ضبط رد در هنگام ناوبری، تناوب ردنگاری چقدر باشد هنگام ناوبری، یک رد GPX به‌صورت خودکار ضبط و در پوشهٔ ردها (tracks) ذخیره می‌شود. تنظیمات لازم برای ارتباط با (OpenStreetMap.org (OSM را مشخص کنید. زبان را مشخص و داده را دانلود/دوباره بار کنید. @@ -615,7 +615,7 @@ قفل قفل قفل‌گشایی - تنظیم فواصل بیدارباش: + تنظیم تناوب بیدارباش: سرعت شبیه‌سازی مسیر: کل حافظهٔ native اختصاص‌یافته به برنامه %1$s مگابایت (دالویک %2$s مگابایت، بقیه %3$s مگابایت). \nحافظهٔ proportional ‏%4$s مگابایت (حد اندروید %5$s مگابایت، دالویک %6$s مگابایت). @@ -835,8 +835,8 @@ کارت حافظه در حالت فقط‌خواندنی است. \nفقط می‌توانید نقشه‌هایی را ببینید که قبلاً دریافت شده‌اند و نمی‌توانید مناطق جدیدی را دانلود کنید. خدمات ناوبری OsmAnd - بازهٔ بیدارباش سرویس پس‌زمینه: - بازهٔ زمانی بیدارباش GPS + تناوب بیدارباش برای سرویس پس‌زمینه: + تناوب بیدارباش GPS شیوهٔ موقعیت‌یابی سرویس پس‌زمینه: ارائه‌دهندهٔ موقعیت زمانی که صفحه خاموش است موقعیت شما را ردگیری می‌کند. @@ -913,8 +913,8 @@ لایه‌های شب‌نما یادداشت‌ها یا POIهای OSMای ذخیره‌شده روی دستگاه مشاهده و مدیریت POIها یا یادداشت‌های OSMای که روی دستگاه شما قرار دارند. - بازهٔ زمانی ردیابی آنلاین را مشخص کنید. - بازهٔ زمانی ردیابی آنلاین + تناوب ردیابی آنلاین را مشخص کنید. + تناوب ردیابی آنلاین برنامهٔ OsmAnd (مخفف OSM Automated Navigation Directions به‌معنی راهنمای خودکار ناوبری بر پایهٔ OSM) یک نرم‌افزار ناوبری متن‌باز است که به گسترهٔ وسیعی از دادهٔ جهانی OSM دسترسی دارد. \n \nتمام دادهٔ نقشه (بُرداری یا کاشی) را می‌توانید برای استفادهٔ آفلاین روی کارت حافظه ذخیره کنید. @@ -1198,7 +1198,7 @@ هم‌رسانی مسیر در قالب فایل GPX مسیر از طریق OsmAnd هم‌رسانی شد دستی (روی فِلِش بزنید) - فرمان‌های ناوبری در بازه‌های منظم بازگو می‌شود. + فرمان‌های ناوبری در فاصله‌های زمانی منظم بازگو می‌شود. تکرار فرمان‌های ناوبری قالب نامعتبر: %s اعلام رسیدن @@ -1258,7 +1258,7 @@ نگه‌داشتن توقف فعال‌کردن حالت پس‌زمینهٔ GPS - بازهٔ بیدارباش GPS + تناوب بیدارباش GPS حالت پس‌زمینهٔ GPS متوقف شود؟ زبان ارجح برای نقشه سواحیلی @@ -1306,9 +1306,9 @@ کیفیت راه سطح راه مسیرهای دوچرخه - بازهٔ زمانی ثبت (سراسری) + تناوب ردنگاری عمومی می‌توانید با استفاده از ابزارک ضبط GPX روی نقشه، ردنگاری در فایل GPX را خاموش یا روشن کنید. - بازهٔ زمانی ثبت + تناوب ردنگاری این افزونه یک ابزارک ضبط GPX روی نقشه اضافه می‌کند و با انتخاب آن می‌توانید رد خود را ضبط و در قالب فایل GPX ذخیره کنید. همچنین این امکان را فراهم می‌کند که هنگام مسیریابی، به‌طور خودکار این کار برای شما انجام شود. \n \nردهای ضبط‌شده را با دوستان یا برای استفاده در مشارکت‌های OSM هم‌رسانی کنید. @@ -1689,7 +1689,7 @@ اعلام هوشمند خودکار فقط اگر جهتم از سمت نقطهٔ مقصد منحرف شد، اعلام شود. بازهٔ زمانی اعلام خودکار - بازهٔ زمانی کمینی بین اعلام پیام‌ها. + تناوب زمانی کمینی بین اعلام پیام‌ها. رنگ پیش‌فرض انتخاب دسته نام @@ -3374,7 +3374,7 @@ اثرات جانبی: بازه‌های توقف یا اصلاً ضبط نخواهند شد یا فقط یک نقطه به‌ازای هر کدام ضبط می‌شود. جابه‌جایی‌های واقعیِ کوچک احتمالاً حذف می‌شود. فایل نهایی اطلاعات کمتری برای پس‌پردازش خواهد داشت و همچنین با حذف نقاط زائد در هنگام ضبط و حفظ بالقوهٔ نقاط غیرواقعی (ناشی از گیرایی ضعیف یا اثرات چیپست GPS) اطلاعات آماریِ فایل بدتر می‌شود. توصیه: اگر به جزئیات بیشتر از ۵ متر نیاز ندارید و در زمان توقف نمی‌خواهید داده ضبط کنید، تنظیم حدود ۵ متر احتمالاً خوب جواب بدهد. مدت حافظهٔ تأخیری - بازهٔ زمانی ردیابی + تناوب ردیابی نشانی وب نشانی اینترنتی را با این پارامترها تعریف کنید: \nlat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6} @@ -3813,7 +3813,7 @@ %s فایل رد انتخاب شده است ضبط هنگامی که برنامه را از طریق برنامه‌های اخیر ببندید ضبط رد به‌طور موقت می‌ایستد. (نشانگر اجرای پس‌زمینه از نوار اعلان حذف می‌شود.) - بازهٔ زمانی برای ضبط رد را انتخاب کنید (که از طریق ابزارک ضبط سفر روی نقشه روشن می‌شود). + تناوب ردنگاری عمومی را انتخاب کنید (که از طریق ابزارک ضبط سفر روی نقشه روشن می‌شود). نگه‌داشتن ضبط سفر ازسرگیری ضبط سفر اسکیت این‌لاین @@ -4061,7 +4061,7 @@ آمادگی خروج از مسیر رسیدن به مقصد - بازه‌های زمانی و مسافتی + تناوب زمانی و مسافتی زمان اعلام پیام‌های گفتاری به نوع پیام، سرعت ناوبری جاری و سرعت ناوبری پیش‌فرض بستگی دارد. زمان اعلام پیام شروع دوباره @@ -4073,4 +4073,18 @@ نمایش کادر آغاز اگر غیرفعال باشد، بلافاصله پس از لمس ابزارک یا آیتم منو، ضبط آغاز می‌شود و کادر تأیید ظاهر نمی‌شود. تمام دادهٔ ذخیره‌نشده از دست خواهد رفت. + برای خط مسیر از %1$s استفاده می‌شود که در سبک انتخاب‌شده برای نقشه (%2$s) مشخص شده است. + رنگ حالت نقشهٔ %1$s را مشخص کنید. + تناوب ردنگاری مشخص می‌کند OsmAnd هر چند وقت یک بار دادهٔ مربوط به موقعیت جاری را درخواست کند. + سفارشی‌سازی خط مسیر + خط مسیر + • روزآمدسازه‌های OsmAnd Live منتقل شد به Downloads ‏> Updates +\n +\n• اکنون می‌توانید رنگ‌بندی ردها را بر اساس ارتفاع، سرعت یا شیب انجام دهید. +\n +\n• گزینه‌ای برای تغییر ظاهر خط مسیر هنگام ناوبری اضافه شد. +\n +\n• کادر «ضبط سفر» روزآمد شد. +\n +\n \ No newline at end of file From befb22b2187544ae1155438857e05ce02a3b77f2 Mon Sep 17 00:00:00 2001 From: ovl-1 Date: Thu, 25 Mar 2021 09:17:13 +0000 Subject: [PATCH 033/109] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegi?= =?UTF-8?q?an=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 60.8% (2249 of 3695 strings) --- OsmAnd/res/values-nb/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-nb/strings.xml b/OsmAnd/res/values-nb/strings.xml index c902064e98..c0254ccc92 100644 --- a/OsmAnd/res/values-nb/strings.xml +++ b/OsmAnd/res/values-nb/strings.xml @@ -3941,4 +3941,8 @@ Ruting kan unngå kraftige oppoverbakker. Lagre og fortsett All ulagret data vil gå tapt. + Vis startdialog + Tilpass rutelinje + Rutelinje + Angi farge for kartmodus: %1$s. \ No newline at end of file From 199c7772bab8f4119bec5651704bc2a7e8c7c4ba Mon Sep 17 00:00:00 2001 From: Franco Date: Thu, 25 Mar 2021 14:16:45 +0000 Subject: [PATCH 034/109] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (3694 of 3695 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 720dccf045..91493663a7 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -4052,4 +4052,17 @@ Se perderán todos los datos no guardados. Mostrar el diálogo inicial Si se desactiva, la grabación será iniciada al pulsar el widget o el elemento del menú, saltándose el diálogo de confirmación. + Personalizar línea de ruta + Línea de ruta + La línea de la ruta sería el uso %1$s especificado en el estilo de mapa seleccionado: %2$s. + Define el color para el modo de mapa: %1$s. + • Las actualizaciones de OsmAnd Live se movieron a «Descargas > Actualizaciones» +\n +\n • Las trazas ahora se pueden colorear por altitud, velocidad o pendiente. +\n +\n • Se añade opción para cambiar la apariencia de la línea de ruta de navegación +\n +\n • Se actualiza el cuadro de diálogo «Grabación de viaje» +\n +\n \ No newline at end of file From e8c0064cb7004abb4aa927250674c9a27710e32c Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Thu, 25 Mar 2021 17:06:19 +0000 Subject: [PATCH 035/109] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-pt-rBR/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-pt-rBR/strings.xml b/OsmAnd/res/values-pt-rBR/strings.xml index 0c4060b65a..30546270a5 100644 --- a/OsmAnd/res/values-pt-rBR/strings.xml +++ b/OsmAnd/res/values-pt-rBR/strings.xml @@ -4045,4 +4045,17 @@ O intervalo de registro define o período de tempo no qual OsmAnd solicitará os dados de posição de localização atual. Mostrar caixa de diálogo inicial Se desativado, a gravação começará logo após tocar no widget ou item de menu, pulando a caixa de diálogo de confirmação. + Personalizar linha de rota + Linha de rota + A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s. + Especifique a cor para o modo de mapa: %1$s. + "• As atualizações do OsmAnd Live foram movidas para \"Downloads > Atualizações\" +\n +\n • As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação. +\n +\n • Adicionada opção para alterar a aparência da linha da rota de navegação +\n +\n • Caixa de diálogo \"Gravação de viagem\" atualizada +\n +\n" \ No newline at end of file From 393e4b06d31528a2b933f641605af14e283550c2 Mon Sep 17 00:00:00 2001 From: Verdulo Date: Thu, 25 Mar 2021 14:41:00 +0000 Subject: [PATCH 036/109] Translated using Weblate (Esperanto) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-eo/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-eo/strings.xml b/OsmAnd/res/values-eo/strings.xml index 0eb1180e72..1063075114 100644 --- a/OsmAnd/res/values-eo/strings.xml +++ b/OsmAnd/res/values-eo/strings.xml @@ -4050,4 +4050,17 @@ Konservi kaj daŭrigi Se malŝaltita, registrado komenciĝos tuj post frapeto sur la fenestraĵo aŭ menuero, preterlasante la konfirman dialogon. Montri komencan dialogon + Elektu koloron por map‑reĝimo: %1$s. + Alĝustigi linion de kurso + Linio de kurso + Por la linio de kurso estos uzata %1$s difinita por la map‑stilo: %2$s. + • ĝisdatigoj OsmAnd Live movitaj al “elŝutoj” → “ĝisdatigoj” +\n +\n• eblo kolorigi spurojn laŭ altitudo, rapido aŭ dekliveco +\n +\n• eblo ŝanĝi aspekton de linio de la navigata kurso +\n +\n• plibonigita ekrano “registri spuron” +\n +\n \ No newline at end of file From aaff5c3f7c29e92a4c8b835e96df80160336a2c7 Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Fri, 26 Mar 2021 01:43:11 +0000 Subject: [PATCH 037/109] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-zh-rTW/strings.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OsmAnd/res/values-zh-rTW/strings.xml b/OsmAnd/res/values-zh-rTW/strings.xml index a40440e789..a12ea721bc 100644 --- a/OsmAnd/res/values-zh-rTW/strings.xml +++ b/OsmAnd/res/values-zh-rTW/strings.xml @@ -4043,4 +4043,17 @@ 所有未儲存的資料都將會遺失。 顯示開始對話框 若停用,則在點擊小工具或選單項目後將跳過確認對話框,立刻開始。 + 自訂路線 + 路線 + 路線將會使用 %1$s 在選定的地圖樣式上指定的:%2$s。 + 指定地圖模式的顏色:%1$s。 + • OsmAnd Live 更新移動至「下載 > 更新」 +\n +\n • 軌跡現在可以使用海拔、速度或坡度來填色 +\n +\n • 新增了變更導航路線外觀的選項 +\n +\n • 更新「旅程錄製」對話框 +\n +\n \ No newline at end of file From ee7e8bf3eb0cb1dc286569f47e75b7a43454dfa5 Mon Sep 17 00:00:00 2001 From: Artem Date: Thu, 25 Mar 2021 08:03:50 +0000 Subject: [PATCH 038/109] Translated using Weblate (Russian) Currently translated at 99.8% (3888 of 3894 strings) --- OsmAnd/res/values-ru/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml index 7b2f28b784..660f3dae0d 100644 --- a/OsmAnd/res/values-ru/phrases.xml +++ b/OsmAnd/res/values-ru/phrases.xml @@ -3886,4 +3886,6 @@ Название трассы Лыжный трамплин По лесу: да + Туннель летучих мышей + Мост летучих мышей \ No newline at end of file From 83902e281a2379a3854125b154aa86494f727f1f Mon Sep 17 00:00:00 2001 From: solokot Date: Thu, 25 Mar 2021 07:40:20 +0000 Subject: [PATCH 039/109] Translated using Weblate (Russian) Currently translated at 99.8% (3888 of 3894 strings) --- OsmAnd/res/values-ru/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-ru/phrases.xml b/OsmAnd/res/values-ru/phrases.xml index 660f3dae0d..5735fbfac4 100644 --- a/OsmAnd/res/values-ru/phrases.xml +++ b/OsmAnd/res/values-ru/phrases.xml @@ -3888,4 +3888,5 @@ По лесу: да Туннель летучих мышей Мост летучих мышей + Конференц-центр \ No newline at end of file From a4e1d93f9e1446a1a83205c6d15a8d1b41a356d2 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 11:38:24 +0200 Subject: [PATCH 040/109] small fixes --- .../monitoring/TripRecordingClearDataBottomSheet.java | 3 ++- .../monitoring/TripRecordingDiscardBottomSheet.java | 3 ++- .../monitoring/TripRecordingOptionsBottomSheet.java | 10 ++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java index e6b820fae2..cf09a2e7f0 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java @@ -11,6 +11,7 @@ import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; +import net.osmand.plus.monitoring.TripRecordingBottomSheet.DismissTargetFragment; import net.osmand.plus.monitoring.TripRecordingBottomSheet.ItemType; import androidx.annotation.NonNull; @@ -20,7 +21,7 @@ import androidx.fragment.app.FragmentManager; import static net.osmand.AndroidUtils.getPrimaryTextColorId; import static net.osmand.plus.monitoring.TripRecordingOptionsBottomSheet.ACTION_CLEAR_DATA; -public class TripRecordingClearDataBottomSheet extends MenuBottomSheetDialogFragment implements TripRecordingBottomSheet.DismissTargetFragment { +public class TripRecordingClearDataBottomSheet extends MenuBottomSheetDialogFragment implements DismissTargetFragment { public static final String TAG = TripRecordingClearDataBottomSheet.class.getSimpleName(); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java index cff99d9daa..1136980b51 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java @@ -12,6 +12,7 @@ import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; +import net.osmand.plus.monitoring.TripRecordingBottomSheet.DismissTargetFragment; import net.osmand.plus.monitoring.TripRecordingBottomSheet.ItemType; import androidx.annotation.NonNull; @@ -21,7 +22,7 @@ import androidx.fragment.app.FragmentManager; import static net.osmand.AndroidUtils.getPrimaryTextColorId; import static net.osmand.plus.monitoring.TripRecordingOptionsBottomSheet.ACTION_STOP_AND_DISMISS; -public class TripRecordingDiscardBottomSheet extends MenuBottomSheetDialogFragment implements TripRecordingBottomSheet.DismissTargetFragment { +public class TripRecordingDiscardBottomSheet extends MenuBottomSheetDialogFragment implements DismissTargetFragment { public static final String TAG = TripRecordingDiscardBottomSheet.class.getSimpleName(); diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java index 5aa2aabd3a..f72de8a640 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java @@ -26,7 +26,7 @@ import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; -import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.monitoring.TripRecordingBottomSheet.DismissTargetFragment; import net.osmand.plus.monitoring.TripRecordingBottomSheet.ItemType; import net.osmand.plus.myplaces.SaveCurrentTrackTask; import net.osmand.plus.settings.backend.OsmandSettings; @@ -36,7 +36,7 @@ import net.osmand.util.Algorithms; import static net.osmand.AndroidUtils.getPrimaryTextColorId; import static net.osmand.plus.monitoring.TripRecordingBottomSheet.UPDATE_DYNAMIC_ITEMS; -public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragment implements TripRecordingBottomSheet.DismissTargetFragment { +public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragment implements DismissTargetFragment { public static final String TAG = TripRecordingOptionsBottomSheet.class.getSimpleName(); public static final String ACTION_STOP_AND_DISMISS = "action_stop_and_discard"; @@ -212,8 +212,10 @@ public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragme @Override public void run() { String time = getTimeTrackSaved(); - TripRecordingBottomSheet.createItem(app, nightMode, buttonSave, ItemType.SAVE, hasDataToSave(), !Algorithms.isEmpty(time) ? time : null); - TripRecordingBottomSheet.createItem(app, nightMode, buttonClear, ItemType.CLEAR_DATA, hasDataToSave(), null); + TripRecordingBottomSheet.createItem(app, nightMode, buttonSave, ItemType.SAVE, + hasDataToSave(), !Algorithms.isEmpty(time) ? time : null); + TripRecordingBottomSheet.createItem(app, nightMode, buttonClear, ItemType.CLEAR_DATA, + hasDataToSave(), null); handler.postDelayed(this, SAVE_UPDATE_INTERVAL); } }; From 0addf8d56bae6c78adfed861c55ef3cb47029486 Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 12:54:53 +0200 Subject: [PATCH 041/109] fix updating graphs after starting a new segment --- .../plus/myplaces/GPXItemPagerAdapter.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index 42609ad9e1..984f588341 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -33,11 +33,13 @@ import net.osmand.GPXUtilities.TrkSegment; import net.osmand.GPXUtilities.WptPt; import net.osmand.plus.GPXDatabase.GpxDataItem; import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; +import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.CustomRadioButtonType; +import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; @@ -132,17 +134,26 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private List getDataSets(LineChart chart, GPXTabItemType tabType, LineGraphType firstType, LineGraphType secondType) { List dataSets = dataSetsMap.get(tabType); - if (gpxItem != null) { - GPXTrackAnalysis analysis = gpxItem.analysis; + GPXTrackAnalysis analysis = null; + boolean withoutGaps = true; + SavingTrackHelper helper = app.getSavingTrackHelper(); + if (displayHelper.getGpx().equals(helper.getCurrentGpx())) { + SelectedGpxFile selectedGpxFile = helper.getCurrentTrack(); + GPXFile currentGpx = selectedGpxFile.getGpxFile(); + analysis = currentGpx.getAnalysis(0); + withoutGaps = !selectedGpxFile.isJoinSegments() + && (Algorithms.isEmpty(currentGpx.tracks) || currentGpx.tracks.get(0).generalTrack); + } else if (gpxItem != null) { + analysis = gpxItem.analysis; GpxDataItem gpxDataItem = displayHelper.getGpxDataItem(); - boolean calcWithoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments(); - if (chart != null) { - dataSets = GpxUiHelper.getDataSets(chart, app, analysis, firstType, secondType, calcWithoutGaps); - if (dataSets != null) { - dataSetsMap.remove(tabType); - } - dataSetsMap.put(tabType, dataSets); + withoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments(); + } + if (chart != null && analysis != null) { + dataSets = GpxUiHelper.getDataSets(chart, app, analysis, firstType, secondType, withoutGaps); + if (dataSets != null) { + dataSetsMap.remove(tabType); } + dataSetsMap.put(tabType, dataSets); } return dataSets; } @@ -217,12 +228,12 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid public Object instantiateItem(@NonNull ViewGroup container, int position) { GPXTabItemType tabType = tabTypes[position]; View view = getViewForTab(container, tabType); + LineChart chart = view.findViewById(R.id.chart); + ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) chart.getLayoutParams(); + AndroidUtils.setMargins(lp, chartHMargin, lp.topMargin, chartHMargin, lp.bottomMargin); GPXFile gpxFile = displayHelper.getGpx(); if (gpxFile != null && gpxItem != null) { GPXTrackAnalysis analysis = gpxItem.analysis; - LineChart chart = view.findViewById(R.id.chart); - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) chart.getLayoutParams(); - AndroidUtils.setMargins(lp, chartHMargin, lp.topMargin, chartHMargin, lp.bottomMargin); setupChart(view, chart); switch (tabType) { From e3b4786556aae5ea163c98386be549c6e71ea68d Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 13:17:45 +0200 Subject: [PATCH 042/109] small refactoring --- .../LiveUpdatesSettingsBottomSheet.java | 188 +++++++++--------- .../LiveUpdatesUpdateAllBottomSheet.java | 6 +- 2 files changed, 95 insertions(+), 99 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index 910ad7da1e..f67128dbe0 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -76,16 +76,17 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen private OsmandApplication app; private OsmandSettings settings; - private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange; + + private BaseBottomSheetItem itemLastCheck; + private BaseBottomSheetItem itemSwitchLiveUpdate; + private BaseBottomSheetItem itemFrequencyHelpMessage; + private BaseBottomSheetItem itemClear; + private BaseBottomSheetItem itemViaWiFi; private MultiStateToggleButton frequencyToggleButton; private MultiStateToggleButton timeOfDayToggleButton; private String fileName; - private int indexLastCheckItem = -1; - private int indexSwitchLiveUpdateItem = -1; - private int indexFrequencyHelpMessageItem = -1; - private int indexClearItem = -1; - private int indexViaWiFiItem = -1; + private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange; public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target, String fileName) { if (!fragmentManager.isStateSaved()) { @@ -122,20 +123,20 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .setLayoutId(R.layout.bottom_sheet_item_title_big) .create()); - items.add(new ShortDescriptionItem.Builder() + itemLastCheck = new ShortDescriptionItem.Builder() .setDescription(getLastCheckString()) .setDescriptionColorId(getSecondaryTextColorId(nightMode)) .setDescriptionMaxLines(2) .setLayoutId(R.layout.bottom_sheet_item_description) - .create()); - indexLastCheckItem = items.size() - 1; + .create(); + items.add(itemLastCheck); View itemLiveUpdate = getCustomButtonView(app, null, localUpdatePreference.get(), nightMode); View itemLiveUpdateButton = itemLiveUpdate.findViewById(R.id.button_container); CompoundButton button = (CompoundButton) itemLiveUpdateButton.findViewById(R.id.compound_button); UiUtilities.setupCompoundButton(button, nightMode, TOOLBAR); itemLiveUpdateButton.setMinimumHeight(getDimen(R.dimen.bottom_sheet_selected_item_title_height)); - items.add(new BottomSheetItemWithCompoundButton.Builder() + itemSwitchLiveUpdate = new BottomSheetItemWithCompoundButton.Builder() .setChecked(localUpdatePreference.get()) .setTitle(getStateText(localUpdatePreference.get())) .setTitleColorId(getActiveTabTextColorId(nightMode)) @@ -143,32 +144,29 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (indexSwitchLiveUpdateItem != -1) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexSwitchLiveUpdateItem); - button.setChecked(!button.isChecked()); - if (onLiveUpdatesForLocalChange != null - && onLiveUpdatesForLocalChange.onUpdateLocalIndex(fileName, button.isChecked(), new Runnable() { - @Override - public void run() { - updateLastCheck(); - updateFrequencyHelpMessage(); - updateFileSize(); - } - })) { - if (indexSwitchLiveUpdateItem != -1 && items.size() > 0) { - button.setTitle(getStateText(button.isChecked())); - updateCustomButtonView(app, null, button.getView(), button.isChecked(), nightMode); - } - CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); - frequencyToggleButton.updateView(localUpdatePreference.get()); - timeOfDayToggleButton.updateView(localUpdatePreference.get()); - setStateViaWiFiButton(localUpdatePreference); + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemSwitchLiveUpdate; + boolean checked = item.isChecked(); + item.setChecked(!checked); + if (onLiveUpdatesForLocalChange != null + && onLiveUpdatesForLocalChange.onUpdateLocalIndex(fileName, !checked, new Runnable() { + @Override + public void run() { + updateLastCheck(); + updateFrequencyHelpMessage(); + updateFileSize(); } + })) { + item.setTitle(getStateText(!checked)); + updateCustomButtonView(app, null, item.getView(), !checked, nightMode); + CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); + frequencyToggleButton.updateView(localUpdatePreference.get()); + timeOfDayToggleButton.updateView(localUpdatePreference.get()); + setStateViaWiFiButton(localUpdatePreference); } } }) - .create()); - indexSwitchLiveUpdateItem = items.size() - 1; + .create(); + items.add(itemSwitchLiveUpdate); TextViewEx frequencyTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); frequencyTitle.setHeight(dp48); @@ -181,7 +179,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .create()); LinearLayout itemFrequencyButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); - LinearLayout.MarginLayoutParams itemFrequencyParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); + LinearLayout.MarginLayoutParams itemFrequencyParams = new LinearLayout.MarginLayoutParams( + LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); AndroidUtils.setMargins(itemFrequencyParams, dp16, 0, dp16, dp12); itemFrequencyButtons.setLayoutParams(itemFrequencyParams); @@ -211,7 +210,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .create()); LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); - LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams(LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); + LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams( + LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, getDimen(R.dimen.context_menu_padding_margin_medium)); itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams); @@ -236,14 +236,15 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .create() ); - items.add(new ShortDescriptionItem.Builder() + itemFrequencyHelpMessage = new ShortDescriptionItem.Builder() .setDescription(getFrequencyHelpMessage()) .setDescriptionColorId(getSecondaryTextColorId(nightMode)) .setLayoutId(R.layout.bottom_sheet_item_description) - .create()); - indexFrequencyHelpMessageItem = items.size() - 1; + .create(); + items.add(itemFrequencyHelpMessage); - LinearLayout itemUpdateNowButton = (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null); + LinearLayout itemUpdateNowButton = + (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null); LinearLayout.MarginLayoutParams itemUpdateNowParams = new LinearLayout.MarginLayoutParams( LinearLayout.MarginLayoutParams.MATCH_PARENT, getDimen(R.dimen.measurement_tool_button_height)); AndroidUtils.setMargins(itemUpdateNowParams, dp12, dp12, dp16, dp12); @@ -281,50 +282,47 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen int iconDeleteColor = ContextCompat.getColor(app, R.color.color_osm_edit_delete); Drawable iconDelete = AppCompatResources.getDrawable(app, R.drawable.ic_action_delete_dark); - items.add( - new BottomSheetItemWithDescription.Builder() - .setDescription(getUpdatesSizeStr()) - .setIcon(UiUtilities.tintDrawable(iconDelete, iconDeleteColor)) - .setTitle(getString(R.string.updates_size)) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_icon_right) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getUpdatesSize() > 0) { - if (getFragmentManager() != null) { - LiveUpdatesClearBottomSheet.showInstance(getFragmentManager(), - LiveUpdatesSettingsBottomSheet.this, fileName); - } - } + itemClear = new BottomSheetItemWithDescription.Builder() + .setDescription(getUpdatesSizeStr()) + .setIcon(UiUtilities.tintDrawable(iconDelete, iconDeleteColor)) + .setTitle(getString(R.string.updates_size)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_icon_right) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (getUpdatesSize() > 0) { + if (getFragmentManager() != null) { + LiveUpdatesClearBottomSheet.showInstance(getFragmentManager(), + LiveUpdatesSettingsBottomSheet.this, fileName); } - }) - .create() - ); - indexClearItem = items.size() - 1; + } + } + }) + .create(); + items.add(itemClear); items.add(createDividerItem()); - items.add( - new BottomSheetItemWithCompoundButton.Builder() - .setChecked(downloadViaWiFiPreference.get()) - .setDescription(getStateText(downloadViaWiFiPreference.get())) - .setIconHidden(true) - .setTitle(getString(R.string.only_download_over_wifi)) - .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_switch_56dp) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (preferenceForLocalIndex(fileName, settings).get() && indexViaWiFiItem != -1 && items.size() > 0) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem); - button.setChecked(!button.isChecked()); - button.setDescription(getStateText(button.isChecked())); - preferenceDownloadViaWiFi(fileName, settings).set(button.isChecked()); - } - } - }) - .create() - ); - indexViaWiFiItem = items.size() - 1; + itemViaWiFi = new BottomSheetItemWithCompoundButton.Builder() + .setChecked(downloadViaWiFiPreference.get()) + .setDescription(getStateText(downloadViaWiFiPreference.get())) + .setIconHidden(true) + .setTitle(getString(R.string.only_download_over_wifi)) + .setLayoutId(R.layout.bottom_sheet_item_with_descr_and_switch_56dp) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (preferenceForLocalIndex(fileName, settings).get()) { + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemViaWiFi; + boolean checked = item.isChecked(); + item.setChecked(!checked); + item.setDescription(getStateText(!checked)); + preferenceDownloadViaWiFi(fileName, settings).set(!checked); + } + } + }) + .create(); + items.add(itemViaWiFi); items.add(new DividerSpaceItem(app, getDimen(R.dimen.context_menu_padding_margin_large))); } @@ -345,12 +343,12 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen } private void setStateViaWiFiButton(CommonPreference localUpdatePreference) { - if (indexViaWiFiItem != -1 && items.size() > 0) { - BottomSheetItemWithCompoundButton button = (BottomSheetItemWithCompoundButton) items.get(indexViaWiFiItem); - if (button.getView() != null) { - TextView title = button.getView().findViewById(R.id.title); - TextView description = button.getView().findViewById(R.id.description); - CompoundButton compoundButton = button.getView().findViewById(R.id.compound_button); + if (itemViaWiFi != null) { + BottomSheetItemWithCompoundButton item = (BottomSheetItemWithCompoundButton) itemViaWiFi; + if (item.getView() != null) { + TextView title = item.getView().findViewById(R.id.title); + TextView description = item.getView().findViewById(R.id.description); + CompoundButton compoundButton = item.getView().findViewById(R.id.compound_button); if (localUpdatePreference.get()) { AndroidUtils.setTextPrimaryColor(app, title, nightMode); AndroidUtils.setTextSecondaryColor(app, description, nightMode); @@ -365,23 +363,20 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen } private void updateLastCheck() { - if (indexLastCheckItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexLastCheckItem)) - .setDescription(getLastCheckString()); + if (itemLastCheck != null) { + ((BottomSheetItemWithDescription) itemLastCheck).setDescription(getLastCheckString()); } } private void updateFrequencyHelpMessage() { - if (indexFrequencyHelpMessageItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexFrequencyHelpMessageItem)) - .setDescription(getFrequencyHelpMessage()); + if (itemFrequencyHelpMessage != null) { + ((BottomSheetItemWithDescription) itemFrequencyHelpMessage).setDescription(getFrequencyHelpMessage()); } } private void updateFileSize() { - if (indexClearItem != -1 && items.size() > 0) { - ((BottomSheetItemWithDescription) items.get(indexClearItem)) - .setDescription(getUpdatesSizeStr()); + if (itemClear != null) { + ((BottomSheetItemWithDescription) itemClear).setDescription(getUpdatesSizeStr()); } } @@ -413,7 +408,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen CommonPreference updateFrequency = preferenceUpdateFrequency(fileName, settings); CommonPreference timeOfDayToUpdate = preferenceTimeOfDayToUpdate(fileName, settings); final long lastUpdate = preferenceLatestUpdateAvailable(fileName, settings).get(); - return formatHelpDateTime(app, UpdateFrequency.values()[updateFrequency.get()], TimeOfDay.values()[timeOfDayToUpdate.get()], lastUpdate); + return formatHelpDateTime(app, UpdateFrequency.values()[updateFrequency.get()], + TimeOfDay.values()[timeOfDayToUpdate.get()], lastUpdate); } private long getUpdatesSize() { @@ -458,7 +454,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen } } - private OnRadioItemClickListener getFrequencyButtonListener(@NonNull final UpdateFrequency type, final View... timeOfDayLayouts) { + private OnRadioItemClickListener getFrequencyButtonListener( + @NonNull final UpdateFrequency type, final View... timeOfDayLayouts) { return new OnRadioItemClickListener() { @Override public boolean onRadioItemClick(RadioItem radioItem, View view) { @@ -543,5 +540,4 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen protected int getDismissButtonTextId() { return R.string.shared_string_close; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java index 8cef25af27..ace4abac20 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java @@ -40,6 +40,9 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme private OsmandApplication app; private OsmandSettings settings; + private BaseBottomSheetItem itemTitle; + private BaseBottomSheetItem itemDescription; + private List mapsList; private LiveUpdateListener listener; @@ -61,9 +64,6 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme } } - BaseBottomSheetItem itemTitle; - BaseBottomSheetItem itemDescription; - @Override public void createMenuItems(Bundle savedInstanceState) { app = getMyApplication(); From 5c83a31c771cdacff42beb62c63916a9b9b44e5e Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 14:31:22 +0200 Subject: [PATCH 043/109] fix "Latest OpenStreetMap..." bar with time now scrollable; add free space under the "Available maps" card; --- OsmAnd/res/layout/fragment_live_updates.xml | 4 ++-- .../src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/layout/fragment_live_updates.xml b/OsmAnd/res/layout/fragment_live_updates.xml index 0f3894de1e..65a4ecdd3f 100644 --- a/OsmAnd/res/layout/fragment_live_updates.xml +++ b/OsmAnd/res/layout/fragment_live_updates.xml @@ -41,8 +41,6 @@ - - diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 2536c4693f..f1da30b5d4 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -203,8 +203,11 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL toolbarSwitchContainer = view.findViewById(R.id.toolbar_switch_container); updateToolbarSwitch(settings.IS_LIVE_UPDATES_ON.get()); - View timeContainer = view.findViewById(R.id.item_import_container); + View headerView = inflater.inflate(R.layout.list_item_import, listView, false); + View timeContainer = headerView.findViewById(R.id.item_import_container); AndroidUtils.setListItemBackground(app, timeContainer, nightMode); + AndroidUiHelper.setVisibility(View.VISIBLE, headerView.findViewById(R.id.bottom_divider)); + listView.addHeaderView(headerView); AppCompatImageView descriptionIcon = timeContainer.findViewById(R.id.icon); Drawable icon = UiUtilities.createTintedDrawable(app, R.drawable.ic_action_time, From ff26a082f909e3d1c68efdbcfa95e6865606d06a Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 14:49:10 +0200 Subject: [PATCH 044/109] fix free space of help icon; fix help page now opens in "chrome tabs"; --- OsmAnd/res/layout/fragment_live_updates.xml | 16 ++++++++-------- .../plus/liveupdates/LiveUpdatesFragment.java | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/OsmAnd/res/layout/fragment_live_updates.xml b/OsmAnd/res/layout/fragment_live_updates.xml index 65a4ecdd3f..0f264763e5 100644 --- a/OsmAnd/res/layout/fragment_live_updates.xml +++ b/OsmAnd/res/layout/fragment_live_updates.xml @@ -26,13 +26,13 @@ @@ -52,14 +52,14 @@ android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" + android:clipToPadding="false" android:divider="@null" android:drawSelectorOnTop="true" android:footerDividersEnabled="false" android:groupIndicator="@null" android:headerDividersEnabled="false" - android:paddingBottom="@dimen/bottom_sheet_list_item_height" - android:clipToPadding="false" android:orientation="vertical" + android:paddingBottom="@dimen/bottom_sheet_list_item_height" tools:context=".liveupdates.LiveUpdatesFragment" /> diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index f1da30b5d4..d1fd883db3 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -58,6 +58,7 @@ import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.TextViewEx; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; @@ -155,9 +156,9 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL iconHelp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SUBSCRIPTION_URL)); - if (AndroidUtils.isIntentSafe(app, intent)) { - startActivity(intent); + Activity activity = getActivity(); + if (activity != null) { + WikipediaDialogFragment.showFullArticle(activity, Uri.parse(SUBSCRIPTION_URL), nightMode); } } }); From 16efbfd7f5ec8cecab4bc1c680e3ff2bc9f7c06e Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 15:37:22 +0200 Subject: [PATCH 045/109] fix landscape app bar text size; refactoring app bar; --- OsmAnd/res/layout/fragment_live_updates.xml | 34 +-------- .../plus/liveupdates/LiveUpdatesFragment.java | 73 +++++++++++-------- 2 files changed, 43 insertions(+), 64 deletions(-) diff --git a/OsmAnd/res/layout/fragment_live_updates.xml b/OsmAnd/res/layout/fragment_live_updates.xml index 0f264763e5..93c11c599f 100644 --- a/OsmAnd/res/layout/fragment_live_updates.xml +++ b/OsmAnd/res/layout/fragment_live_updates.xml @@ -1,5 +1,4 @@ - - - - - - - - - - + android:orientation="vertical" /> Date: Fri, 26 Mar 2021 16:48:43 +0200 Subject: [PATCH 046/109] fix text style in OsmAnd Live banner --- OsmAnd/res/layout/osm_live_banner_list_item.xml | 10 ++++++---- .../osmand/plus/download/ui/UpdatesIndexFragment.java | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/OsmAnd/res/layout/osm_live_banner_list_item.xml b/OsmAnd/res/layout/osm_live_banner_list_item.xml index 05d83d8da1..12f59c3ef0 100644 --- a/OsmAnd/res/layout/osm_live_banner_list_item.xml +++ b/OsmAnd/res/layout/osm_live_banner_list_item.xml @@ -29,13 +29,14 @@ android:layout_weight="1" android:orientation="vertical"> - + android:textSize="@dimen/default_list_text_size" + osmand:typeface="@string/font_roboto_medium" /> - + android:textSize="@dimen/default_desc_text_size" + osmand:typeface="@string/font_roboto_medium" /> Date: Fri, 26 Mar 2021 16:59:22 +0200 Subject: [PATCH 047/109] fix text style for "Update frequency" and "Update time" items --- .../src/net/osmand/plus/download/ui/UpdatesIndexFragment.java | 2 +- .../plus/liveupdates/LiveUpdatesSettingsBottomSheet.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index 24bce21ec0..12fe4f6f95 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -382,7 +382,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download } AndroidUiHelper.setVisibility(View.GONE, view.findViewById(R.id.compound_button)); ((ImageView) view.findViewById(R.id.icon)).setImageResource(R.drawable.ic_action_subscription_osmand_live); - TextViewEx tvTitle = view.findViewById(R.id.title); + TextView tvTitle = view.findViewById(R.id.title); tvTitle.setText(R.string.download_live_updates); AndroidUtils.setTextPrimaryColor(app, tvTitle, nightMode); countView = view.findViewById(R.id.description); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index f67128dbe0..83e66200ca 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -168,10 +168,12 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .create(); items.add(itemSwitchLiveUpdate); + Typeface typefaceRegular = FontCache.getRobotoRegular(app); TextViewEx frequencyTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); frequencyTitle.setHeight(dp48); frequencyTitle.setMinimumHeight(dp48); frequencyTitle.setText(R.string.update_frequency); + frequencyTitle.setTypeface(typefaceRegular); AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), 0, frequencyTitle.getPaddingRight(), 0); AndroidUtils.setTextPrimaryColor(app, frequencyTitle, nightMode); items.add(new BaseBottomSheetItem.Builder() @@ -203,6 +205,7 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen timeOfDayTitle.setHeight(dp40); timeOfDayTitle.setMinimumHeight(dp40); timeOfDayTitle.setText(R.string.update_time); + timeOfDayTitle.setTypeface(typefaceRegular); AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), 0, timeOfDayTitle.getPaddingRight(), 0); AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode); items.add(new BaseBottomSheetItem.Builder() From 50ac1174d0cd30a762743b7e845ea452a9911b4c Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 17:22:17 +0200 Subject: [PATCH 048/109] fix padding between title and description --- .../LiveUpdatesSettingsBottomSheet.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index 83e66200ca..21828d812a 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -77,6 +77,7 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen private OsmandApplication app; private OsmandSettings settings; + private BaseBottomSheetItem itemTitle; private BaseBottomSheetItem itemLastCheck; private BaseBottomSheetItem itemSwitchLiveUpdate; private BaseBottomSheetItem itemFrequencyHelpMessage; @@ -117,11 +118,12 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen int dp40 = getDimen(R.dimen.list_header_height); int dp48 = getDimen(R.dimen.context_menu_buttons_bottom_height); - items.add(new SimpleBottomSheetItem.Builder() + itemTitle = new SimpleBottomSheetItem.Builder() .setTitle(getNameToDisplay(fileName, app)) .setTitleColorId(getPrimaryTextColorId(nightMode)) .setLayoutId(R.layout.bottom_sheet_item_title_big) - .create()); + .create(); + items.add(itemTitle); itemLastCheck = new ShortDescriptionItem.Builder() .setDescription(getLastCheckString()) @@ -334,6 +336,19 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { View view = super.onCreateView(inflater, parent, savedInstanceState); + + int titleHeight = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_descr_height); + TextViewEx titleView = (TextViewEx) itemTitle.getView(); + titleView.setMinimumHeight(titleHeight); + titleView.getLayoutParams().height = titleHeight; + titleView.setPadding(titleView.getPaddingLeft(), getResources().getDimensionPixelSize(R.dimen.bottom_sheet_title_padding_top), + titleView.getPaddingRight(), titleView.getPaddingBottom()); + + int descriptionHeight = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_title_height); + TextViewEx descriptionView = (TextViewEx) itemLastCheck.getView(); + descriptionView.setMinimumHeight(descriptionHeight); + descriptionView.getLayoutParams().height = descriptionHeight; + CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); setStateViaWiFiButton(localUpdatePreference); return view; From d22edfd9ae044bb65e585c5c1749ee37c4f86745 Mon Sep 17 00:00:00 2001 From: cepprice Date: Fri, 26 Mar 2021 20:28:30 +0500 Subject: [PATCH 049/109] Split layout to cards --- OsmAnd/res/layout/contact_support.xml | 73 ++++ OsmAnd/res/layout/empty_purchases_layout.xml | 220 ---------- .../layout/new_device_or_account_button.xml | 34 ++ OsmAnd/res/layout/no_purchases_card.xml | 92 ++++ OsmAnd/res/layout/purchases_layout.xml | 407 +----------------- .../res/layout/restore_purchases_button.xml | 34 ++ OsmAnd/res/layout/subscriptions_card.xml | 204 ++++++++- OsmAnd/res/layout/subscriptions_list_card.xml | 6 + OsmAnd/res/layout/troubleshooting_card.xml | 96 +++++ .../plus/liveupdates/LiveUpdatesFragment.java | 64 ++- .../settings/fragments/PurchasesFragment.java | 245 ++--------- .../settings/fragments/SubscriptionsCard.java | 173 ++++---- .../fragments/SubscriptionsListCard.java | 124 ++++++ .../TroubleshootingOrPurchasingCard.java | 126 ++++++ 14 files changed, 975 insertions(+), 923 deletions(-) create mode 100644 OsmAnd/res/layout/contact_support.xml delete mode 100644 OsmAnd/res/layout/empty_purchases_layout.xml create mode 100644 OsmAnd/res/layout/new_device_or_account_button.xml create mode 100644 OsmAnd/res/layout/no_purchases_card.xml create mode 100644 OsmAnd/res/layout/restore_purchases_button.xml create mode 100644 OsmAnd/res/layout/subscriptions_list_card.xml create mode 100644 OsmAnd/res/layout/troubleshooting_card.xml create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java create mode 100644 OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java diff --git a/OsmAnd/res/layout/contact_support.xml b/OsmAnd/res/layout/contact_support.xml new file mode 100644 index 0000000000..30e45c4ea4 --- /dev/null +++ b/OsmAnd/res/layout/contact_support.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/empty_purchases_layout.xml b/OsmAnd/res/layout/empty_purchases_layout.xml deleted file mode 100644 index 56bfb82b6f..0000000000 --- a/OsmAnd/res/layout/empty_purchases_layout.xml +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OsmAnd/res/layout/new_device_or_account_button.xml b/OsmAnd/res/layout/new_device_or_account_button.xml new file mode 100644 index 0000000000..d6afc440ef --- /dev/null +++ b/OsmAnd/res/layout/new_device_or_account_button.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/no_purchases_card.xml b/OsmAnd/res/layout/no_purchases_card.xml new file mode 100644 index 0000000000..7bb787d4ab --- /dev/null +++ b/OsmAnd/res/layout/no_purchases_card.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/purchases_layout.xml b/OsmAnd/res/layout/purchases_layout.xml index d4bb5a3465..c4f361eca5 100644 --- a/OsmAnd/res/layout/purchases_layout.xml +++ b/OsmAnd/res/layout/purchases_layout.xml @@ -1,12 +1,10 @@ + android:background="?attr/activity_background_color" + android:orientation="vertical" + android:focusableInTouchMode="false"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:orientation="vertical"/> diff --git a/OsmAnd/res/layout/restore_purchases_button.xml b/OsmAnd/res/layout/restore_purchases_button.xml new file mode 100644 index 0000000000..a4a34bcd6c --- /dev/null +++ b/OsmAnd/res/layout/restore_purchases_button.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/subscriptions_card.xml b/OsmAnd/res/layout/subscriptions_card.xml index 278f381933..b4deb45ffc 100644 --- a/OsmAnd/res/layout/subscriptions_card.xml +++ b/OsmAnd/res/layout/subscriptions_card.xml @@ -1,5 +1,207 @@ \ No newline at end of file + android:background="?attr/bg_color" + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/subscriptions_list_card.xml b/OsmAnd/res/layout/subscriptions_list_card.xml new file mode 100644 index 0000000000..54c8480c4e --- /dev/null +++ b/OsmAnd/res/layout/subscriptions_list_card.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/OsmAnd/res/layout/troubleshooting_card.xml b/OsmAnd/res/layout/troubleshooting_card.xml new file mode 100644 index 0000000000..96e6b3627d --- /dev/null +++ b/OsmAnd/res/layout/troubleshooting_card.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 631b1a7f07..f6c3bd4b66 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -22,19 +22,7 @@ import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; -import androidx.annotation.DrawableRes; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - import net.osmand.plus.OsmandApplication; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.LocalIndexHelper; @@ -43,13 +31,15 @@ import net.osmand.plus.activities.OsmandBaseExpandableListAdapter; import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.resources.IncrementalChangesManager; -import net.osmand.plus.settings.fragments.PurchasesFragment; +import net.osmand.plus.settings.backend.CommonPreference; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; import java.io.File; @@ -60,6 +50,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.SwitchCompat; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import static net.osmand.plus.liveupdates.LiveUpdatesFragmentNew.showUpdateDialog; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.DEFAULT_LAST_CHECK; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; @@ -182,8 +181,8 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc statusTextView.setText(getString(R.string.osm_live_active)); statusIcon.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_done)); - String countryName = PurchasesFragment.getSupportRegionName(app, getInAppPurchaseHelper()); - String header = PurchasesFragment.getSupportRegionHeader(app, countryName); + String countryName = getSupportRegionName(app, getInAppPurchaseHelper()); + String header = getSupportRegionHeader(app, countryName); regionNameHeaderTextView.setText(header); regionNameTextView.setText(countryName); @@ -279,6 +278,41 @@ public class LiveUpdatesFragment extends BaseOsmAndFragment implements InAppPurc subscriptionFragment.show(getChildFragmentManager(), SubscriptionFragment.TAG); } + public static String getSupportRegionName(OsmandApplication app, InAppPurchaseHelper purchaseHelper) { + OsmandSettings settings = app.getSettings(); + String countryName = settings.BILLING_USER_COUNTRY.get(); + if (purchaseHelper != null) { + List subscriptions = purchaseHelper.getLiveUpdates().getVisibleSubscriptions(); + boolean donationSupported = false; + for (InAppSubscription s : subscriptions) { + if (s.isDonationSupported()) { + donationSupported = true; + break; + } + } + if (donationSupported) { + if (Algorithms.isEmpty(countryName)) { + if (OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER.equals(settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get())) { + countryName = app.getString(R.string.osmand_team); + } else { + countryName = app.getString(R.string.shared_string_world); + } + } + } else { + countryName = app.getString(R.string.osmand_team); + } + } else { + countryName = app.getString(R.string.osmand_team); + } + return countryName; + } + + public static String getSupportRegionHeader(OsmandApplication app, String supportRegion) { + return supportRegion.equals(app.getString(R.string.osmand_team)) ? + app.getString(R.string.default_buttons_support) : + app.getString(R.string.osm_live_support_region); + } + protected class LocalIndexesAdapter extends OsmandBaseExpandableListAdapter { public static final int SHOULD_UPDATE_GROUP_POSITION = 0; public static final int SHOULD_NOT_UPDATE_GROUP_POSITION = 1; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index 00a15b3071..d08cf6f892 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -2,23 +2,13 @@ package net.osmand.plus.settings.fragments; import android.app.Activity; import android.content.Context; -import android.content.Intent; -import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.Spanned; -import android.text.method.LinkMovementMethod; -import android.text.style.StyleSpan; -import android.text.style.URLSpan; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; import com.google.android.material.appbar.AppBarLayout; @@ -32,16 +22,10 @@ import net.osmand.plus.Version; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandInAppPurchaseActivity; import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.liveupdates.CountrySelectionFragment; -import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem; import net.osmand.plus.liveupdates.CountrySelectionFragment.OnFragmentInteractionListener; -import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; -import net.osmand.plus.liveupdates.OsmLiveActivity; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.util.Algorithms; @@ -59,11 +43,6 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public static final String KEY_IS_SUBSCRIBER = "action_is_new"; - private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; - private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; - private static final String EMAIL_DEEPLINK_URI = "mailto:support@osmand.net"; - private static final String OSMAND_EMAIL = "support@osmand.net"; - private static final String OSMAND_NEW_DEVICE_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; private static final String OSMAND_PURCHASES_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases"; private OsmandApplication app; @@ -71,18 +50,16 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha private InAppPurchaseHelper purchaseHelper; private View mainView; + ViewGroup cardsContainer; private SubscriptionsCard subscriptionsCard; - private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment(); - - private String url; private Boolean isPaidVersion; public static boolean showInstance(FragmentManager fragmentManager) { try { PurchasesFragment fragment = new PurchasesFragment(); fragmentManager.beginTransaction() - .replace(R.id.fragmentContainer, fragment, TAG) + .add(R.id.fragmentContainer, fragment, TAG) .addToBackStack(TAG) .commitAllowingStateLoss(); return true; @@ -102,67 +79,39 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha app = getMyApplication(); context = requireContext(); isPaidVersion = Version.isPaidVersion(app); - final MapActivity mapActivity = getMapActivity(); final boolean nightMode = !app.getSettings().isLightContent(); LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); - if (isPaidVersion) { - mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); - setSubscriptionClick(mapActivity); - } else { - mainView = themedInflater.inflate(R.layout.empty_purchases_layout, container, false); - LinearLayout osmandLive = mainView.findViewById(R.id.osmand_live); - osmandLive.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (getMyApplication() != null && getMyActivity() != null) { - ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), getMyActivity().getSupportFragmentManager(), ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); - } - } - }); - TextView infoDescription = mainView.findViewById(R.id.info_description); - - String restorePurchases = getString(R.string.restore_purchases); - String infoPurchases = String.format(getString(R.string.empty_purchases_description), restorePurchases); - infoDescription.setText(infoPurchases); - } + mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); AndroidUtils.addStatusBarPadding21v(getActivity(), mainView); createToolbar(mainView, nightMode); - LinearLayout purchasesRestore = mainView.findViewById(R.id.restore_purchases); - purchasesRestore.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (purchaseHelper != null) { - purchaseHelper.requestInventory(); - } - } - }); - LinearLayout newDeviceAccountContainer = mainView.findViewById(R.id.new_device_account_container); - newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - WikipediaDialogFragment.showFullArticle(context, Uri.parse(OSMAND_NEW_DEVICE_URL), nightMode); - } - }); + cardsContainer = mainView.findViewById(R.id.cards_container); - setFormatStrings(); return mainView; } @Override public void onResume() { super.onResume(); + updateCards(); + } + + private void updateCards() { + MapActivity mapActivity = getMapActivity(); purchaseHelper = getInAppPurchaseHelper(); - if (isPaidVersion) { - MapActivity mapActivity = getMapActivity(); - if (getMapActivity() != null && purchaseHelper != null) { - ViewGroup subscriptionsCardContainer = mainView.findViewById(R.id.subscriptions_card_container); - subscriptionsCardContainer.removeAllViews(); - subscriptionsCard = new SubscriptionsCard(mapActivity, purchaseHelper); - subscriptionsCardContainer.addView(subscriptionsCard.build(mapActivity)); - } - setupSupportRegion(); + cardsContainer.removeAllViews(); + if (mapActivity == null || purchaseHelper == null) { + return; } + + boolean hasSubscriptions = !Algorithms.isEmpty(purchaseHelper.getEverMadeSubscriptions()); + if (hasSubscriptions) { + subscriptionsCard = new SubscriptionsCard(mapActivity, this, purchaseHelper); + cardsContainer.addView(subscriptionsCard.build(mapActivity)); + } + + cardsContainer.addView(new TroubleshootingOrPurchasingCard(mapActivity, purchaseHelper, isPaidVersion) + .build(mapActivity)); } @Override @@ -175,95 +124,10 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public void onViewStateRestored(@Nullable Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); if (savedInstanceState != null) { - savedInstanceState.getBoolean(KEY_IS_SUBSCRIBER); + isPaidVersion = savedInstanceState.getBoolean(KEY_IS_SUBSCRIBER); } } - private void setSubscriptionClick(final MapActivity mapActivity) { - LinearLayout reportContainer = mainView.findViewById(R.id.report_container); - reportContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(mapActivity, OsmLiveActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - if (mapActivity != null) { - mapActivity.startActivity(intent); - } - } - }); - LinearLayout liveUpdatesContainer = mainView.findViewById(R.id.live_updates_container); - liveUpdatesContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FragmentActivity activity = getActivity(); - if (activity != null) { - LiveUpdatesFragmentNew.showInstance(activity.getSupportFragmentManager(), PurchasesFragment.this); - } - } - }); - getSkuAppId(); - LinearLayout manageSubscriptionContainer = mainView.findViewById(R.id.manage_subscription_container); - manageSubscriptionContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - if (AndroidUtils.isIntentSafe(context, intent)) { - startActivity(intent); - } - } - }); - - } - - private void setupSupportRegion() { - String region = getSupportRegionName(app, purchaseHelper); - String header = getSupportRegionHeader(app, region); - TextView supportRegionHeader = mainView.findViewById(R.id.support_region_header); - TextView supportRegion = mainView.findViewById(R.id.support_region); - supportRegionHeader.setText(header); - supportRegion.setText(region); - - View supportRegionContainer = mainView.findViewById(R.id.support_region_container); - supportRegionContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - CountrySelectionFragment countryCountrySelectionFragment = countrySelectionFragment; - countryCountrySelectionFragment.show(getChildFragmentManager(), CountrySelectionFragment.TAG); - } - }); - - countrySelectionFragment.initCountries(app); - } - - public static String getSupportRegionName(OsmandApplication app, InAppPurchaseHelper purchaseHelper) { - OsmandSettings settings = app.getSettings(); - String countryName = settings.BILLING_USER_COUNTRY.get(); - if (purchaseHelper != null) { - InAppSubscription monthlyPurchased = purchaseHelper.getPurchasedMonthlyLiveUpdates(); - if (monthlyPurchased != null && monthlyPurchased.isDonationSupported()) { - if (Algorithms.isEmpty(countryName)) { - if (OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER.equals(settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get())) { - countryName = app.getString(R.string.osmand_team); - } else { - countryName = app.getString(R.string.shared_string_world); - } - } - } else { - countryName = app.getString(R.string.osmand_team); - } - } else { - countryName = app.getString(R.string.osmand_team); - } - return countryName; - } - - public static String getSupportRegionHeader(OsmandApplication app, String supportRegion) { - return supportRegion.equals(app.getString(R.string.osmand_team)) ? - app.getString(R.string.default_buttons_support) : - app.getString(R.string.osm_live_support_region); - } - @Nullable public InAppPurchaseHelper getInAppPurchaseHelper() { Activity activity = getActivity(); @@ -303,69 +167,21 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha appbar.addView(toolbar); } - public void setFormatStrings() { - TextView contactSupportLink = mainView.findViewById(R.id.contact_support_title); - TextView supportDescription = mainView.findViewById(R.id.support_link_title); - - SpannableString spannableStringSupport = new SpannableString(getString(R.string.contact_support)); - spannableStringSupport.setSpan(new URLSpan(EMAIL_DEEPLINK_URI), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - String supportDescriptionString = getString(R.string.contact_support_description, OSMAND_EMAIL); - SpannableString spannableStringMail = new SpannableString(supportDescriptionString); - int startIndex = supportDescriptionString.indexOf(OSMAND_EMAIL); - int endIndex = startIndex + OSMAND_EMAIL.length(); - StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); - spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - - contactSupportLink.setText(spannableStringSupport); - supportDescription.setText(spannableStringMail); - - AndroidUtils.removeLinkUnderline(contactSupportLink); - - contactSupportLink.setMovementMethod(LinkMovementMethod.getInstance()); - } - - private void getSkuAppId() { - InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); - if (purchaseHelper != null && purchaseHelper.getFullVersion() != null) { - String sku = purchaseHelper.getFullVersion().getSku(); - url = String.format(PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL, - sku, context.getPackageName()); - } else { - url = PLAY_STORE_SUBSCRIPTION_URL; - } - } - - @Override - public void onSearchResult(CountryItem selectedCountryItem) { - String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : ""; - String countryDownloadName = selectedCountryItem != null ? - selectedCountryItem.getDownloadName() : OsmandSettings.BILLING_USER_DONATION_WORLD_PARAMETER; - - OsmandApplication app = getMyApplication(); - if (app != null) { - TextView supportRegionHeader = mainView.findViewById(R.id.support_region_header); - TextView supportRegion = mainView.findViewById(R.id.support_region); - supportRegionHeader.setText(getSupportRegionHeader(app, countryName)); - supportRegion.setText(countryName); - app.getSettings().BILLING_USER_COUNTRY.set(countryName); - app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName); - } - } - @Override public void onError(InAppPurchaseHelper.InAppPurchaseTaskType taskType, String error) { } @Override public void onGetItems() { - if (subscriptionsCard != null) { - subscriptionsCard.update(); + if (app != null) { + isPaidVersion = Version.isPaidVersion(app); } + updateCards(); } @Override public void onItemPurchased(String sku, boolean active) { + isPaidVersion = true; if (purchaseHelper != null) { purchaseHelper.requestInventory(); } @@ -379,7 +195,14 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha public void dismissProgress(InAppPurchaseHelper.InAppPurchaseTaskType taskType) { } + @Override + public void onSearchResult(CountrySelectionFragment.CountryItem name) { + if (subscriptionsCard != null) { + subscriptionsCard.onSupportRegionSelected(name); + } + } + private MapActivity getMapActivity() { return (MapActivity) getActivity(); } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index 1cc422b3ff..100bab00df 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -1,121 +1,146 @@ package net.osmand.plus.settings.fragments; -import android.os.Build; -import android.view.LayoutInflater; +import android.content.Intent; +import android.net.Uri; import android.view.View; import android.view.ViewGroup; +import android.widget.LinearLayout; import android.widget.TextView; import net.osmand.AndroidUtils; -import net.osmand.Period; import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; -import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; -import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState; +import net.osmand.plus.liveupdates.CountrySelectionFragment; +import net.osmand.plus.liveupdates.LiveUpdatesFragment; +import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; +import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.util.Algorithms; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; public class SubscriptionsCard extends BaseCard { - private final InAppPurchaseHelper purchaseHelper; + private static final String PLAY_STORE_SUBSCRIPTION_URL = "https://play.google.com/store/account/subscriptions"; + private static final String PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL = "https://play.google.com/store/account/subscriptions?sku=%s&package=%s"; - private final SimpleDateFormat dateFormat; + private Fragment target; + private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment(); + private SubscriptionsListCard subscriptionsListCard; + + private InAppPurchaseHelper purchaseHelper; @Override public int getCardLayoutId() { return R.layout.subscriptions_card; } - public SubscriptionsCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper) { + public SubscriptionsCard(@NonNull MapActivity mapActivity, @NonNull Fragment target, @NonNull InAppPurchaseHelper purchaseHelper) { super(mapActivity); + this.target = target; this.purchaseHelper = purchaseHelper; - this.dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.getDefault()); } @Override protected void updateContent() { if (purchaseHelper == null || Algorithms.isEmpty(purchaseHelper.getEverMadeSubscriptions())) { + AndroidUiHelper.updateVisibility(view, false); return; + } else { + AndroidUiHelper.updateVisibility(view, true); } - LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode); - ((ViewGroup) view).removeAllViews(); + updateSubscriptionsListCard(); + setupSupportRegion(); - List subscriptions = purchaseHelper.getEverMadeSubscriptions(); - for (int i = 0; i < subscriptions.size(); i++) { - InAppSubscription subscription = subscriptions.get(i); - SubscriptionState state = subscription.getState(); - boolean autoRenewed = state == SubscriptionState.ACTIVE || state == SubscriptionState.IN_GRACE_PERIOD; - - View card = inflater.inflate(R.layout.subscription_layout, null, false); - ((ViewGroup) view).addView(card); - - TextView subscriptionPeriod = card.findViewById(R.id.subscription_type); - String period = app.getString(subscription.getPeriodTypeString()); - if (!Algorithms.isEmpty(period)) { - subscriptionPeriod.setText(period); - AndroidUiHelper.updateVisibility(subscriptionPeriod, true); + LinearLayout reportContainer = view.findViewById(R.id.report_container); + reportContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(mapActivity, OsmLiveActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + mapActivity.startActivity(intent); } + }); - if (autoRenewed) { - TextView nextBillingDate = card.findViewById(R.id.next_billing_date); - String date = getHumanDate(subscription.getPurchaseTime(), subscription.getSubscriptionPeriod()); - if (!Algorithms.isEmpty(date)) { - nextBillingDate.setText(app.getString(R.string.next_billing_date, date)); - AndroidUiHelper.updateVisibility(nextBillingDate, true); - } - } else { - View renewContainer = card.findViewById(R.id.renewContainer); - AndroidUiHelper.updateVisibility(renewContainer, true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); - } else { - AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); - } - final String sku = subscription.getSku(); - renewContainer.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ChoosePlanDialogFragment.subscribe(app, mapActivity, purchaseHelper, sku); - } - }); - - View renew = card.findViewById(R.id.renew); - AndroidUtils.setBackground(mapActivity, renew, nightMode, - R.drawable.btn_solid_border_light, R.drawable.btn_solid_border_dark); + LinearLayout liveUpdatesContainer = view.findViewById(R.id.live_updates_container); + liveUpdatesContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + LiveUpdatesFragmentNew.showInstance(mapActivity.getSupportFragmentManager(), target); } + }); - TextView status = card.findViewById(R.id.status); - status.setText(app.getString(state.getStringRes())); - AndroidUtils.setBackground(status, app.getUIUtilities().getIcon(state.getBackgroundRes())); + final String subscriptionUrl = getSubscriptionUrl(); + LinearLayout manageSubscriptionContainer = view.findViewById(R.id.manage_subscription_container); + manageSubscriptionContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(subscriptionUrl)); + if (AndroidUtils.isIntentSafe(mapActivity, intent)) { + target.startActivity(intent); + } + } + }); + } - int dividerLayout = i + 1 == subscriptions.size() ? R.layout.simple_divider_item : R.layout.divider_half_item; - View divider = inflater.inflate(dividerLayout, (ViewGroup) view, false); - ((ViewGroup) view).addView(divider); + public void updateSubscriptionsListCard() { + if (subscriptionsListCard == null) { + ViewGroup subscriptionsListContainer = view.findViewById(R.id.subscriptions_list_container); + subscriptionsListContainer.removeAllViews(); + subscriptionsListCard = new SubscriptionsListCard(mapActivity, purchaseHelper); + subscriptionsListContainer.addView(subscriptionsListCard.build(mapActivity)); + } else { + subscriptionsListCard.update(); } } - private String getHumanDate(long time, Period period) { - if (period == null || period.getUnit() == null) { - return ""; + private void setupSupportRegion() { + String region = LiveUpdatesFragment.getSupportRegionName(app, purchaseHelper); + String header = LiveUpdatesFragment.getSupportRegionHeader(app, region); + TextView supportRegionHeader = view.findViewById(R.id.support_region_header); + TextView supportRegion = view.findViewById(R.id.support_region); + supportRegionHeader.setText(header); + supportRegion.setText(region); + + View supportRegionContainer = view.findViewById(R.id.support_region_container); + supportRegionContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CountrySelectionFragment countryCountrySelectionFragment = countrySelectionFragment; + countryCountrySelectionFragment.show(target.getChildFragmentManager(), CountrySelectionFragment.TAG); + } + }); + + countrySelectionFragment.initCountries(app); + } + + private String getSubscriptionUrl() { + InAppPurchaseHelper purchaseHelper = app.getInAppPurchaseHelper(); + if (purchaseHelper != null && purchaseHelper.getFullVersion() != null) { + String sku = purchaseHelper.getFullVersion().getSku(); + return String.format(PLAY_STORE_SUBSCRIPTION_DEEPLINK_URL, + sku, mapActivity.getPackageName()); + } else { + return PLAY_STORE_SUBSCRIPTION_URL; } - Date date = new Date(time); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(date); - calendar.add(period.getUnit().getCalendarIdx(), period.getNumberOfUnits()); - date = calendar.getTime(); - return dateFormat.format(date); + } + + public void onSupportRegionSelected(CountrySelectionFragment.CountryItem selectedCountryItem) { + String countryName = selectedCountryItem != null ? selectedCountryItem.getLocalName() : ""; + String countryDownloadName = selectedCountryItem != null ? + selectedCountryItem.getDownloadName() : OsmandSettings.BILLING_USER_DONATION_WORLD_PARAMETER; + + TextView supportRegionHeader = view.findViewById(R.id.support_region_header); + TextView supportRegion = view.findViewById(R.id.support_region); + supportRegionHeader.setText(LiveUpdatesFragment.getSupportRegionHeader(app, countryName)); + supportRegion.setText(countryName); + app.getSettings().BILLING_USER_COUNTRY.set(countryName); + app.getSettings().BILLING_USER_COUNTRY_DOWNLOAD_NAME.set(countryDownloadName); } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java new file mode 100644 index 0000000000..9d8d4f9568 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java @@ -0,0 +1,124 @@ +package net.osmand.plus.settings.fragments; + +import android.os.Build; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import net.osmand.AndroidUtils; +import net.osmand.Period; +import net.osmand.plus.R; +import net.osmand.plus.UiUtilities; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.util.Algorithms; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import androidx.annotation.NonNull; + +public class SubscriptionsListCard extends BaseCard { + + private final InAppPurchaseHelper purchaseHelper; + + private final SimpleDateFormat dateFormat; + + @Override + public int getCardLayoutId() { + return R.layout.subscriptions_list_card; + } + + public SubscriptionsListCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper) { + super(mapActivity); + this.purchaseHelper = purchaseHelper; + this.dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.getDefault()); + } + + @Override + protected void updateContent() { + if (purchaseHelper == null || Algorithms.isEmpty(purchaseHelper.getEverMadeSubscriptions())) { + AndroidUiHelper.updateVisibility(view, false); + return; + } else { + AndroidUiHelper.updateVisibility(view, true); + } + + LayoutInflater inflater = UiUtilities.getInflater(mapActivity, nightMode); + ((ViewGroup) view).removeAllViews(); + + List subscriptions = purchaseHelper.getEverMadeSubscriptions(); + for (int i = 0; i < subscriptions.size(); i++) { + InAppSubscription subscription = subscriptions.get(i); + SubscriptionState state = subscription.getState(); + boolean autoRenewed = state == SubscriptionState.ACTIVE || state == SubscriptionState.IN_GRACE_PERIOD; + + View card = inflater.inflate(R.layout.subscription_layout, null, false); + ((ViewGroup) view).addView(card); + + TextView subscriptionPeriod = card.findViewById(R.id.subscription_type); + String period = app.getString(subscription.getPeriodTypeString()); + if (!Algorithms.isEmpty(period)) { + subscriptionPeriod.setText(period); + AndroidUiHelper.updateVisibility(subscriptionPeriod, true); + } + + if (autoRenewed) { + TextView nextBillingDate = card.findViewById(R.id.next_billing_date); + String date = getHumanDate(subscription.getPurchaseTime(), subscription.getSubscriptionPeriod()); + if (!Algorithms.isEmpty(date)) { + nextBillingDate.setText(app.getString(R.string.next_billing_date, date)); + AndroidUiHelper.updateVisibility(nextBillingDate, true); + } + } else { + View renewContainer = card.findViewById(R.id.renewContainer); + AndroidUiHelper.updateVisibility(renewContainer, true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); + } else { + AndroidUtils.setBackground(mapActivity, renewContainer, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); + } + final String sku = subscription.getSku(); + renewContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ChoosePlanDialogFragment.subscribe(app, mapActivity, purchaseHelper, sku); + } + }); + + View renew = card.findViewById(R.id.renew); + AndroidUtils.setBackground(mapActivity, renew, nightMode, + R.drawable.btn_solid_border_light, R.drawable.btn_solid_border_dark); + } + + TextView status = card.findViewById(R.id.status); + status.setText(app.getString(state.getStringRes())); + AndroidUtils.setBackground(status, app.getUIUtilities().getIcon(state.getBackgroundRes())); + + int dividerLayout = i + 1 == subscriptions.size() ? R.layout.simple_divider_item : R.layout.divider_half_item; + View divider = inflater.inflate(dividerLayout, (ViewGroup) view, false); + ((ViewGroup) view).addView(divider); + } + } + + private String getHumanDate(long time, Period period) { + if (period == null || period.getUnit() == null) { + return ""; + } + Date date = new Date(time); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(period.getUnit().getCalendarIdx(), period.getNumberOfUnits()); + date = calendar.getTime(); + return dateFormat.format(date); + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java new file mode 100644 index 0000000000..c53950ee2b --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java @@ -0,0 +1,126 @@ +package net.osmand.plus.settings.fragments; + +import android.graphics.Typeface; +import android.net.Uri; +import android.os.Build; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.method.LinkMovementMethod; +import android.text.style.StyleSpan; +import android.text.style.URLSpan; +import android.view.View; +import android.widget.TextView; + +import net.osmand.AndroidUtils; +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; +import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.routepreparationmenu.cards.BaseCard; +import net.osmand.plus.wikipedia.WikipediaDialogFragment; + +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.core.content.ContextCompat; + +public class TroubleshootingOrPurchasingCard extends BaseCard { + + private static final String OSMAND_NEW_DEVICE_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases#new-device--new-account"; + private static final String OSMAND_EMAIL = "support@osmand.net"; + private static final String EMAIL_DEEPLINK_URI = "mailto:support@osmand.net"; + + protected InAppPurchaseHelper purchaseHelper; + + private final boolean isPaidVersion; + + @Override + public int getCardLayoutId() { + return isPaidVersion ? R.layout.troubleshooting_card : R.layout.no_purchases_card; + } + + public TroubleshootingOrPurchasingCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper, boolean isPaidVersion) { + super(mapActivity); + this.purchaseHelper = purchaseHelper; + this.isPaidVersion = isPaidVersion; + } + + @Override + protected void updateContent() { + setupRestorePurchasesBtn(R.id.restore_purchases); + setupNewDeviceOrAccountBtn(R.id.new_device_account_container); + setupSupportDescription(); + setupContactUsLink(); + + if (!isPaidVersion) { + TextView infoDescription = view.findViewById(R.id.info_description); + String restorePurchases = app.getString(R.string.restore_purchases); + String infoPurchases = String.format(app.getString(R.string.empty_purchases_description), restorePurchases); + infoDescription.setText(infoPurchases); + + View osmandLive = view.findViewById(R.id.osmand_live); + osmandLive.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ChoosePlanDialogFragment.showDialogInstance(getMyApplication(), + mapActivity.getSupportFragmentManager(), + ChoosePlanDialogFragment.ChoosePlanDialogType.OSM_LIVE); + } + }); + + CardView getItButtonContainer = view.findViewById(R.id.card_view); + int colorRes = nightMode ? R.color.switch_button_active_dark : R.color.switch_button_active_light; + getItButtonContainer.setCardBackgroundColor(ContextCompat.getColor(mapActivity, colorRes)); + + View getItButton = view.findViewById(R.id.card_container); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + AndroidUtils.setBackground(mapActivity, getItButton, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark); + } else { + AndroidUtils.setBackground(mapActivity, getItButton, nightMode, R.drawable.btn_unstroked_light, R.drawable.btn_unstroked_dark); + } + } + } + + protected void setupRestorePurchasesBtn(@IdRes int btnId) { + View purchasesRestore = view.findViewById(btnId); + purchasesRestore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (purchaseHelper != null) { + purchaseHelper.requestInventory(); + } + } + }); + } + + protected void setupNewDeviceOrAccountBtn(@IdRes int btnId) { + View newDeviceAccountContainer = view.findViewById(btnId); + newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + WikipediaDialogFragment.showFullArticle(mapActivity, Uri.parse(OSMAND_NEW_DEVICE_URL), nightMode); + } + }); + } + + protected void setupSupportDescription() { + TextView supportDescription = view.findViewById(R.id.support_link_title); + String supportDescriptionString = app.getString(R.string.contact_support_description, OSMAND_EMAIL); + SpannableString spannableStringMail = new SpannableString(supportDescriptionString); + int startIndex = supportDescriptionString.indexOf(OSMAND_EMAIL); + int endIndex = startIndex + OSMAND_EMAIL.length(); + StyleSpan boldSpan = new StyleSpan(Typeface.BOLD); + spannableStringMail.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + supportDescription.setText(spannableStringMail); + } + + protected void setupContactUsLink() { + TextView contactSupportLink = view.findViewById(R.id.contact_support_title); + SpannableString spannableStringSupport = new SpannableString(app.getString(R.string.contact_support)); + spannableStringSupport.setSpan(new URLSpan(EMAIL_DEEPLINK_URI), 0, spannableStringSupport.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + contactSupportLink.setText(spannableStringSupport); + AndroidUtils.removeLinkUnderline(contactSupportLink); + contactSupportLink.setMovementMethod(LinkMovementMethod.getInstance()); + } +} \ No newline at end of file From c5540162f432c72fd79ee37e9786db60d07012aa Mon Sep 17 00:00:00 2001 From: Skalii Date: Fri, 26 Mar 2021 18:04:01 +0200 Subject: [PATCH 050/109] fix swap "Update frequency" and "Update time" --- .../LiveUpdatesSettingsBottomSheet.java | 99 ++++++++++--------- 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index 21828d812a..e91d5d9f3c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -113,9 +113,10 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen CommonPreference downloadViaWiFiPreference = preferenceDownloadViaWiFi(fileName, settings); CommonPreference frequencyPreference = preferenceUpdateFrequency(fileName, settings); CommonPreference timeOfDayPreference = preferenceTimeOfDayToUpdate(fileName, settings); + int dp4 = getDimen(R.dimen.list_item_button_padding); int dp12 = getDimen(R.dimen.content_padding_small); int dp16 = getDimen(R.dimen.content_padding); - int dp40 = getDimen(R.dimen.list_header_height); + int dp36 = getDimen(R.dimen.dialog_button_height); int dp48 = getDimen(R.dimen.context_menu_buttons_bottom_height); itemTitle = new SimpleBottomSheetItem.Builder() @@ -171,12 +172,47 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen items.add(itemSwitchLiveUpdate); Typeface typefaceRegular = FontCache.getRobotoRegular(app); + TextViewEx timeOfDayTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); + timeOfDayTitle.setHeight(dp48); + timeOfDayTitle.setMinimumHeight(dp48); + timeOfDayTitle.setText(R.string.update_time); + timeOfDayTitle.setTypeface(typefaceRegular); + AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), dp4, timeOfDayTitle.getPaddingRight(), dp4); + AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode); + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(timeOfDayTitle) + .create()); + + LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); + LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams( + LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); + AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, 0); + itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams); + + String morning = getString(R.string.morning); + String night = getString(R.string.night); + RadioItem morningButton = new RadioItem(morning); + RadioItem nightButton = new RadioItem(night); + timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode); + timeOfDayToggleButton.setItems(morningButton, nightButton); + setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton); + timeOfDayToggleButton.updateView(localUpdatePreference.get()); + refreshTimeOfDayLayout(frequencyPreference.get(), itemTimeOfDayButtons, timeOfDayTitle); + + morningButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.MORNING)); + nightButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.NIGHT)); + + items.add(new BaseBottomSheetItem.Builder() + .setCustomView(itemTimeOfDayButtons) + .create() + ); + TextViewEx frequencyTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); frequencyTitle.setHeight(dp48); frequencyTitle.setMinimumHeight(dp48); frequencyTitle.setText(R.string.update_frequency); frequencyTitle.setTypeface(typefaceRegular); - AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), 0, frequencyTitle.getPaddingRight(), 0); + AndroidUtils.setPadding(frequencyTitle, frequencyTitle.getPaddingLeft(), dp4, frequencyTitle.getPaddingRight(), dp4); AndroidUtils.setTextPrimaryColor(app, frequencyTitle, nightMode); items.add(new BaseBottomSheetItem.Builder() .setCustomView(frequencyTitle) @@ -203,43 +239,9 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen .setCustomView(itemFrequencyButtons) .create()); - TextViewEx timeOfDayTitle = (TextViewEx) inflater.inflate(R.layout.bottom_sheet_item_title, null); - timeOfDayTitle.setHeight(dp40); - timeOfDayTitle.setMinimumHeight(dp40); - timeOfDayTitle.setText(R.string.update_time); - timeOfDayTitle.setTypeface(typefaceRegular); - AndroidUtils.setPadding(timeOfDayTitle, timeOfDayTitle.getPaddingLeft(), 0, timeOfDayTitle.getPaddingRight(), 0); - AndroidUtils.setTextPrimaryColor(app, timeOfDayTitle, nightMode); - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(timeOfDayTitle) - .create()); - - LinearLayout itemTimeOfDayButtons = (LinearLayout) inflater.inflate(R.layout.custom_radio_buttons, null); - LinearLayout.MarginLayoutParams itemTimeOfDayParams = new LinearLayout.MarginLayoutParams( - LinearLayout.MarginLayoutParams.MATCH_PARENT, LinearLayout.MarginLayoutParams.WRAP_CONTENT); - AndroidUtils.setMargins(itemTimeOfDayParams, dp16, 0, dp16, getDimen(R.dimen.context_menu_padding_margin_medium)); - itemTimeOfDayButtons.setLayoutParams(itemTimeOfDayParams); - - String morning = getString(R.string.morning); - String night = getString(R.string.night); - RadioItem morningButton = new RadioItem(morning); - RadioItem nightButton = new RadioItem(night); - timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode); - timeOfDayToggleButton.setItems(morningButton, nightButton); - setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton); - timeOfDayToggleButton.updateView(localUpdatePreference.get()); - refreshTimeOfDayLayout(frequencyPreference.get(), itemTimeOfDayButtons, timeOfDayTitle); - hourlyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.HOURLY, itemTimeOfDayButtons, timeOfDayTitle)); dailyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.DAILY, itemTimeOfDayButtons, timeOfDayTitle)); weeklyButton.setOnClickListener(getFrequencyButtonListener(UpdateFrequency.WEEKLY, itemTimeOfDayButtons, timeOfDayTitle)); - morningButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.MORNING)); - nightButton.setOnClickListener(getTimeOfDayButtonListener(TimeOfDay.NIGHT)); - - items.add(new BaseBottomSheetItem.Builder() - .setCustomView(itemTimeOfDayButtons) - .create() - ); itemFrequencyHelpMessage = new ShortDescriptionItem.Builder() .setDescription(getFrequencyHelpMessage()) @@ -251,13 +253,13 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen LinearLayout itemUpdateNowButton = (LinearLayout) inflater.inflate(R.layout.bottom_sheet_button_with_icon_center, null); LinearLayout.MarginLayoutParams itemUpdateNowParams = new LinearLayout.MarginLayoutParams( - LinearLayout.MarginLayoutParams.MATCH_PARENT, getDimen(R.dimen.measurement_tool_button_height)); - AndroidUtils.setMargins(itemUpdateNowParams, dp12, dp12, dp16, dp12); + LinearLayout.MarginLayoutParams.MATCH_PARENT, dp36); + AndroidUtils.setMargins(itemUpdateNowParams, dp12, 0, dp16, dp12); itemUpdateNowButton.setLayoutParams(itemUpdateNowParams); ((AppCompatImageView) itemUpdateNowButton.findViewById(R.id.button_icon)).setImageDrawable( AppCompatResources.getDrawable(app, R.drawable.ic_action_update)); UiUtilities.setupDialogButton(nightMode, itemUpdateNowButton, UiUtilities.DialogButtonType.SECONDARY, getString(R.string.update_now)); - itemUpdateNowButton.setMinimumHeight(AndroidUtils.dpToPx(app, app.getResources().getDimension(R.dimen.dialog_button_height))); + itemUpdateNowButton.setMinimumHeight(AndroidUtils.dpToPx(app, dp36)); items.add(new BaseBottomSheetItem.Builder() .setCustomView(itemUpdateNowButton) @@ -337,18 +339,23 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { View view = super.onCreateView(inflater, parent, savedInstanceState); - int titleHeight = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_descr_height); + int titleHeight = getDimen(R.dimen.bottom_sheet_descr_height); TextViewEx titleView = (TextViewEx) itemTitle.getView(); titleView.setMinimumHeight(titleHeight); titleView.getLayoutParams().height = titleHeight; - titleView.setPadding(titleView.getPaddingLeft(), getResources().getDimensionPixelSize(R.dimen.bottom_sheet_title_padding_top), - titleView.getPaddingRight(), titleView.getPaddingBottom()); + titleView.setPadding(titleView.getPaddingLeft(), getDimen(R.dimen.content_padding_small), + titleView.getPaddingRight(), getDimen(R.dimen.list_item_button_padding)); - int descriptionHeight = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_title_height); - TextViewEx descriptionView = (TextViewEx) itemLastCheck.getView(); + int descriptionHeight = getDimen(R.dimen.bottom_sheet_title_height); + TextView descriptionView = (TextView) itemLastCheck.getView(); descriptionView.setMinimumHeight(descriptionHeight); descriptionView.getLayoutParams().height = descriptionHeight; + int frequencyHelpMessageHeight = getDimen(R.dimen.context_menu_progress_min_height); + TextView frequencyHelpMessageView = (TextView) itemFrequencyHelpMessage.getView(); + frequencyHelpMessageView.setMinimumHeight(frequencyHelpMessageHeight); + frequencyHelpMessageView.getLayoutParams().height = frequencyHelpMessageHeight; + CommonPreference localUpdatePreference = preferenceForLocalIndex(fileName, settings); setStateViaWiFiButton(localUpdatePreference); return view; @@ -446,8 +453,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen private BaseBottomSheetItem createDividerItem() { DividerItem dividerItem = new DividerItem(app); - int start = app.getResources().getDimensionPixelSize(R.dimen.content_padding); - int vertical = getResources().getDimensionPixelSize(R.dimen.content_padding_small_half); + int start = getDimen(R.dimen.content_padding); + int vertical = getDimen(R.dimen.content_padding_small_half); dividerItem.setMargins(start, vertical, 0, vertical); return dividerItem; } From 3e8dac9cafa131f63c1c0094f28510ef791b3466 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Fri, 26 Mar 2021 23:09:00 +0200 Subject: [PATCH 051/109] Setting format --- .../src/net/osmand/plus/OsmAndFormatter.java | 22 ++++++++----------- .../fragments/CoordinatesFormatFragment.java | 2 +- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java index 10838339d0..383128095b 100644 --- a/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java +++ b/OsmAnd/src/net/osmand/plus/OsmAndFormatter.java @@ -5,6 +5,7 @@ import android.text.format.DateUtils; import androidx.core.text.TextUtilsCompat; import androidx.core.view.ViewCompat; + import com.jwetherell.openmap.common.LatLonPoint; import com.jwetherell.openmap.common.MGRSPoint; import com.jwetherell.openmap.common.UTMPoint; @@ -509,19 +510,14 @@ public class OsmAndFormatter { result.append(formatCoordinate(lat, outputFormat)).append(" ").append(formatCoordinate(lon, outputFormat)); } else if (outputFormat == FORMAT_DEGREES || outputFormat == FORMAT_MINUTES || outputFormat == FORMAT_SECONDS) { boolean isLeftToRight = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_LTR; - if (isLeftToRight) { - result - .append(formatCoordinate(lat, outputFormat)).append(" ") - .append(lat > 0 ? NORTH : SOUTH).append(", ") - .append(formatCoordinate(lon, outputFormat)).append(" ") - .append(lon > 0 ? EAST : WEST); - } else { - result - .append(formatCoordinate(lat, outputFormat)).append(" ") - .append(lon > 0 ? EAST : WEST).append(" ") - .append(formatCoordinate(lon, outputFormat)).append(", ") - .append(lat > 0 ? NORTH : SOUTH); - } + String rtlCoordinates = isLeftToRight ? "" : "\u200f"; + String rtlCoordinatesPunctuation = isLeftToRight ? ", " : " ,"; + result + .append(rtlCoordinates) + .append(formatCoordinate(lat, outputFormat)).append(rtlCoordinates).append(" ").append(rtlCoordinates) + .append(lat > 0 ? NORTH : SOUTH).append(rtlCoordinates).append(rtlCoordinatesPunctuation).append(rtlCoordinates) + .append(formatCoordinate(lon, outputFormat)).append(rtlCoordinates).append(" ").append(rtlCoordinates) + .append(lon > 0 ? EAST : WEST); } else if (outputFormat == UTM_FORMAT) { UTMPoint pnt = new UTMPoint(new LatLonPoint(lat, lon)); result diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/CoordinatesFormatFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/CoordinatesFormatFragment.java index fd62f6df3c..2af8ac55b8 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/CoordinatesFormatFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/CoordinatesFormatFragment.java @@ -146,7 +146,7 @@ public class CoordinatesFormatFragment extends BaseSettingsFragment { return spannableBuilder; } - return getString(R.string.ltr_or_rtl_combine_via_colon, getString(R.string.shared_string_example), formattedCoordinates); + return formattedCoordinates; } @Override From 7048f8c52d51c47ad432413d0cfe78e6f51a6c5e Mon Sep 17 00:00:00 2001 From: Skalii Date: Sat, 27 Mar 2021 22:51:59 +0200 Subject: [PATCH 052/109] fix dynamic updating graphs; some fixes; --- .../monitoring/TripRecordingBottomSheet.java | 55 +++--- .../plus/myplaces/GPXItemPagerAdapter.java | 173 +++++++++++------- .../plus/track/GpxBlockStatisticsBuilder.java | 5 + 3 files changed, 139 insertions(+), 94 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index 21994e3cb7..aa2a5b6cb6 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -48,7 +48,6 @@ import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.helpers.AndroidUiHelper; -import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.mapcontextmenu.other.TrackChartPoints; import net.osmand.plus.myplaces.GPXItemPagerAdapter; import net.osmand.plus.myplaces.GPXTabItemType; @@ -94,7 +93,6 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl private View statusContainer; private AppCompatImageView trackAppearanceIcon; - private TrackDisplayHelper displayHelper; private TrackChartPoints trackChartPoints; private GPXItemPagerAdapter graphsAdapter; private int graphTabPosition = 0; @@ -157,7 +155,6 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } }); - setupDisplayHelper(); segmentsTabs = itemView.findViewById(R.id.segments_container); createSegmentsTabs(segmentsTabs); @@ -186,8 +183,10 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl boolean wasTrackMonitored = !wasTrackMonitored(); if (!wasTrackMonitored) { blockStatisticsBuilder.stopUpdatingStatBlocks(); + stopUpdatingGraph(); } else { blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded(); + runUpdatingGraph(); } settings.SAVE_GLOBAL_TRACK_TO_GPX.set(wasTrackMonitored); updateStatus(); @@ -256,10 +255,8 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl updateTrackIcon(app, trackAppearanceIcon); } if (key.equals(UPDATE_DYNAMIC_ITEMS)) { - blockStatisticsBuilder.stopUpdatingStatBlocks(); - blockStatisticsBuilder.runUpdatingStatBlocksIfNeeded(); - stopUpdatingGraph(); - runUpdatingGraph(); + blockStatisticsBuilder.restartUpdatingStatBlocks(); + restartUpdatingGraph(); } } } @@ -271,11 +268,11 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } } - public void stopUpdatingGPS() { + private void stopUpdatingGPS() { handler.removeCallbacks(updatingGPS); } - public void runUpdatingGPS() { + private void runUpdatingGPS() { updatingGPS = new Runnable() { @Override public void run() { @@ -287,38 +284,30 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl handler.post(updatingGPS); } - public void stopUpdatingGraph() { + private void stopUpdatingGraph() { handler.removeCallbacks(updatingGraph); } - public void runUpdatingGraph() { + private void runUpdatingGraph() { updatingGraph = new Runnable() { @Override public void run() { int interval = app.getSettings().SAVE_GLOBAL_TRACK_INTERVAL.get(); - graphsAdapter.setGpxItem(GpxUiHelper.makeGpxDisplayItem(app, displayHelper.getGpx())); - graphsAdapter.fetchTabTypesIfNeeded(INIT_TAB_ITEMS); graphsAdapter.updateGraph(graphTabPosition); - AndroidUiHelper.updateVisibility(segmentsTabs, graphsAdapter.isVisible()); + AndroidUiHelper.updateVisibility(segmentsTabs, graphsAdapter.isTabsVisible()); handler.postDelayed(this, Math.max(GPS_UPDATE_INTERVAL, interval)); } }; handler.post(updatingGraph); } - private void setupDisplayHelper() { - displayHelper = new TrackDisplayHelper(app); - GPXFile gpxFile = getGPXFile(); - if (!selectedGpxFile.isShowCurrentTrack()) { - File file = new File(gpxFile.path); - displayHelper.setFile(file); - displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); - } - displayHelper.setGpx(gpxFile); + private void restartUpdatingGraph() { + stopUpdatingGraph(); + runUpdatingGraph(); } private void createSegmentsTabs(ViewGroup viewGroup) { - View segmentView = SegmentGPXAdapter.createGpxTabsView(displayHelper, viewGroup, this, nightMode); + View segmentView = SegmentGPXAdapter.createGpxTabsView(null, viewGroup, this, nightMode); AndroidUiHelper.setVisibility(View.GONE, segmentView.findViewById(R.id.list_item_divider)); WrapContentHeightViewPager pager = segmentView.findViewById(R.id.pager); PagerSlidingTabStrip tabLayout = segmentView.findViewById(R.id.sliding_tabs); @@ -330,6 +319,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl public void onTabSelected(int position) { graphTabPosition = position; blockStatisticsBuilder.setTabItem(INIT_TAB_ITEMS[graphTabPosition]); + blockStatisticsBuilder.restartUpdatingStatBlocks(); } @Override @@ -339,8 +329,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } }); - graphsAdapter = new GPXItemPagerAdapter(app, GpxUiHelper.makeGpxDisplayItem(app, displayHelper.getGpx()), - displayHelper, nightMode, this, true); + graphsAdapter = new GPXItemPagerAdapter(app, nightMode, this, true, true); graphsAdapter.setChartHMargin(getResources().getDimensionPixelSize(R.dimen.content_padding)); pager.setAdapter(graphsAdapter); @@ -618,11 +607,23 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } } + private TrackDisplayHelper getDisplayHelper() { + TrackDisplayHelper displayHelper = new TrackDisplayHelper(app); + GPXFile gpxFile = getGPXFile(); + if (!selectedGpxFile.isShowCurrentTrack()) { + File file = new File(gpxFile.path); + displayHelper.setFile(file); + displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); + } + displayHelper.setGpx(gpxFile); + return displayHelper; + } + @Override public void onPointSelected(TrkSegment segment, double lat, double lon) { if (trackChartPoints == null) { trackChartPoints = new TrackChartPoints(); - trackChartPoints.setGpx(displayHelper.getGpx()); + trackChartPoints.setGpx(getDisplayHelper().getGpx()); } MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index 984f588341..cea3454fbc 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -39,7 +39,6 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities.CustomRadioButtonType; -import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType; @@ -52,8 +51,7 @@ import net.osmand.plus.views.controls.WrapContentHeightViewPager.ViewAtPositionI import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; -import org.apache.commons.lang3.ArrayUtils; - +import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -82,6 +80,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private WptPt selectedWpt; private TrkSegment segment; private GpxDisplayItem gpxItem; + private GPXTrackAnalysis analysis; private GPXTabItemType[] tabTypes; private SparseArray views = new SparseArray<>(); @@ -90,14 +89,45 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private boolean chartClicked; private boolean nightMode; private boolean onlyGraphs; + private boolean recordingTrack = false; private int chartHMargin = 0; public void setChartHMargin(int chartHMargin) { this.chartHMargin = chartHMargin; } - public void setGpxItem(GpxDisplayItem gpxItem) { - this.gpxItem = gpxItem; + private SelectedGpxFile getCurrentTrack() { + return app.getSavingTrackHelper().getCurrentTrack(); + } + + private GPXFile getGpxFile() { + return recordingTrack ? getCurrentTrack().getGpxFile() : displayHelper.getGpx(); + } + + public GPXItemPagerAdapter(@NonNull OsmandApplication app, + boolean nightMode, + @NonNull SegmentActionsListener actionsListener, + boolean onlyGraphs, + boolean recordingTrack) { + super(); + this.app = app; + this.nightMode = nightMode; + this.actionsListener = actionsListener; + this.onlyGraphs = onlyGraphs; + this.recordingTrack = recordingTrack; + iconsCache = app.getUIUtilities(); + + displayHelper = new TrackDisplayHelper(app); + GPXFile gpxFile = getGpxFile(); + if (!getCurrentTrack().isShowCurrentTrack()) { + File file = new File(gpxFile.path); + displayHelper.setFile(file); + displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); + } + displayHelper.setGpx(gpxFile); + + updateAnalysis(); + fetchTabTypes(); } public GPXItemPagerAdapter(@NonNull OsmandApplication app, @@ -114,17 +144,39 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid this.actionsListener = actionsListener; this.onlyGraphs = onlyGraphs; iconsCache = app.getUIUtilities(); + updateAnalysis(); fetchTabTypes(); } + private void updateAnalysis() { + analysis = null; + if (recordingTrack) { + GPXFile currentGpx = getCurrentTrack().getGpxFile(); + if (!currentGpx.isEmpty()) { + analysis = currentGpx.getAnalysis(0); + } + gpxItem = GpxUiHelper.makeGpxDisplayItem(app, currentGpx); + } else { + if (gpxItem != null) { + analysis = gpxItem.analysis; + } + } + } + private void fetchTabTypes() { List tabTypeList = new ArrayList<>(); - tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL); - if (gpxItem != null && gpxItem.analysis != null) { - if (gpxItem.analysis.hasElevationData) { + if (recordingTrack) { + if (analysis != null && (analysis.hasElevationData || analysis.hasSpeedData)) { + tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL); + } + } else { + tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL); + } + if (analysis != null) { + if (analysis.hasElevationData) { tabTypeList.add(GPX_TAB_ITEM_ALTITUDE); } - if (gpxItem.analysis.isSpeedSpecified()) { + if (analysis.isSpeedSpecified()) { tabTypeList.add(GPX_TAB_ITEM_SPEED); } } @@ -134,17 +186,12 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private List getDataSets(LineChart chart, GPXTabItemType tabType, LineGraphType firstType, LineGraphType secondType) { List dataSets = dataSetsMap.get(tabType); - GPXTrackAnalysis analysis = null; boolean withoutGaps = true; - SavingTrackHelper helper = app.getSavingTrackHelper(); - if (displayHelper.getGpx().equals(helper.getCurrentGpx())) { - SelectedGpxFile selectedGpxFile = helper.getCurrentTrack(); - GPXFile currentGpx = selectedGpxFile.getGpxFile(); - analysis = currentGpx.getAnalysis(0); - withoutGaps = !selectedGpxFile.isJoinSegments() + if (recordingTrack) { + GPXFile currentGpx = getGpxFile(); + withoutGaps = !getCurrentTrack().isJoinSegments() && (Algorithms.isEmpty(currentGpx.tracks) || currentGpx.tracks.get(0).generalTrack); } else if (gpxItem != null) { - analysis = gpxItem.analysis; GpxDataItem gpxDataItem = displayHelper.getGpxDataItem(); withoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments(); } @@ -231,20 +278,17 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid LineChart chart = view.findViewById(R.id.chart); ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) chart.getLayoutParams(); AndroidUtils.setMargins(lp, chartHMargin, lp.topMargin, chartHMargin, lp.bottomMargin); - GPXFile gpxFile = displayHelper.getGpx(); - if (gpxFile != null && gpxItem != null) { - GPXTrackAnalysis analysis = gpxItem.analysis; + if (analysis != null) { setupChart(view, chart); - switch (tabType) { case GPX_TAB_ITEM_GENERAL: - setupGeneralTab(view, chart, analysis, gpxFile, position); + setupGeneralTab(view, chart, position); break; case GPX_TAB_ITEM_ALTITUDE: - setupAltitudeTab(view, chart, analysis, gpxFile, position); + setupAltitudeTab(view, chart, position); break; case GPX_TAB_ITEM_SPEED: - setupSpeedTab(view, chart, analysis, gpxFile, position); + setupSpeedTab(view, chart, position); break; } } @@ -277,7 +321,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid return view; } - private void setupSpeedTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { + private void setupSpeedTab(View view, LineChart chart, int position) { if (analysis != null && analysis.isSpeedSpecified()) { if (analysis.hasSpeedData) { GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); @@ -349,7 +393,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid }); } - private void setupAltitudeTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { + private void setupAltitudeTab(View view, LineChart chart, int position) { if (analysis != null) { if (analysis.hasElevationData) { GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); @@ -416,7 +460,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid } } - private void setupGeneralTab(View view, LineChart chart, GPXTrackAnalysis analysis, GPXFile gpxFile, int position) { + private void setupGeneralTab(View view, LineChart chart, int position) { if (analysis != null) { if (analysis.hasElevationData || analysis.hasSpeedData) { GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); @@ -657,10 +701,12 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid @Override public void tabStylesUpdated(View tabsContainer, int currentPosition) { - ViewGroup.MarginLayoutParams params = (MarginLayoutParams) tabsContainer.getLayoutParams(); - params.height = app.getResources().getDimensionPixelSize(!onlyGraphs ? R.dimen.dialog_button_height : R.dimen.context_menu_buttons_bottom_height); - tabsContainer.setLayoutParams(params); - UiUtilities.updateCustomRadioButtons(app, tabsContainer, nightMode, getCustomRadioButtonType(currentPosition)); + if (getCount() > 0) { + ViewGroup.MarginLayoutParams params = (MarginLayoutParams) tabsContainer.getLayoutParams(); + params.height = app.getResources().getDimensionPixelSize(!onlyGraphs ? R.dimen.dialog_button_height : R.dimen.context_menu_buttons_bottom_height); + tabsContainer.setLayoutParams(params); + UiUtilities.updateCustomRadioButtons(app, tabsContainer, nightMode, getCustomRadioButtonType(currentPosition)); + } } private CustomRadioButtonType getCustomRadioButtonType(int index) { @@ -692,7 +738,6 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid void updateJoinGapsInfo(View view, int position) { if (view != null) { - GPXTrackAnalysis analysis = gpxItem.analysis; GPXTabItemType tabType = tabTypes[position]; boolean visible = gpxItem.isGeneralTrack() && analysis != null && tabType.equals(GPXTabItemType.GPX_TAB_ITEM_GENERAL); AndroidUiHelper.updateVisibility(view.findViewById(R.id.gpx_join_gaps_container), visible); @@ -731,50 +776,44 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid } } - public boolean isVisible() { - for (int i = 0; i < views.size(); i++) { - if (views.get(i).findViewById(R.id.chart).getVisibility() == View.VISIBLE) { - if (tabTypes[i] == GPX_TAB_ITEM_GENERAL && (gpxItem == null || gpxItem.analysis == null)) { - return false; + public boolean isTabsVisible() { + if (getCount() > 0 && views.size() > 0) { + for (int i = 0; i < getCount(); i++) { + LineChart lc = getViewAtPosition(i).findViewById(R.id.chart); + if (!lc.isEmpty() && !getGpxFile().isEmpty()) { + return true; } - return true; } } return false; } public void updateGraph(int position) { - LineGraphType firstType = tabTypes[position] == GPX_TAB_ITEM_SPEED ? SPEED : ALTITUDE; - LineGraphType secondType = null; - if (tabTypes[position] == GPX_TAB_ITEM_ALTITUDE) { - secondType = SLOPE; - } else if (tabTypes[position] == GPX_TAB_ITEM_GENERAL) { - secondType = SPEED; - } - - LineChart chart = getViewAtPosition(position).findViewById(R.id.chart); - List dataSets = getDataSets(chart, tabTypes[position], firstType, secondType); - boolean isEmptyDataSets = Algorithms.isEmpty(dataSets); - AndroidUiHelper.updateVisibility(chart, !isEmptyDataSets); - chart.clear(); - if (!isEmptyDataSets) { - chart.setData(new LineData(dataSets)); - } - if (chart.getAxisRight().getLabelCount() != CHART_LABEL_COUNT - || chart.getAxisLeft().getLabelCount() != CHART_LABEL_COUNT) { - GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); - } - updateChart(chart); - notifyDataSetChanged(); - } - - public void fetchTabTypesIfNeeded(GPXTabItemType[] tabTypes) { - if (!ArrayUtils.isEquals(this.tabTypes, tabTypes)) { - fetchTabTypes(); - for (int i = 0; i < this.tabTypes.length; i++) { - updateGraph(i); + updateAnalysis(); + fetchTabTypes(); + if (getCount() > 0 && views.size() > 0) { + LineGraphType firstType = tabTypes[position] == GPX_TAB_ITEM_SPEED ? SPEED : ALTITUDE; + LineGraphType secondType = null; + if (tabTypes[position] == GPX_TAB_ITEM_ALTITUDE) { + secondType = SLOPE; + } else if (tabTypes[position] == GPX_TAB_ITEM_GENERAL) { + secondType = SPEED; } + LineChart chart = getViewAtPosition(position).findViewById(R.id.chart); + List dataSets = getDataSets(chart, tabTypes[position], firstType, secondType); + boolean isEmptyDataSets = Algorithms.isEmpty(dataSets); + AndroidUiHelper.updateVisibility(chart, !isEmptyDataSets); + chart.clear(); + if (!isEmptyDataSets) { + chart.setData(new LineData(dataSets)); + } + if (chart.getAxisRight().getLabelCount() != CHART_LABEL_COUNT + || chart.getAxisLeft().getLabelCount() != CHART_LABEL_COUNT) { + GpxUiHelper.setupGPXChart(app, chart, CHART_LABEL_COUNT); + } + updateChart(chart); } + notifyDataSetChanged(); } private TrkSegment getTrkSegment() { diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 499706c83e..f62ce6a82a 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -131,6 +131,11 @@ public class GpxBlockStatisticsBuilder { } } + public void restartUpdatingStatBlocks() { + stopUpdatingStatBlocks(); + runUpdatingStatBlocksIfNeeded(); + } + public void initItems() { GPXFile gpxFile = getGPXFile(); if (app == null || gpxFile == null) { From ae858ede93857a6619c69c647a2e6bc9240adafc Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 28 Mar 2021 00:24:57 +0200 Subject: [PATCH 053/109] storage path fix --- .../net/osmand/plus/settings/datastorage/DataStorageHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java index 67fd73897e..b292a02e0d 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java @@ -106,7 +106,7 @@ public class DataStorageHelper { //shared storage dir = settings.getDefaultInternalStorage(); - path = dir.getAbsolutePath(); + path = "\u200e" + dir.getAbsolutePath(); iconId = R.drawable.ic_action_phone; StorageItem sharedStorageItem = StorageItem.builder() From 239d42852af4447f2bc681cf92de0e10af07e6db Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Fri, 26 Mar 2021 10:24:45 +0000 Subject: [PATCH 054/109] Translated using Weblate (Japanese) Currently translated at 97.8% (3616 of 3695 strings) --- OsmAnd/res/values-ja/strings.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index c619818f9b..212dfab6fe 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -3080,7 +3080,7 @@ POIの更新は利用できません 経路%sを保存しました 一時的な制限の検討 『クイックアクション』のリストに最低ひとつは項目を設定する必要があります - アルペン/ダウンヒルスキー + アルペンスキーとダウンヒルスキー アルペンスキーまたはダウンヒルスキーに用の斜面(ゲレンデ)やスキーリフトへの道 クロスカントリースキーとノルディックスキー ノルディックスキーやクロスカントリースキー用コースやそれらに用いられる小道などです。 @@ -3776,7 +3776,7 @@ POIの更新は利用できません 繰り返し • ルート計画機能を更新 : セグメントごとに異なるナビゲーションタイプを使用し、経路として反映することが可能に \n -\n• 経路の新しい外観オプション : 色、太さ、表示方向矢印、開始/終了アイコン選択 +\n• 経路の新しい外観オプション : 色、太さ、表示方向矢印、開始と終了アイコンの選択 \n \n• 自転車ノードの視認性を向上 \n @@ -4052,4 +4052,12 @@ POIの更新は利用できません \n• \"旅程記録\"ダイアログを更新 \n \n + 開始・終了アイコン + \'等高線(Contour lines)\'をご購入いただきありがとうございます + サブスクリプションは選択した期間に応じて課金されます。 AppGalleryからいつでもキャンセルできます。 + 購入確認後に利用者のAppGalleryアカウントへ請求されます。 +\n +\nサブスクリプションは更新日前にキャンセルされない限り自動的に延長されます。アカウントには更新日に更新期間分(月/ 3ヶ月/年)の金額が請求されます。 +\n +\nAppGallery設定でサブスクリプションの管理およびキャンセルができます。 \ No newline at end of file From fa0dcb03aaf88017aac4e0995ef584c38c450298 Mon Sep 17 00:00:00 2001 From: Ldm Public Date: Sat, 27 Mar 2021 18:14:41 +0000 Subject: [PATCH 055/109] Translated using Weblate (French) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-fr/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OsmAnd/res/values-fr/strings.xml b/OsmAnd/res/values-fr/strings.xml index 72e77075b4..89e6c2730b 100644 --- a/OsmAnd/res/values-fr/strings.xml +++ b/OsmAnd/res/values-fr/strings.xml @@ -715,7 +715,7 @@ Enregistrez l\'emplacement de stationnement de votre véhicule et, si besoin, mesurez la durée de stationnement restante. \nCes informations sont visibles sur le Tableau de bord comme sur la carte. Un rappel peut même être ajouté à votre calendrier. Stationnement - Marquer comme stationnement + Stationnement Supprimer l\'emplacement de stationnement Point de départ trop éloigné de la route la plus proche. Lieu partagé @@ -1217,7 +1217,7 @@ \nPoints de passage %2$s %1$s \nPoints %1$s \nTrace %2$s - Itinéraire + Point de passage Heure actuelle Chargement de %1$s… Enregistrer comme groupe de favoris @@ -3722,7 +3722,7 @@ Saisissez l\'adresse Ajouter à un fichier de trace Ajouter des fichiers de trace - Ajouter un point de passage + Ajouter une étape Ajouter un point de passage à la trace Début de la trace Déplacer sur les routes From 2b01201311dcaed456be8a6959f085926d6a2502 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 26 Mar 2021 19:13:36 +0000 Subject: [PATCH 056/109] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-uk/strings.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/OsmAnd/res/values-uk/strings.xml b/OsmAnd/res/values-uk/strings.xml index a2fcf4cd0e..c679111b1e 100644 --- a/OsmAnd/res/values-uk/strings.xml +++ b/OsmAnd/res/values-uk/strings.xml @@ -545,7 +545,7 @@ Завантажується список доступних регіонів… Не вдалося отримати список регіонів з https://osmand.net. Збережена точка закладки була змінена - Точки Закладок відсутні + Немає закладених точок Замінити Показати маршрут Почати супровід @@ -878,7 +878,7 @@ Показувати попередження… Аварійні служби Швидка побудова маршруту (можливо неоптимальна) - Налаштування попередження про дорожній рух (обмеження швидкості, вимушені зупинки, штучні нерівності, тунелі), попередження про камери контролю швидкості, відомості про смуги руху. + Налаштування попереджень про дорожній рух (обмеження швидкості, вимушені зупинки, штучні нерівності, тунелі), попередження про камери контролю швидкості, відомості про смуги руху. Уник. автомагістралей Прив’язуватися до доріг Перегляд та навігація в автономному та мережевому режимах мапами OSM @@ -977,7 +977,7 @@ Використовувати магнітометр Налаштуйте, як записувати свої поїздки. Завантаження… - Вилучити точку + Видалити точку час точність швидкість @@ -1348,7 +1348,7 @@ Ви увійшли як %1$s Допустиме значення перевищення швидкості Оберіть допустиме значення перевищення швидкості, при перевищенні якого Ви отримаєте голосове попередження. - Назву Закладки було змінено на %1$s, щоб мати можливість зберігати рядки зі смайликами у файл. + Закладку перейменовано на «%1$s», щоб зберегти у файл рядок, що містить смайлики. Друк маршруту Дублювання назви закладки Вказана назва Закладки вже існує, тому її було змінено на %1$s, щоб уникнути появи дублікатів. @@ -1900,7 +1900,7 @@ Сповіщати лише, коли змінюється напрямок до цільової точки. Період сповіщеннь Найменший час між оголошеннями. - Усталений колір + Типовий колір Оберіть категорію Додайте назву Додайте категорію @@ -2031,7 +2031,7 @@ Втулок для необмеженого доступу до мап, їх оновлень та отримання відомостей з Wikipedia. Милі/метри Пропустити завантаження мап - У Вас немає завантажених мап. Ви можете вибрати мапу зі списку або завантажити її пізніше за допомогою меню — %1$s. + У вас немає завантажених мап. Ви можете вибрати мапу зі списку або завантажити її пізніше за допомогою меню — %1$s. Виберіть інший регіон Пошук мапи… OsmAnd визначить ваше розташування і запропонує завантажити мапи для цього регіону. @@ -2395,7 +2395,7 @@ Поділитися своїми вуличними видами цієї місцевості через Mapillary. Віджет Mapillary Дозволяє швидко зробити внесок в Mapillary. - Світлини вулиць в мережі для всіх. Відкрийте для себе місця, діліться та знимкуйте весь світ. + Світлини вулиць в мережі для всіх. Відкрийте для себе місця, діліться та захоплюйте весь світ. Вуличні світлини для усіх. Відкривайте для себе місця, співпрацюйте, знімкуйте світ. Мережеві світлини Тут нема світлин. @@ -2979,7 +2979,7 @@ Виберіть профіль для початку Служба завантаження OsmAnd Пурпуровий - Значок + Піктограма Дані зібрано Натисніть ще раз для зміни орієнтації мапи Мінімальна швидкість @@ -3077,7 +3077,7 @@ Зовнішні пристрої введення Оберіть пристрій на зразок звичайної клавіатури чи WunderLINQ для зовнішнього керування. Немає - Звичайна клавіатура + Клавіатура WundеrLINQ Parrot Увімкніть принаймні один профіль застосунку, щоб скористатися цим параметром. @@ -3253,7 +3253,7 @@ Надавати перевагу ґрунтовим дорогам Надати перевагу незаасфальтованим над асфальтованими дорогами для прокладки. Правки OSM - Увімк/вимк показ горизонталей. + Увімк/вимк показ горизонталей на мапі. Кнопка, що показує чи приховує горизонталі на мапі. Не вдається запустити рушій мовлення. Відтворити свою позицію за допомогою записаного треку GPX. @@ -3370,7 +3370,7 @@ Додати власну категорію Показувати лише вночі Усі налаштування втулка відновлено до усталеного стану. - Усі налаштування профілю відновлено до усталеного стану. + Усі налаштування профілю відновлено до типових. %1$s/%2$s Захід сонця о %1$s Схід сонця о %1$s @@ -3436,7 +3436,7 @@ Нічого не вибрано Швидкі дії Профілі - Перелічені %1$s вже існують у OsmAnd. + Перелічені %1$s вже існують в OsmAnd. Поточні елементи будуть замінені на елементи з файлу Замінити все Зберегти обидва @@ -3464,7 +3464,7 @@ Маршрут буде перераховано, якщо відстань від маршруту до поточного місця розташування перевищує вибране значення. Виберіть відстань, після якого маршрут буде перераховано. Перерахунок маршруту у випадку відхилення - Хв + Мін Рельєф Мапа пагорбів використовує темні відтінки для показу схилів, вершин і низин. У режимі Схил, рельєф місцевості візуалізується за допомогою кольорів. @@ -3485,7 +3485,7 @@ Вибрати групу Вибрати фігуру Коло - Площа + Квадрат Восьмикутник Замінити іншу точку цією. Гірськолижний туризм From c7c9cd76828c7593a34e7e188bead700bffc498d Mon Sep 17 00:00:00 2001 From: Manuel Tassi Date: Fri, 26 Mar 2021 10:23:45 +0000 Subject: [PATCH 057/109] Translated using Weblate (Italian) Currently translated at 88.1% (3257 of 3695 strings) --- OsmAnd/res/values-it/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 240b7e3156..56bc8eff8e 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -2070,7 +2070,7 @@ Spessore linee isoipse Spessore linee isoipse Acqua - Non visualizzare l\'acqua + Nascondi l\'acqua Densità linee isoipse Azione rapida Azione %d From 387a92af01fef7e8961dd934fa1c8d7779247cf5 Mon Sep 17 00:00:00 2001 From: iman Date: Sat, 27 Mar 2021 19:03:31 +0000 Subject: [PATCH 058/109] Translated using Weblate (Persian) Currently translated at 99.9% (3692 of 3695 strings) --- OsmAnd/res/values-fa/strings.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OsmAnd/res/values-fa/strings.xml b/OsmAnd/res/values-fa/strings.xml index 92ceed2233..c7a92d5c8a 100644 --- a/OsmAnd/res/values-fa/strings.xml +++ b/OsmAnd/res/values-fa/strings.xml @@ -680,7 +680,7 @@ \n {1} مگابایت (از {2} مگابایت) استفاده خواهد شد. پوستهٔ شفاف کتابخانهٔ native بر روی این دستگاه پشتیبانی نمی‌شود. - مقداردهی اولیهٔ کتابخانهٔ native… + در حال مقداردهی اولیهٔ کتابخانهٔ native… نمای نقشه خودکار-مرکز مدت‌زمانی که طول می‌کشد تا نقشه با موقعیت کنونی همگام شود. ناوبری فقط با حالت خودکار-مرکز @@ -706,7 +706,7 @@ آیا از حذف %1$d علاقه‌مندی و %2$d گروه علاقه‌مندی مطمئن هستید؟ نقشه پایهٔ جهان را دانلود کنید تا نمایی از سراسر جهان در زوم‌های کم داشته باشید. نسخهٔ محلی - گشودن دادهٔ جدید… + در حال گشودن دادهٔ جدید… ناوبری آنلاین به‌طور آفلاین کار نمی‌کند. داده وجود ندارد برعکس‌کردن جهت رد @@ -744,7 +744,7 @@ هم‌رسانی مکان در حال نمایه‌کردن نشانی… در حال نمایه‌کردن نقشه… - نمایه‌کردن POI‏… + در حال نمایه‌کردن نقاط توجه… در حال نمایه‌کردن حمل‌ونقل… خطای ورودی/خروجی km @@ -787,8 +787,8 @@ در حال تبدیل اسامی محلی/انگلیسی… ناموفق اجازهٔ دسترسی احراز نشد - بستن بستهٔ تغییر… - بازکردن بستهٔ تغییر… + در حال بستن بستهٔ تغییر… + در حال بازکردن بستهٔ تغییر… دریافت لیست مناطق از https://osmand.net ناموفق بود. در حال دانلود لیست مناطق موجود… دادهٔ آفلاینِ {0} از قبل وجود دارد ({1}). آن را روزآمد می‌کنید ({2})؟ @@ -1633,7 +1633,7 @@ صرف‌نظر از دانلود نقشه‌ها نقشهٔ آفلاینی نصب نکرده‌اید. نقشه‌ای را از لیست انتخاب نمایید یا بعداً از طریق «منو ← %1$s»، آن را دانلود کنید. منطقهٔ دیگری را انتخاب کنید - جست‌وجوی نقشه‌ها… + در حال جست‌وجوی نقشه‌ها… اجازه دهید برنامه موقعیت شما را پیدا کند تا نقشهٔ آنجا را برای دانلود پیشنهاد بدهد. موقعیت پیدا نشد اتصال اینترنت برقرار نیست @@ -2375,7 +2375,7 @@ درون‌برد فایل GPX ورود فوری مختصات نمایش خطوط جهت‌دار - به نمایشش روی نقشه ادامه بده + روی نقشه نمایان بماند ذخیره به‌عنوان نقاط مسیر نقطهٔ مسیر میزان اُفت‌وخیز ارتفاع را انتخاب کنید @@ -2824,7 +2824,7 @@ پیاده طول مسیر نقاط توجه (POI) - محاسبهٔ مسیر… + در حال محاسبهٔ مسیر… حمل‌ونقل عمومی جاده‌ای که می‌خواهید هنگام ناوبری از آن بپرهیزید، روی نقشه یا از لیست زیر انتخاب کنید: در امتداد مسیر نشان بده @@ -2947,7 +2947,7 @@ محاسبهٔ مسیر پیاده نوع حمل‌ونقل ارسال گزارش - جست‌وجوی GPS‏ + در حال جست‌وجوی GPS‏ ابزارک مختصات لطفاً در گوگل‌پلی دربارهٔ کار ما نظر و امتیاز بدهید. سیاست حریم خصوصی From 787ec5b159bf0fc954a95d90b9bf4b64c7d2272f Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 26 Mar 2021 19:18:25 +0000 Subject: [PATCH 059/109] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3894 of 3894 strings) --- OsmAnd/res/values-uk/phrases.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 015cddb2a8..454bd79608 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -1209,7 +1209,7 @@ Скайп Ютюб Інстаграм - Вконтактє + VKontakte Гугле+ Мобільний телефон Час обслуговування From 6322fad7b578a55acdf3a5ac0543f06504974b9f Mon Sep 17 00:00:00 2001 From: Franco Date: Fri, 26 Mar 2021 11:44:04 +0000 Subject: [PATCH 060/109] Translated using Weblate (Spanish (Argentina)) Currently translated at 99.9% (3694 of 3695 strings) --- OsmAnd/res/values-es-rAR/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-es-rAR/strings.xml b/OsmAnd/res/values-es-rAR/strings.xml index 91493663a7..177cc6c449 100644 --- a/OsmAnd/res/values-es-rAR/strings.xml +++ b/OsmAnd/res/values-es-rAR/strings.xml @@ -1394,7 +1394,7 @@ Descargando lista de regiones disponibles… No se pudo obtener la lista de regiones desde https://osmand.net. Punto favorito editado - Sin puntos de Favoritos + No existen puntos favoritos Reemplazar Mostrar ruta Iniciar la guía From 122aef6ae662da3f033d48f8f307d804264646f9 Mon Sep 17 00:00:00 2001 From: Softmap Date: Fri, 26 Mar 2021 22:07:42 +0000 Subject: [PATCH 061/109] Translated using Weblate (Arabic) Currently translated at 93.4% (3639 of 3894 strings) --- OsmAnd/res/values-ar/phrases.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OsmAnd/res/values-ar/phrases.xml b/OsmAnd/res/values-ar/phrases.xml index 372df7b654..ddb10cbcc1 100644 --- a/OsmAnd/res/values-ar/phrases.xml +++ b/OsmAnd/res/values-ar/phrases.xml @@ -3703,4 +3703,12 @@ الجيوديسيا (شكل الأرض ومساحتها) المرجع المحلي الزحلقه + التدريب: تصفيف الشعر + التدريب: الطيران + التدريب: اليوغا + التدريب: الحاسوب + التدريب: فن + التدريب: رياضة + نصب تذكاري بوذي + ممر زحلقة الشمالي \ No newline at end of file From 97f0f8d9e82904ebb0672533201e005aedc69fa0 Mon Sep 17 00:00:00 2001 From: Famlam Date: Fri, 26 Mar 2021 21:43:42 +0000 Subject: [PATCH 062/109] Translated using Weblate (Dutch) Currently translated at 98.2% (3629 of 3695 strings) --- OsmAnd/res/values-nl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/res/values-nl/strings.xml b/OsmAnd/res/values-nl/strings.xml index 07c4aef6f7..bad32e0a9e 100644 --- a/OsmAnd/res/values-nl/strings.xml +++ b/OsmAnd/res/values-nl/strings.xml @@ -2884,7 +2884,7 @@ Wissel tussen dag-/nachtmodus Oppervlakte Kwaliteit wegdek - Steilte + Helling U gebruikt {0} kaart geleverd door OsmAnd. Wilt u de \"OsmAnd full\" versie openen\? Open OsmAnd\? Eenheid hoeken From be85c4dcd6dc455ce49b1f17ff840e1971f2e831 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 28 Mar 2021 22:37:03 +0300 Subject: [PATCH 063/109] User suggestion --- .../routing/data/AnnounceTimeDistances.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java index ea50cdf1e5..a0f1ca0cd8 100644 --- a/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java +++ b/OsmAnd/src/net/osmand/plus/routing/data/AnnounceTimeDistances.java @@ -210,24 +210,21 @@ public class AnnounceTimeDistances { return (int) (dist - voicePromptDelayTimeSec * speed); } - private void appendTurnDesc(SpannableStringBuilder builder, String name, int dist, String meter, String second) { - appendTurnDesc(builder, name, dist, DEFAULT_SPEED, meter, second); + private void appendTurnDesc(OsmandApplication app, SpannableStringBuilder builder, String name, int dist, String meter, String second) { + appendTurnDesc(app, builder, name, dist, DEFAULT_SPEED, meter, second); } - private void appendTurnDesc(SpannableStringBuilder builder, String name, int dist, float speed, String meter, String second) { + private void appendTurnDesc(OsmandApplication app, SpannableStringBuilder builder, String name, int dist, float speed, String meter, String second) { int minDist = (dist / 5) * 5; int time = (int) (dist / speed); if (time > 15) { // round to 5 time = (time / 5) * 5; } - boolean isLeftToRight = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == ViewCompat.LAYOUT_DIRECTION_LTR; - if (isLeftToRight) { - builder.append(String.format("\n%s: %d - %d %s, %d %s.", name, minDist, minDist + 5, meter, time, second)); - } else { - builder.append(String.format("\n%s: %s %d, %s %d - %d.", name, second, time, meter, minDist, minDist + 5)); + String distStr = String.format("\n%s: %d - %d %s", name, minDist, minDist + 5, meter); + String timeStr = String.format("%d %s.", time, second); + builder.append(app.getString(R.string.ltr_or_rtl_combine_via_comma, distStr, timeStr)); - } } public Spannable getIntervalsDescription(OsmandApplication app) { @@ -253,35 +250,35 @@ public class AnnounceTimeDistances { builder.append(turn); makeBold(builder, turn); if (PREPARE_DISTANCE_END <= PREPARE_DISTANCE) { - appendTurnDesc(builder, prepare, PREPARE_DISTANCE, meter, second); + appendTurnDesc(app, builder, prepare, PREPARE_DISTANCE, meter, second); } if (PREPARE_LONG_DISTANCE_END <= PREPARE_LONG_DISTANCE) { - appendTurnDesc(builder, longPrepare, PREPARE_LONG_DISTANCE, meter, second); + appendTurnDesc(app, builder, longPrepare, PREPARE_LONG_DISTANCE, meter, second); } - appendTurnDesc(builder, approach, TURN_IN_DISTANCE, meter, second); - appendTurnDesc(builder, passing, TURN_NOW_DISTANCE, TURN_NOW_SPEED, meter, second); + appendTurnDesc(app, builder, approach, TURN_IN_DISTANCE, meter, second); + appendTurnDesc(app, builder, passing, TURN_NOW_DISTANCE, TURN_NOW_SPEED, meter, second); // Arrive at destination - appendTurnDesc(builder, arrive, (int) (getArrivalDistance()), meter, second); + appendTurnDesc(app, builder, arrive, (int) (getArrivalDistance()), meter, second); makeBoldFormatted(builder, arrive); // Off-route if (getOffRouteDistance() > 0) { - appendTurnDesc(builder, offRoute, (int) getOffRouteDistance(), meter, second); + appendTurnDesc(app, builder, offRoute, (int) getOffRouteDistance(), meter, second); makeBoldFormatted(builder, offRoute); } // Traffic warnings builder.append(traffic); makeBold(builder, traffic); - appendTurnDesc(builder, approach, LONG_ALARM_ANNOUNCE_RADIUS, meter, second); - appendTurnDesc(builder, passing, SHORT_ALARM_ANNOUNCE_RADIUS, meter, second); + appendTurnDesc(app, builder, approach, LONG_ALARM_ANNOUNCE_RADIUS, meter, second); + appendTurnDesc(app, builder, passing, SHORT_ALARM_ANNOUNCE_RADIUS, meter, second); // Waypoint / Favorite / POI builder.append(point); makeBold(builder, point); - appendTurnDesc(builder, approach, LONG_PNT_ANNOUNCE_RADIUS, meter, second); - appendTurnDesc(builder, passing, SHORT_PNT_ANNOUNCE_RADIUS, meter, second); + appendTurnDesc(app, builder, approach, LONG_PNT_ANNOUNCE_RADIUS, meter, second); + appendTurnDesc(app, builder, passing, SHORT_PNT_ANNOUNCE_RADIUS, meter, second); return builder; } From 6fb2273ee49472ede4ef140a67a4380a6c3ca771 Mon Sep 17 00:00:00 2001 From: xmd5a Date: Sun, 28 Mar 2021 23:30:32 +0300 Subject: [PATCH 064/109] Add phrase --- OsmAnd/res/values/phrases.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 675077e65c..1f4afe5537 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4347,4 +4347,6 @@ Local ref + Camp pitch + From 99c432d9ff37216b2e2dc367069fdd09d9a6e007 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Sun, 28 Mar 2021 23:41:49 +0300 Subject: [PATCH 065/109] Change targetFragment to MapRouteInfoMenu, static startNavigation --- .../MapRouteInfoMenuFragment.java | 47 ++++++++++++++----- .../cards/TracksCard.java | 6 +-- .../osmand/plus/track/TrackMenuFragment.java | 23 +++++---- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java index bd1d382677..8710c934dd 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java @@ -16,6 +16,7 @@ import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import net.osmand.AndroidUtils; +import net.osmand.GPXUtilities; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.OsmandApplication; @@ -23,11 +24,14 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.base.ContextMenuFragment; import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.routing.GPXRouteParams; import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.settings.backend.ApplicationMode; +import net.osmand.plus.track.TrackMenuFragment; +import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import net.osmand.plus.widgets.TextViewExProgress; -public class MapRouteInfoMenuFragment extends ContextMenuFragment { +public class MapRouteInfoMenuFragment extends ContextMenuFragment implements TrackSelectSegmentBottomSheet.OnSegmentSelectedListener { public static final String TAG = MapRouteInfoMenuFragment.class.getName(); @Nullable @@ -95,13 +99,13 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + Bundle savedInstanceState) { MapActivity mapActivity = requireMapActivity(); menu = mapActivity.getMapRouteInfoMenu(); View view = super.onCreateView(inflater, container, savedInstanceState); if (view != null) { - bottomContainer = (FrameLayout) view.findViewById(R.id.bottom_container); + bottomContainer = view.findViewById(R.id.bottom_container); modesLayoutToolbar = view.findViewById(R.id.modes_layout_toolbar); modesLayoutToolbarContainer = view.findViewById(R.id.modes_layout_toolbar_container); modesLayoutListContainer = view.findViewById(R.id.modes_layout_list_container); @@ -121,7 +125,7 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { int widthNoShadow = getLandscapeNoShadowWidth(); modesLayoutToolbar.setLayoutParams(new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT)); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(widthNoShadow, ViewGroup.LayoutParams.WRAP_CONTENT); - params.gravity = Gravity.BOTTOM|Gravity.START; + params.gravity = Gravity.BOTTOM | Gravity.START; view.findViewById(R.id.control_buttons).setLayoutParams(params); View appModesView = view.findViewById(R.id.app_modes); AndroidUtils.setPadding(appModesView, 0, 0, appModesView.getPaddingRight(), 0); @@ -182,15 +186,15 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { @Override protected void updateMenuState(int currentMenuState, int newMenuState) { - if(getMyApplication().getRoutingHelper().isRouteCalculated() ) { + if (getMyApplication().getRoutingHelper().isRouteCalculated()) { ApplicationMode mV = getMyApplication().getRoutingHelper().getAppMode(); if (newMenuState == MenuState.HEADER_ONLY && currentMenuState == MenuState.HALF_SCREEN) { - getSettings().OPEN_ONLY_HEADER_STATE_ROUTE_CALCULATED.setModeValue(mV,true); + getSettings().OPEN_ONLY_HEADER_STATE_ROUTE_CALCULATED.setModeValue(mV, true); } else if (currentMenuState == MenuState.HEADER_ONLY && newMenuState == MenuState.HALF_SCREEN) { getSettings().OPEN_ONLY_HEADER_STATE_ROUTE_CALCULATED.resetModeToDefault(mV); } } - } + } @Override protected void setViewY(int y, boolean animated, boolean adjustMapPos) { @@ -347,7 +351,7 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { OsmandApplication app = getMyApplication(); return app != null && app.getRoutingHelper().isOsmandRouting(); } - + public void updateRouteCalculationProgress(int progress) { MapActivity mapActivity = getMapActivity(); View mainView = getMainView(); @@ -356,7 +360,7 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { return; } boolean indeterminate = isPublicTransportMode() || !isOsmandRouting(); - ProgressBar progressBar = (ProgressBar) mainView.findViewById(R.id.progress_bar); + ProgressBar progressBar = mainView.findViewById(R.id.progress_bar); if (progressBar != null) { if (progress == 0) { progressBar.setIndeterminate(indeterminate); @@ -366,14 +370,14 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { } progressBar.setProgress(progress); } - ProgressBar progressBarButton = (ProgressBar) view.findViewById(R.id.progress_bar_button); + ProgressBar progressBarButton = view.findViewById(R.id.progress_bar_button); if (progressBarButton != null) { if (progressBarButton.getVisibility() != View.VISIBLE) { progressBarButton.setVisibility(View.VISIBLE); } progressBarButton.setProgress(indeterminate ? 0 : progress); } - TextViewExProgress textViewExProgress = (TextViewExProgress) view.findViewById(R.id.start_button_descr); + TextViewExProgress textViewExProgress = view.findViewById(R.id.start_button_descr); textViewExProgress.percent = indeterminate ? 0 : progress / 100f; textViewExProgress.invalidate(); } @@ -390,11 +394,11 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { if (progressBar != null) { progressBar.setVisibility(View.GONE); } - ProgressBar progressBarButton = (ProgressBar) view.findViewById(R.id.progress_bar_button); + ProgressBar progressBarButton = view.findViewById(R.id.progress_bar_button); if (progressBarButton != null) { progressBarButton.setProgress(0); } - TextViewExProgress textViewExProgress = (TextViewExProgress) view.findViewById(R.id.start_button_descr); + TextViewExProgress textViewExProgress = view.findViewById(R.id.start_button_descr); textViewExProgress.percent = 0; } @@ -501,4 +505,21 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment { return false; } } + + @Override + public void onSegmentSelect(GPXUtilities.GPXFile gpxFile, int selectedSegment) { + if (getMyApplication() != null) { + getMyApplication().getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment); + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + TrackMenuFragment.startNavigationForGPX(gpxFile, mapActivity.getMapActions(), mapActivity); + GPXRouteParams.GPXRouteParamsBuilder paramsBuilder = getMyApplication().getRoutingHelper().getCurrentGPXRoute(); + if (paramsBuilder != null) { + paramsBuilder.setSelectedSegment(selectedSegment); + getMyApplication().getRoutingHelper().onSettingsChanged(true); + } + dismiss(); + } + } + } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java index 1abccb3382..fe09174683 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/TracksCard.java @@ -21,8 +21,8 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.GpxUiHelper; import net.osmand.plus.helpers.GpxUiHelper.GPXInfo; +import net.osmand.plus.routepreparationmenu.MapRouteInfoMenuFragment; import net.osmand.plus.settings.backend.ApplicationMode; -import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import java.io.File; @@ -131,8 +131,8 @@ public class TracksCard extends BaseCard { } } if (item.file.getNonEmptySegmentsCount() > 1) { - Fragment f = mapActivity.getSupportFragmentManager().findFragmentByTag(TrackMenuFragment.TAG); - TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), item.file, f); + Fragment targetFragment = mapActivity.getSupportFragmentManager().findFragmentByTag(MapRouteInfoMenuFragment.TAG); + TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), item.file, targetFragment); } else { mapActivity.getMapActions().setGPXRouteParams(item.file); app.getTargetPointsHelper().updateRouteAndRefresh(true); diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index bb738a8e00..f5c52a11ce 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -82,8 +82,8 @@ import net.osmand.plus.myplaces.TrackActivityFragmentAdapter; import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.routepreparationmenu.cards.BaseCard.CardListener; -import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.routing.GPXRouteParams.GPXRouteParamsBuilder; +import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.track.SaveGpxAsyncTask.SaveGpxListener; import net.osmand.plus.track.TrackSelectSegmentBottomSheet.OnSegmentSelectedListener; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; @@ -804,7 +804,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card if (gpxFile.getNonEmptySegmentsCount() > 1) { TrackSelectSegmentBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), gpxFile, this); } else { - startNavigationForGPX(gpxFile, mapActions); + startNavigationForGPX(gpxFile, mapActions, mapActivity); dismiss(); } } @@ -827,7 +827,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card segment = segments.get(0); } } - GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}; + GpxDisplayItemType[] filterTypes = new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT}; List items = TrackDisplayHelper.flatten(displayHelper.getOriginalGroups(filterTypes)); if (segment != null && !Algorithms.isEmpty(items)) { SplitSegmentDialogFragment.showInstance(fragmentManager, displayHelper, items.get(0), segment); @@ -904,12 +904,11 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } } - private void startNavigationForGPX(final GPXFile gpxFile, MapActivityActions mapActions) { - if (app.getRoutingHelper().isFollowingMode()) { + public static void startNavigationForGPX(final GPXFile gpxFile, MapActivityActions mapActions, final MapActivity mapActivity) { + if (mapActivity.getMyApplication().getRoutingHelper().isFollowingMode()) { mapActions.stopNavigationActionConfirm(null, new Runnable() { @Override public void run() { - MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null, null, null, true, true, MenuState.HEADER_ONLY); @@ -1130,7 +1129,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card public boolean onMenuItemClick(MenuItem item) { int i = item.getItemId(); if (i == R.id.action_edit) { - editSegment(segment); + editSegment(); return true; } else if (i == R.id.action_delete) { FragmentActivity activity = getActivity(); @@ -1164,7 +1163,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card app.getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment); MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { - startNavigationForGPX(gpxFile, mapActivity.getMapActions()); + startNavigationForGPX(gpxFile, mapActivity.getMapActions(), mapActivity); GPXRouteParamsBuilder paramsBuilder = app.getRoutingHelper().getCurrentGPXRoute(); if (paramsBuilder != null) { paramsBuilder.setSelectedSegment(selectedSegment); @@ -1174,7 +1173,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } } - private void editSegment(TrkSegment segment) { + private void editSegment() { GPXFile gpxFile = getGpx(); openPlanRoute(new GpxData(gpxFile)); hide(); @@ -1219,7 +1218,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card @Override public void gpxSavingFinished(Exception errorMessage) { if (selectedGpxFile != null) { - List groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[] {GpxDisplayItemType.TRACK_SEGMENT}); + List groups = displayHelper.getDisplayGroups(new GpxDisplayItemType[]{GpxDisplayItemType.TRACK_SEGMENT}); selectedGpxFile.setDisplayGroups(groups, app); selectedGpxFile.processPoints(app); } @@ -1313,7 +1312,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } public static void showInstance(@NonNull MapActivity mapActivity, - @Nullable String path, + @Nullable String path, boolean showCurrentTrack, @Nullable final LatLon latLon, @Nullable final String returnScreenName, @@ -1332,7 +1331,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card } public static boolean showInstance(@NonNull MapActivity mapActivity, - @NonNull SelectedGpxFile selectedGpxFile, + @NonNull SelectedGpxFile selectedGpxFile, @Nullable LatLon latLon, @Nullable String returnScreenName, @Nullable String callingFragmentTag) { From 1cdf506212c4b18dc3e6281c4bb1c7a2511046e5 Mon Sep 17 00:00:00 2001 From: Hierax Swiftwing Date: Sun, 28 Mar 2021 13:40:21 +0000 Subject: [PATCH 066/109] Translated using Weblate (Serbian) Currently translated at 97.7% (3612 of 3695 strings) --- OsmAnd/res/values-sr/strings.xml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-sr/strings.xml b/OsmAnd/res/values-sr/strings.xml index e23eae86cc..f3e3dd9e2b 100644 --- a/OsmAnd/res/values-sr/strings.xml +++ b/OsmAnd/res/values-sr/strings.xml @@ -1604,7 +1604,7 @@ Просек %1$d од %2$d Успон/Спуст - Време кретања + Време у покрету Макс/Мин Мин/Макс Туре @@ -3861,7 +3861,7 @@ Спорт Хитна помоћ Путовање - Треба да додате најмање две тачке + Додајте најмање две тачке Пријавите се на OpenStreetMap.org Пријавите се на OpenStreetMap.org Пријавите се помоћу ОпенСтритМап @@ -3979,4 +3979,13 @@ Сегмент %1$d Отпремљено %1$d од %2$d Одаберите измене за отпремање + Подврста + Возило + Бицикл + Аутомобил + Празно + Уреди путању + Преименуј путању + Сачувај и настави + Сви несачувани подаци ће бити изгубљени. \ No newline at end of file From 53106fd8e2eee9d5d40a021c5285a34a0ac7392c Mon Sep 17 00:00:00 2001 From: Ajeje Brazorf Date: Sun, 28 Mar 2021 16:37:49 +0000 Subject: [PATCH 067/109] Translated using Weblate (Sardinian) Currently translated at 99.2% (3669 of 3695 strings) --- OsmAnd/res/values-sc/strings.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sc/strings.xml b/OsmAnd/res/values-sc/strings.xml index f2fdc6c6d8..c11864da5a 100644 --- a/OsmAnd/res/values-sc/strings.xml +++ b/OsmAnd/res/values-sc/strings.xml @@ -844,7 +844,7 @@ Domo Amigos Logos - Àteru + Àteros Nùmene Categoria No, gràtzias @@ -4042,4 +4042,8 @@ Ischerta un\'àtera casta de coloratzione. Còmporas Distàntzia pro tocu + Sarva e sighi + Totu sos datos non sarvados s\'ant a pèrdere. + Ammustra su diàlogu de incumintzu + Dislinda unu colore pro sa modalidade pro sa mapa: %1$s. \ No newline at end of file From a557c6f2fc2a1896e5933e9fe85836fe3a3839c1 Mon Sep 17 00:00:00 2001 From: Hierax Swiftwing Date: Sun, 28 Mar 2021 13:55:23 +0000 Subject: [PATCH 068/109] Translated using Weblate (Serbian) Currently translated at 97.4% (3795 of 3894 strings) --- OsmAnd/res/values-sr/phrases.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values-sr/phrases.xml b/OsmAnd/res/values-sr/phrases.xml index f261e4e3f9..fae32d16dc 100644 --- a/OsmAnd/res/values-sr/phrases.xml +++ b/OsmAnd/res/values-sr/phrases.xml @@ -3863,4 +3863,8 @@ Сирена Медицинска сестра Мобилни агент за новац + Језеро + Река + Цепљење: Ковид 19 + Цепљење \ No newline at end of file From aa7e75bc4a3473df054cfc155ee7c523f7406a94 Mon Sep 17 00:00:00 2001 From: Hinagiku Zeppeki Date: Mon, 29 Mar 2021 01:37:06 +0000 Subject: [PATCH 069/109] Translated using Weblate (Japanese) Currently translated at 98.5% (3643 of 3695 strings) --- OsmAnd/res/values-ja/strings.xml | 92 +++++++++++++++++++------------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/OsmAnd/res/values-ja/strings.xml b/OsmAnd/res/values-ja/strings.xml index 212dfab6fe..8e969c342f 100644 --- a/OsmAnd/res/values-ja/strings.xml +++ b/OsmAnd/res/values-ja/strings.xml @@ -556,7 +556,7 @@ POIの更新は利用できません %1$d ファイルが残っています あと%1$d個のファイルがダウンロード可能です フルバージョン - ルートをキャンセル + ルートを破棄しますか? ナビゲーションの停止 選択した目的地、経由地点を削除します、よろしいですか? Wi-Fiに接続されていません。現在の接続を利用してインターネットからダウンロードを行いますか? @@ -1941,7 +1941,7 @@ POIの更新は利用できません 進行方向を振動で示して案内します。 OsmAnd Live更新でのナビゲーションを有効化します。 OsmAnd Liveナビゲーション - 目的地が設定されていません + アクセシビリティプラグイン: ターゲットが設定されていません 指定の道を外れた後にルート再計算を行わない 反対方向へ向かった場合ルートを変更しない ルートと反対方向に移動しても、自動的にルートの再計算をしないようにします。 @@ -2294,13 +2294,20 @@ POIの更新は利用できません  • GPX経路情報をアプリから直接OSMにアップロードできます  • POIを追加してOSMに直接アップロードできます(オフラインの場合は後で行うことができます) " - OsmAndはオープンソースで積極的に開発されています。バグを報告したり、翻訳を改善したり、新しい機能をコーディングすることで、誰もがアプリケーションの開発に貢献できます。このような開発者とユーザーとのやりとりによって、プロジェクトは継続的に改善されています。プロジェクトの進捗状況は、資金調達と新しい機能のテストに大きく左右されます。 -\n -\n地図のおおよそのエリアとその品質(※注 *の数が多いほど充実しています): -\n • 西ヨーロッパ: ****  • 東ヨーロッパ: ***  • ロシア: ***  • 北アメリカ: ***  • 南アメリカ: **  • アジア: **  • 日本、韓国: ***  • 中東: **  • アフリカ: **  • 南極: * -\n -\n 世界中のほとんどの国の地図がダウンロード可能です! -\n フランス、ドイツ、メキシコ、イギリス、スペイン、オランダ、アメリカ、ロシア、ブラジルなどの国の便利なナビゲーターを入手しましょう。 + OsmAndはオープンソースで現在も積極的に開発されています。バグを報告したり、翻訳を改善したり、新機能をコーディングしたりすることで、誰もがアプリの開発に貢献できます。またこのプロジェクトは、新機能のコーディングとテストに要する金銭面での貢献によっても支えられています。 +\n地図のおおよその範囲と品質(※注 *の数が多いほど内容が充実しています): +\n• 西ヨーロッパ:**** +\n• 東ヨーロッパ:*** +\n• ロシア:*** +\n• 北アメリカ:*** +\n• 南アメリカ:** +\n• アジア:** +\n• 日本、韓国:*** +\n• 中東:** +\n• アフリカ:** +\n• 南極大陸:* +\n世界中のほとんどの国がダウンロード可能です! +\nフランス、ドイツ、メキシコ、イギリス、スペイン、オランダ、アメリカ、ロシア、ブラジルなど、各国において頼りとなるナビゲーターを手に入れましょう。 OsmAnd(OSM Automated Navigation Directions~自動ナビ案内)は、『無償利用可、ワールドワイド対応、高品質のOSM』データを使用した、地図&ナビゲーションアプリです。 \n音声と視覚による案内、POI(Point Of Interest~興味的地点)表示、GPX経路の作成と管理、等高線を使った地形情報(要プラグイン)、ドライブ、サイクリング、徒歩移動各移動手段別のモード、OSMの編集等々に対応。 \n OsmAnd+は有料のアプリケーションです。購入することで同プロジェクトの資金、新機能開発への援助となり、最新アップデートも利用可能になります。 @@ -2347,7 +2354,7 @@ POIの更新は利用できません マップ画面でのOSMメモの表示/非表示を切り替えるボタンです。 距離順で並べ替え お気に入りで検索 - 標高の高低をグラデーション表示するには、陰影起伏図(Hillshade Overlay)マップのダウンロードが必要です。 + 標高の高低をグラデーション表示するには、\'Hillshade(陰影起伏図)\'マップのダウンロードが必要です。 等高線プラグイン『Contour lines plugin — OsmAnd』をインストールすることで、陰影起伏図(高低差を陰影で表したもの)をマップ上に表示できます。 ズームレベルを非表示 この地域用の等高線マップをダウンロードします。 @@ -2369,20 +2376,20 @@ POIの更新は利用できません 検索範囲を拡大 再検索 配色 - " 地図のおおよそのエリアとその品質(※注 *の数が多いほど充実しています): -\n • 西ヨーロッパ: **** -\n • 東ヨーロッパ: *** -\n • ロシア: *** -\n • 北米: *** -\n • 南アメリカ: ** -\n • アジア: ** -\n • 日本、韓国: *** -\n • 中東: ** -\n • アフリカ: ** -\n • 南極: * -\n -\n 世界中のほとんどの国の地図がダウンロード可能です! -\n アフガニスタンからジンバブエ、オーストラリアからアメリカ、 アルゼンチン、ブラジル、カナダ、フランス、ドイツ、メキシコ、イギリス、スペイン、... " + 地図のおおよその範囲と品質:(※注 *の数が多いほど内容が充実しています): +\n• 西ヨーロッパ:**** +\n• 東ヨーロッパ:*** +\n• ロシア:*** +\n• 北アメリカ:*** +\n• 南アメリカ: ** +\n• アジア:** +\n• 日本、韓国:*** +\n• 中東:** +\n•アフリカ:** +\n•南極大陸:* +\n世界中のほとんどの国がダウンロード可能です! +\nアフガニスタンからジンバブエへ、オーストラリアからアメリカへも…またアルゼンチン、ブラジル、カナダ、フランス、ドイツ、メキシコ、イギリス、スペイン等々… +\n " 直接OSMに寄与 • データ、バグの報告ができます @@ -2812,7 +2819,7 @@ POIの更新は利用できません By OsmAnd プランと料金 月間 - 3ヶ月間 + 3ヶ月毎 年間 %1$s / 月 %1$.2f %2$s / 月 @@ -3489,9 +3496,9 @@ POIの更新は利用できません 四角形 最小 マップ内公共交通機関の表示/非表示を切り替えるボタンです。 - POIの作成/編集 + POIの作成・編集 駐車位置 - お気に入りの追加/編集 + お気に入りの追加・編集 アイテム順序を初期状態に戻します 編集に戻る 選択したプロファイルを切り替えるボタンです。 @@ -3518,7 +3525,7 @@ POIの更新は利用できません %1$s / %2$s お支払いは、購入の確認後にGoogle Playアカウントに請求されます。 \n -\nサブスクリプションは更新日より前にキャンセルしない限り、自動的に更新されます。アカウントの更新期間(月/ 3ヶ月/年)に準じた更新日に請求されます。 +\nサブスクリプションは更新日前にキャンセルしない限り、自動的に延長されます。アカウントには更新日に更新期間(月/ 3ヶ月/年)に応じた金額が請求されます。 \n \nサブスクリプションの管理およびキャンセルはGoogle Playの設定からおこなえます。 POIのタイプで検索 @@ -3661,7 +3668,7 @@ POIの更新は利用できません 車高を入力してください。一部のルートにおいては、車高の高い車両では通行できない場合があります。 車両の重量を入力してください。一部のルートにおいては、大型車両では通行できない場合があります。 車の長さを入力してください。一部のルートにおいては、長い車両では通行できない場合があります。 - 常に + 常時 画面の制御 現在無効。 \'画面を表示する時間\'の下にある\'画面を常に表示\'への設定が必要です。 画面オフを維持 @@ -3725,9 +3732,9 @@ POIの更新は利用できません インラインスケート 最も近い目的地を削除 地点の名前を入力してください - ルート上の現在の目的地点が削除されます。目的地に着いた場合はナビは停止します。 + ルート上の次の目的地を削除します。それが最終目的地の場合は、ナビゲーションが停止します。 Wikipediaマップのダウンロード - Wikipediaから興味のあるポイントに関する情報を取得します。それがあなたのモバイルオフラインガイドになります - Wikipediaプラグインを有効にして、周囲の名所に関する記事を楽しんでください。 + 場所や目的地に関する記事が掲載されたWikipediaのオフラインポケットガイドを活用し、ランドマークや観光名所の詳しい情報を入手しましょう。 追加した地点はマップ上に表示されません。選択したグループは非表示になっているため、\"%s\"から見つけることができます。 新しい経路ファイルとして保存 経路ファイルを追加 @@ -3762,8 +3769,8 @@ POIの更新は利用できません 次年度以降 %1$s 初%2$s度 %1$s 初%2$s度 %1$s - ルート記録を一時停止 - ルート記録を続行 + 旅程の記録を一時停止 + 旅程の記録を続行 システムのデフォルト 以後のすべてのセグメントは、選択したプロファイルを使用して再計算されます。 以後のすべてのセグメント @@ -3794,7 +3801,7 @@ POIの更新は利用できません %s個の経路ファイルが選択されました ファイル名 (最近使用したアプリを介して) OsmAndを終了すると、GPXの記録が一時停止されます(バックグラウンドサービスインジケーターがAndroid通知バーから消えます。) - 一般的な経路記録の記録間隔を定義します(マップ画面の\'GPX\'ボタンを使用) + 一般的な経路記録の記録間隔を指定します(マップウィジェットの\'旅程の記録\'ボタンでONにします) 保存されました 最終更新日 名称: 降順(Z-A) @@ -4055,9 +4062,20 @@ POIの更新は利用できません 開始・終了アイコン \'等高線(Contour lines)\'をご購入いただきありがとうございます サブスクリプションは選択した期間に応じて課金されます。 AppGalleryからいつでもキャンセルできます。 - 購入確認後に利用者のAppGalleryアカウントへ請求されます。 + お支払いは、購入の確認後にAppGalleryアカウントへ請求されます。 \n -\nサブスクリプションは更新日前にキャンセルされない限り自動的に延長されます。アカウントには更新日に更新期間分(月/ 3ヶ月/年)の金額が請求されます。 +\nサブスクリプションは更新日前にキャンセルされない限り自動的に延長されます。アカウントには更新日に更新期間(月/ 3ヶ月/年)に応じた金額が請求されます。 \n -\nAppGallery設定でサブスクリプションの管理およびキャンセルができます。 +\nサブスクリプションの管理およびキャンセルはAppGalleryの設定からおこなえます。 + ドイツ語(話し言葉) + MGRS(Military Grid Reference System) + 新着情報 + スノーモービルレジャー用の専用道路や通路です。 + MGRS(Military Grid Reference System) + OsmAndは、UTM NATO形式類似のMGRSを使用します。 + 凡例 + %2$sの%1$s + 基本前進のみの車椅子 + 通常色 + 逆方向の場合 \ No newline at end of file From 8ceef9af42a25db1c092fe2ad03f5bfcb5f9e19b Mon Sep 17 00:00:00 2001 From: Ahmad Alfrhood Date: Mon, 29 Mar 2021 08:04:00 +0000 Subject: [PATCH 070/109] Translated using Weblate (Arabic) Currently translated at 100.0% (3695 of 3695 strings) --- OsmAnd/res/values-ar/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/res/values-ar/strings.xml b/OsmAnd/res/values-ar/strings.xml index d697e4909f..4cb4b38f94 100644 --- a/OsmAnd/res/values-ar/strings.xml +++ b/OsmAnd/res/values-ar/strings.xml @@ -1010,7 +1010,7 @@ المفضلة تم حفظها بنجاح إلى {0} لم يتم العثور على نقاط أماكن مفضلة للقيام بالاحتفاظ بها تم تعديل النقطة المفضلة - لا وجود لأية نقطة مفضلة + لا يوجد نقاط مفضلة تعديل المفضلة حذف المفضلة إزالة النقطة المفضلة \'%s\' ؟ @@ -3536,7 +3536,7 @@ مربع دائرة تحديد الشكل - تحديد المجموعة + تحديد مجموعة إضافة وصف حذف الوصف زر لإظهار طبقة التضاريس أو إخفائها على الخريطة. From 03a450f9e2bfd72303831f4ee9129ada47defc3e Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 12:49:11 +0300 Subject: [PATCH 071/109] WeakReference - mapActivity, import header --- .../MapRouteInfoMenuFragment.java | 22 +++++++++---------- .../osmand/plus/track/TrackMenuFragment.java | 6 +++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java index 8710c934dd..b60074f0b4 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/MapRouteInfoMenuFragment.java @@ -31,6 +31,8 @@ import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.track.TrackSelectSegmentBottomSheet; import net.osmand.plus.widgets.TextViewExProgress; +import static net.osmand.plus.track.TrackMenuFragment.startNavigationForGPX; + public class MapRouteInfoMenuFragment extends ContextMenuFragment implements TrackSelectSegmentBottomSheet.OnSegmentSelectedListener { public static final String TAG = MapRouteInfoMenuFragment.class.getName(); @@ -508,18 +510,16 @@ public class MapRouteInfoMenuFragment extends ContextMenuFragment implements Tra @Override public void onSegmentSelect(GPXUtilities.GPXFile gpxFile, int selectedSegment) { - if (getMyApplication() != null) { - getMyApplication().getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment); - MapActivity mapActivity = getMapActivity(); - if (mapActivity != null) { - TrackMenuFragment.startNavigationForGPX(gpxFile, mapActivity.getMapActions(), mapActivity); - GPXRouteParams.GPXRouteParamsBuilder paramsBuilder = getMyApplication().getRoutingHelper().getCurrentGPXRoute(); - if (paramsBuilder != null) { - paramsBuilder.setSelectedSegment(selectedSegment); - getMyApplication().getRoutingHelper().onSettingsChanged(true); - } - dismiss(); + MapActivity mapActivity = getMapActivity(); + if (mapActivity != null) { + mapActivity.getMyApplication().getSettings().GPX_ROUTE_SEGMENT.set(selectedSegment); + startNavigationForGPX(gpxFile, mapActivity.getMapActions(), mapActivity); + GPXRouteParams.GPXRouteParamsBuilder paramsBuilder = getMyApplication().getRoutingHelper().getCurrentGPXRoute(); + if (paramsBuilder != null) { + paramsBuilder.setSelectedSegment(selectedSegment); + getMyApplication().getRoutingHelper().onSettingsChanged(true); } + dismiss(); } } } \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index f5c52a11ce..b2d3aaa7dd 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -906,11 +906,13 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card public static void startNavigationForGPX(final GPXFile gpxFile, MapActivityActions mapActions, final MapActivity mapActivity) { if (mapActivity.getMyApplication().getRoutingHelper().isFollowingMode()) { + final WeakReference activityRef = new WeakReference<>(mapActivity); mapActions.stopNavigationActionConfirm(null, new Runnable() { @Override public void run() { - if (mapActivity != null) { - mapActivity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null, + MapActivity activity = activityRef.get(); + if (activity != null) { + activity.getMapActions().enterRoutePlanningModeGivenGpx(gpxFile, null, null, null, true, true, MenuState.HEADER_ONLY); } } From 78175e8a1cd269cb6609828d9e8bef237ee04294 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 13:39:36 +0300 Subject: [PATCH 072/109] Import header, storage path replace in UI display --- .../main/java/com/jwetherell/openmap/common/MGRSPoint.java | 4 ++-- .../plus/settings/datastorage/DataStorageFragment.java | 5 ++++- .../osmand/plus/settings/datastorage/DataStorageHelper.java | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java b/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java index be6793bef8..519fc9d171 100644 --- a/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java +++ b/OsmAnd-java/src/main/java/com/jwetherell/openmap/common/MGRSPoint.java @@ -699,8 +699,8 @@ public class MGRSPoint extends ZonedUTMPoint { String zero = ""; } - all.add(String.format(java.util.Locale.US,"%0" + accuracy + "d", roundedEasting)); - all.add(String.format(java.util.Locale.US,"%0" + accuracy + "d", roundedNorthing)); + all.add(String.format(Locale.US,"%0" + accuracy + "d", roundedEasting)); + all.add(String.format(Locale.US,"%0" + accuracy + "d", roundedNorthing)); break; } } diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java index 7fd96b8185..e25a4a6cc0 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java @@ -46,6 +46,7 @@ import java.util.ArrayList; import static net.osmand.plus.settings.datastorage.DataStorageHelper.INTERNAL_STORAGE; import static net.osmand.plus.settings.datastorage.DataStorageHelper.MANUALLY_SPECIFIED; import static net.osmand.plus.settings.datastorage.DataStorageHelper.OTHER_MEMORY; +import static net.osmand.plus.settings.datastorage.DataStorageHelper.SHARED_STORAGE; import static net.osmand.plus.settings.datastorage.DataStorageHelper.TILES_MEMORY; import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY; import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA; @@ -226,7 +227,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto int defaultIconColor = isNightMode() ? R.color.icon_color_default_dark : R.color.icon_color_default_light; int chosenIconColor = isNightMode() ? R.color.icon_color_osmand_dark : R.color.icon_color_osmand_light; - Drawable icon = app.getUIUtilities().getIcon(item.getIconResId(), + Drawable icon = app.getUIUtilities().getIcon(item.getIconResId(), isCurrent ? chosenIconColor : defaultIconColor); ivIcon.setImageDrawable(icon); @@ -249,6 +250,8 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } if (currentKey.equals(INTERNAL_STORAGE)) { tvAdditionalDescription.setText(item.getDescription()); + } else if(currentKey.equals(SHARED_STORAGE)){ + tvAdditionalDescription.setText(String.format("\u200E%s", item.getDirectory())); } else { tvAdditionalDescription.setText(item.getDirectory()); } diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java index b292a02e0d..67fd73897e 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageHelper.java @@ -106,7 +106,7 @@ public class DataStorageHelper { //shared storage dir = settings.getDefaultInternalStorage(); - path = "\u200e" + dir.getAbsolutePath(); + path = dir.getAbsolutePath(); iconId = R.drawable.ic_action_phone; StorageItem sharedStorageItem = StorageItem.builder() From 6ba23e6a3c7e8f889600e12e05ca4fa3344469a2 Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 14:03:05 +0300 Subject: [PATCH 073/109] some fixes; --- OsmAnd/res/values/strings.xml | 2 +- .../plus/activities/LocalIndexInfo.java | 66 +++++++++++++++++- .../download/ui/UpdatesIndexFragment.java | 2 +- .../plus/liveupdates/LiveUpdatesFragment.java | 67 ++++++++++--------- .../LiveUpdatesUpdateAllBottomSheet.java | 38 ++++++----- .../PerformLiveUpdateAsyncTask.java | 3 +- 6 files changed, 122 insertions(+), 56 deletions(-) diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5311d58c27..dbb0c79fd6 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,7 +12,7 @@ --> - Update all maps added to \"OsmAnd Live\"? + Update all maps added to %1$s? • OsmAnd Live updates moved to \"Downloads > Updates\"\n\n • Tracks now could be colorizing by altitude, speed, or slope.\n\n diff --git a/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java b/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java index 4b9c8fa3ac..753e0af019 100644 --- a/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java +++ b/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java @@ -1,5 +1,8 @@ package net.osmand.plus.activities; +import android.os.Parcel; +import android.os.Parcelable; + import androidx.annotation.NonNull; import net.osmand.GPXUtilities.GPXFile; @@ -7,8 +10,9 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType; import java.io.File; +import java.io.Serializable; -public class LocalIndexInfo implements Comparable { +public class LocalIndexInfo implements Comparable, Parcelable { private LocalIndexType type; private String description = ""; @@ -43,6 +47,22 @@ public class LocalIndexInfo implements Comparable { this.backupedData = backuped; } + protected LocalIndexInfo(Parcel in) { + readFromParcel(in); + } + + public static final Creator CREATOR = new Creator() { + @Override + public LocalIndexInfo createFromParcel(Parcel in) { + return new LocalIndexInfo(in); + } + + @Override + public LocalIndexInfo[] newArray(int size) { + return new LocalIndexInfo[size]; + } + }; + public void setAttachedObject(Object attachedObject) { this.attachedObject = attachedObject; } @@ -176,4 +196,46 @@ public class LocalIndexInfo implements Comparable { public int compareTo(LocalIndexInfo o) { return getFileName().compareTo(o.getFileName()); } -} \ No newline at end of file + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeSerializable(type); + dest.writeString(description); + dest.writeString(name); + dest.writeByte((byte) (backupedData ? 1 : 0)); + dest.writeByte((byte) (corrupted ? 1 : 0)); + dest.writeByte((byte) (notSupported ? 1 : 0)); + dest.writeByte((byte) (loaded ? 1 : 0)); + dest.writeString(subfolder); + dest.writeString(pathToData); + dest.writeString(fileName); + dest.writeByte((byte) (singleFile ? 1 : 0)); + dest.writeInt(kbSize); + dest.writeSerializable((Serializable) attachedObject); + dest.writeByte((byte) (expanded ? 1 : 0)); + dest.writeValue(gpxFile); + } + + private void readFromParcel(Parcel in) { + type = (LocalIndexType) in.readSerializable(); + description = in.readString(); + name = in.readString(); + backupedData = in.readByte() != 0; + corrupted = in.readByte() != 0; + notSupported = in.readByte() != 0; + loaded = in.readByte() != 0; + subfolder = in.readString(); + pathToData = in.readString(); + fileName = in.readString(); + singleFile = in.readByte() != 0; + kbSize = in.readInt(); + attachedObject = in.readSerializable(); + expanded = in.readByte() != 0; + gpxFile = (GPXFile) in.readSerializable(); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index 12fe4f6f95..89eb840cb8 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -399,7 +399,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download public void onClick(View v) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { showUpdateDialog(getActivity(), getFragmentManager(), - listAdapter.mapsList, listAdapter.countEnabled, null); + settings, listAdapter.mapsList, null); } } }); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index a669b919ed..1ba3a06563 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -170,8 +170,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL @Override public void onRefresh() { if (settings.IS_LIVE_UPDATES_ON.get()) { - showUpdateDialog(getActivity(), getFragmentManager(), adapter.mapsList, - adapter.countEnabled, liveUpdateListener); + showUpdateDialog(getActivity(), getFragmentManager(), settings, adapter.mapsList, liveUpdateListener); startUpdateDateAsyncTask(); } swipeRefresh.setRefreshing(false); @@ -262,9 +261,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL Toolbar toolbar = (Toolbar) appBarLayout.findViewById(R.id.toolbar); TextViewEx toolbarTitle = (TextViewEx) toolbar.findViewById(R.id.toolbar_title); toolbarTitle.setText(R.string.osm_live); - int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; - Drawable icBack = app.getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(app), iconColorResId); - DrawableCompat.setTint(icBack, ContextCompat.getColor(app, iconColorResId)); View closeButton = toolbar.findViewById(R.id.close_button); closeButton.setOnClickListener(new View.OnClickListener() { @@ -275,6 +271,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL }); FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button); + int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light; AppCompatImageButton iconHelp = toolbar.findViewById(R.id.action_button_icon); Drawable helpDrawable = app.getUIUtilities().getIcon(R.drawable.ic_action_help_online, iconColorResId); iconHelp.setImageDrawable(helpDrawable); @@ -329,18 +326,19 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL private void switchOnLiveUpdates() { settings.IS_LIVE_UPDATES_ON.set(true); enableLiveUpdates(true); - showUpdateDialog(getMyActivity(), getFragmentManager(), adapter.mapsList, adapter.countEnabled, liveUpdateListener); + showUpdateDialog(getMyActivity(), getFragmentManager(), settings, adapter.mapsList, liveUpdateListener); startUpdateDateAsyncTask(); } - public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, List mapsList, - int countEnabled, @Nullable LiveUpdateListener listener) { + public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, OsmandSettings settings, + List mapsList, @Nullable LiveUpdateListener listener) { if (!Algorithms.isEmpty(mapsList)) { + int countEnabled = updateCountEnabled(null, mapsList, settings); if (countEnabled == 1) { LocalIndexInfo li = mapsList.get(0); runLiveUpdate(context, li.getFileName(), false, listener); } else if (countEnabled > 1) { - LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, mapsList, listener); + LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, getMapsToUpdate(mapsList, settings), listener); } } } @@ -348,22 +346,20 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL private void enableLiveUpdates(boolean enable) { if (!Algorithms.isEmpty(adapter.mapsList)) { AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); - for (LocalIndexInfo li : adapter.mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - String fileName = li.getFileName(); - PendingIntent alarmIntent = getPendingIntent(app, fileName); - if (enable) { - final CommonPreference updateFrequencyPreference = - preferenceUpdateFrequency(fileName, settings); - final CommonPreference timeOfDayPreference = - preferenceTimeOfDayToUpdate(fileName, settings); - UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; - TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; - setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); - } else { - alarmMgr.cancel(alarmIntent); - } + List mapsToUpdate = getMapsToUpdate(adapter.mapsList, settings); + for (LocalIndexInfo li : mapsToUpdate) { + String fileName = li.getFileName(); + PendingIntent alarmIntent = getPendingIntent(app, fileName); + if (enable) { + final CommonPreference updateFrequencyPreference = + preferenceUpdateFrequency(fileName, settings); + final CommonPreference timeOfDayPreference = + preferenceTimeOfDayToUpdate(fileName, settings); + UpdateFrequency updateFrequency = UpdateFrequency.values()[updateFrequencyPreference.get()]; + TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDayPreference.get()]; + setAlarmForPendingIntent(alarmIntent, alarmMgr, updateFrequency, timeOfDayToUpdate); + } else { + alarmMgr.cancel(alarmIntent); } } } @@ -375,21 +371,26 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL } } - public static int updateCountEnabled(TextView countView, ArrayList mapsList, OsmandSettings settings) { - int countEnabled = 0; + public static int updateCountEnabled(TextView countView, List mapsList, OsmandSettings settings) { + int countEnabled = getMapsToUpdate(mapsList, settings).size(); if (countView != null) { - for (LocalIndexInfo map : mapsList) { - CommonPreference preference = preferenceForLocalIndex(map.getFileName(), settings); - if (preference.get()) { - countEnabled++; - } - } String countText = countEnabled + "/" + mapsList.size(); countView.setText(countText); } return countEnabled; } + public static List getMapsToUpdate(List mapsList, OsmandSettings settings) { + List listToUpdate = new ArrayList<>(); + for (LocalIndexInfo mapToUpdate : mapsList) { + CommonPreference preference = preferenceForLocalIndex(mapToUpdate.getFileName(), settings); + if (preference.get()) { + listToUpdate.add(mapToUpdate); + } + } + return listToUpdate; + } + protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { private final ArrayList mapsList = new ArrayList<>(); private int countEnabled = 0; diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java index ace4abac20..9357210328 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java @@ -1,6 +1,7 @@ package net.osmand.plus.liveupdates; import android.os.Bundle; +import android.os.Parcelable; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -11,7 +12,6 @@ import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; -import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.UiUtilities.DialogButtonType; import net.osmand.plus.activities.LocalIndexInfo; @@ -20,25 +20,22 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem; import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; -import net.osmand.plus.settings.backend.CommonPreference; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.TextViewEx; import org.apache.commons.logging.Log; +import java.util.ArrayList; import java.util.List; import static net.osmand.AndroidUtils.getPrimaryTextColorId; -import static net.osmand.plus.liveupdates.LiveUpdatesHelper.preferenceForLocalIndex; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragment { public static final String TAG = LiveUpdatesUpdateAllBottomSheet.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(LiveUpdatesUpdateAllBottomSheet.class); - - private OsmandApplication app; - private OsmandSettings settings; + private static final String MAPS_TO_UPDATE = "maps_to_update"; + private static final String LIVE_UPDATE_LISTENER = "live_update_listener"; private BaseBottomSheetItem itemTitle; private BaseBottomSheetItem itemDescription; @@ -66,8 +63,10 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme @Override public void createMenuItems(Bundle savedInstanceState) { - app = getMyApplication(); - settings = app.getSettings(); + if (savedInstanceState != null) { + mapsList = savedInstanceState.getParcelableArrayList(MAPS_TO_UPDATE); + listener = (LiveUpdateListener) savedInstanceState.getSerializable(LIVE_UPDATE_LISTENER); + } updateBottomButtons(); @@ -78,8 +77,9 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme .create(); items.add(itemTitle); + String osmAndLive = "\"" + getString(R.string.osm_live) + "\""; itemDescription = new LongDescriptionItem.Builder() - .setDescription(getString(R.string.live_update_all_maps)) + .setDescription(getString(R.string.update_all_maps_added, osmAndLive)) .setDescriptionMaxLines(5) .setDescriptionColorId(getPrimaryTextColorId(nightMode)) .setLayoutId(R.layout.bottom_sheet_item_description_long) @@ -97,14 +97,17 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme return view; } + @Override + @SuppressWarnings("unchecked") + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(MAPS_TO_UPDATE, (ArrayList) mapsList); + outState.putSerializable(LIVE_UPDATE_LISTENER, listener); + } + private void updateAll() { - if (settings != null) { - for (LocalIndexInfo li : mapsList) { - CommonPreference localUpdateOn = preferenceForLocalIndex(li.getFileName(), settings); - if (localUpdateOn.get()) { - runLiveUpdate(getActivity(), li.getFileName(), false, listener); - } - } + for (LocalIndexInfo li : mapsList) { + runLiveUpdate(getActivity(), li.getFileName(), false, listener); } } @@ -128,5 +131,4 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme protected DialogButtonType getRightBottomButtonType() { return DialogButtonType.PRIMARY; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java index 07e533640b..d60470107d 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java @@ -25,6 +25,7 @@ import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; +import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -48,7 +49,7 @@ public class PerformLiveUpdateAsyncTask private final boolean userRequested; private final LiveUpdateListener listener; - public interface LiveUpdateListener { + public interface LiveUpdateListener extends Serializable { void processFinish(); } From a77362c5e013536a112862cb18327265bc17b523 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 14:43:14 +0300 Subject: [PATCH 074/109] BidiFormatter --- .../datastorage/DataStorageFragment.java | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java index e25a4a6cc0..41c58ebd7f 100644 --- a/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/datastorage/DataStorageFragment.java @@ -6,7 +6,9 @@ import android.content.Context; import android.content.DialogInterface; import android.graphics.drawable.Drawable; import android.os.AsyncTask; +import android.os.Build; import android.os.Bundle; +import android.text.BidiFormatter; import android.view.View; import android.widget.ImageView; import android.widget.TextView; @@ -24,12 +26,12 @@ import androidx.preference.PreferenceViewHolder; import net.osmand.AndroidUtils; import net.osmand.FileUtils; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.UiUtilities; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandActionBarActivity; import net.osmand.plus.download.DownloadActivity; +import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet; import net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet; import net.osmand.plus.settings.datastorage.item.MemoryItem; @@ -43,20 +45,20 @@ import java.io.File; import java.text.DecimalFormat; import java.util.ArrayList; +import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY; +import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA; +import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.NEW_PATH; +import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.PATH_CHANGED; import static net.osmand.plus.settings.datastorage.DataStorageHelper.INTERNAL_STORAGE; import static net.osmand.plus.settings.datastorage.DataStorageHelper.MANUALLY_SPECIFIED; import static net.osmand.plus.settings.datastorage.DataStorageHelper.OTHER_MEMORY; import static net.osmand.plus.settings.datastorage.DataStorageHelper.SHARED_STORAGE; import static net.osmand.plus.settings.datastorage.DataStorageHelper.TILES_MEMORY; -import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY; -import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA; -import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.NEW_PATH; -import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.PATH_CHANGED; public class DataStorageFragment extends BaseSettingsFragment implements DataStorageHelper.UpdateMemoryInfoUIAdapter { public final static int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 500; public final static int UI_REFRESH_TIME_MS = 500; - + private final static String CHANGE_DIRECTORY_BUTTON = "change_directory"; private final static String OSMAND_USAGE = "osmand_usage"; @@ -68,7 +70,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto private String tmpManuallySpecifiedPath; private DataStorageHelper dataStorageHelper; private boolean calculateTilesBtnPressed; - + private RefreshUsedMemoryTask calculateMemoryTask; private RefreshUsedMemoryTask calculateTilesMemoryTask; @@ -85,10 +87,10 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } super.onCreate(savedInstanceState); } - + @Override protected void setupPreferences() { - + PreferenceScreen screen = getPreferenceScreen(); if (screen == null || dataStorageHelper == null) { @@ -203,13 +205,13 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto int primaryTextColorResId = isNightMode() ? R.color.text_color_primary_dark : R.color.text_color_primary_light; int primaryTextColor = ContextCompat.getColor(app, primaryTextColorResId); - String[] memoryUnitsFormats = new String[] { + String[] memoryUnitsFormats = new String[]{ getString(R.string.shared_string_memory_kb_desc), getString(R.string.shared_string_memory_mb_desc), getString(R.string.shared_string_memory_gb_desc), getString(R.string.shared_string_memory_tb_desc) }; - + final View itemView = holder.itemView; if (preference instanceof CheckBoxPreference) { StorageItem item = dataStorageHelper.getStorage(key); @@ -250,8 +252,13 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto } if (currentKey.equals(INTERNAL_STORAGE)) { tvAdditionalDescription.setText(item.getDescription()); - } else if(currentKey.equals(SHARED_STORAGE)){ - tvAdditionalDescription.setText(String.format("\u200E%s", item.getDirectory())); + } else if (currentKey.equals(SHARED_STORAGE)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + BidiFormatter rtlFormatter = BidiFormatter.getInstance(); + tvAdditionalDescription.setText(rtlFormatter.unicodeWrap(item.getDirectory())); + } else { + tvAdditionalDescription.setText(String.format("\u200E%s", item.getDirectory())); + } } else { tvAdditionalDescription.setText(item.getDirectory()); } @@ -264,7 +271,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto AndroidUtils.setBackground(itemView, drawable); icon.setVisibility(View.INVISIBLE); title.setText(R.string.shared_string_change); - } else if(key.equals(OSMAND_USAGE)) { + } else if (key.equals(OSMAND_USAGE)) { long totalUsageBytes = dataStorageHelper.getTotalUsedBytes(); TextView tvSummary = itemView.findViewById(R.id.summary); tvSummary.setText(DataStorageHelper.getFormattedMemoryInfo(totalUsageBytes, memoryUnitsFormats)); @@ -427,7 +434,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto refreshDataInfo(); updateAllSettings(); } - + private void refreshDataInfo() { calculateTilesBtnPressed = false; dataStorageHelper = new DataStorageHelper(app); @@ -463,7 +470,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto public void onMemoryInfoUpdate() { updateAllSettings(); } - + @Override public void onFinishUpdating(String tag) { updateAllSettings(); From d190da742acd61d226dfe25b24b2b29cd1786136 Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 29 Mar 2021 18:13:56 +0500 Subject: [PATCH 075/109] Huawei fix and small corrections --- .../osmand/plus/inapp/InAppPurchasesImpl.java | 5 +++++ .../settings/fragments/PurchasesFragment.java | 16 ++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java index 4ed0021b6f..59d97daed0 100644 --- a/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java +++ b/OsmAnd/src-huawei/net/osmand/plus/inapp/InAppPurchasesImpl.java @@ -165,6 +165,11 @@ public class InAppPurchasesImpl extends InAppPurchases { this.info = info; } + @Override + public int getPeriodTypeString() { + return R.string.monthly_subscription; + } + @Override public String getDefaultPrice(Context ctx) { return ""; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java index d08cf6f892..e3bbb85f04 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/PurchasesFragment.java @@ -46,13 +46,12 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha private static final String OSMAND_PURCHASES_URL = "https://docs.osmand.net/en/main@latest/osmand/purchases"; private OsmandApplication app; - private Context context; private InAppPurchaseHelper purchaseHelper; - private View mainView; - ViewGroup cardsContainer; + private ViewGroup cardsContainer; private SubscriptionsCard subscriptionsCard; + private boolean nightMode; private Boolean isPaidVersion; public static boolean showInstance(FragmentManager fragmentManager) { @@ -77,12 +76,11 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { app = getMyApplication(); - context = requireContext(); isPaidVersion = Version.isPaidVersion(app); - final boolean nightMode = !app.getSettings().isLightContent(); - LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode); + nightMode = !app.getSettings().isLightContent(); + LayoutInflater themedInflater = UiUtilities.getInflater(getContext(), nightMode); - mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); + View mainView = themedInflater.inflate(R.layout.purchases_layout, container, false); AndroidUtils.addStatusBarPadding21v(getActivity(), mainView); createToolbar(mainView, nightMode); cardsContainer = mainView.findViewById(R.id.cards_container); @@ -148,7 +146,9 @@ public class PurchasesFragment extends BaseOsmAndFragment implements InAppPurcha icon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - WikipediaDialogFragment.showFullArticle(context, Uri.parse(OSMAND_PURCHASES_URL), nightMode); + if (getContext() != null) { + WikipediaDialogFragment.showFullArticle(getContext(), Uri.parse(OSMAND_PURCHASES_URL), nightMode); + } } }); ImageButton backButton = toolbar.findViewById(R.id.close_button); From 7115368dd4962e6b79ed6d8f36155549afe25cec Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 16:38:08 +0300 Subject: [PATCH 076/109] fix manual update process; --- .../plus/activities/LocalIndexInfo.java | 66 +------------- .../download/ui/UpdatesIndexFragment.java | 23 +++-- .../liveupdates/LiveUpdatesAlarmReceiver.java | 3 +- .../plus/liveupdates/LiveUpdatesFragment.java | 89 +++++++++---------- .../plus/liveupdates/LiveUpdatesHelper.java | 29 +++++- .../LiveUpdatesSettingsBottomSheet.java | 8 ++ .../LiveUpdatesUpdateAllBottomSheet.java | 45 ++-------- .../PerformLiveUpdateAsyncTask.java | 25 ++---- 8 files changed, 116 insertions(+), 172 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java b/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java index 753e0af019..4b9c8fa3ac 100644 --- a/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java +++ b/OsmAnd/src/net/osmand/plus/activities/LocalIndexInfo.java @@ -1,8 +1,5 @@ package net.osmand.plus.activities; -import android.os.Parcel; -import android.os.Parcelable; - import androidx.annotation.NonNull; import net.osmand.GPXUtilities.GPXFile; @@ -10,9 +7,8 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType; import java.io.File; -import java.io.Serializable; -public class LocalIndexInfo implements Comparable, Parcelable { +public class LocalIndexInfo implements Comparable { private LocalIndexType type; private String description = ""; @@ -47,22 +43,6 @@ public class LocalIndexInfo implements Comparable, Parcelable { this.backupedData = backuped; } - protected LocalIndexInfo(Parcel in) { - readFromParcel(in); - } - - public static final Creator CREATOR = new Creator() { - @Override - public LocalIndexInfo createFromParcel(Parcel in) { - return new LocalIndexInfo(in); - } - - @Override - public LocalIndexInfo[] newArray(int size) { - return new LocalIndexInfo[size]; - } - }; - public void setAttachedObject(Object attachedObject) { this.attachedObject = attachedObject; } @@ -196,46 +176,4 @@ public class LocalIndexInfo implements Comparable, Parcelable { public int compareTo(LocalIndexInfo o) { return getFileName().compareTo(o.getFileName()); } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeSerializable(type); - dest.writeString(description); - dest.writeString(name); - dest.writeByte((byte) (backupedData ? 1 : 0)); - dest.writeByte((byte) (corrupted ? 1 : 0)); - dest.writeByte((byte) (notSupported ? 1 : 0)); - dest.writeByte((byte) (loaded ? 1 : 0)); - dest.writeString(subfolder); - dest.writeString(pathToData); - dest.writeString(fileName); - dest.writeByte((byte) (singleFile ? 1 : 0)); - dest.writeInt(kbSize); - dest.writeSerializable((Serializable) attachedObject); - dest.writeByte((byte) (expanded ? 1 : 0)); - dest.writeValue(gpxFile); - } - - private void readFromParcel(Parcel in) { - type = (LocalIndexType) in.readSerializable(); - description = in.readString(); - name = in.readString(); - backupedData = in.readByte() != 0; - corrupted = in.readByte() != 0; - notSupported = in.readByte() != 0; - loaded = in.readByte() != 0; - subfolder = in.readString(); - pathToData = in.readString(); - fileName = in.readString(); - singleFile = in.readByte() != 0; - kbSize = in.readInt(); - attachedObject = in.readSerializable(); - expanded = in.readByte() != 0; - gpxFile = (GPXFile) in.readSerializable(); - } - - @Override - public int describeContents() { - return 0; - } -} +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index 89eb840cb8..1dbd8782ba 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -29,6 +29,7 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.cardview.widget.CardView; import androidx.core.content.ContextCompat; import androidx.core.view.MenuItemCompat; +import androidx.fragment.app.Fragment; import net.osmand.AndroidUtils; import net.osmand.Collator; @@ -40,6 +41,7 @@ import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; import net.osmand.plus.liveupdates.LiveUpdatesFragment; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.liveupdates.LoadLiveMapsTask; import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; import net.osmand.plus.chooseplan.ChoosePlanDialogFragment.ChoosePlanDialogType; @@ -52,7 +54,6 @@ import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents; import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.IndexItem; import net.osmand.plus.inapp.InAppPurchaseHelper; -import net.osmand.plus.widgets.TextViewEx; import net.osmand.util.Algorithms; import java.util.ArrayList; @@ -62,7 +63,7 @@ import java.util.List; import static net.osmand.plus.liveupdates.LiveUpdatesFragment.showUpdateDialog; import static net.osmand.plus.liveupdates.LiveUpdatesFragment.updateCountEnabled; -public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates { +public class UpdatesIndexFragment extends OsmAndListFragment implements DownloadEvents, RefreshLiveUpdates, LiveUpdateListener { private static final int RELOAD_ID = 5; private UpdateIndexAdapter listAdapter; private String errorMessage; @@ -398,8 +399,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download @Override public void onClick(View v) { if (!listAdapter.isShowOsmLivePurchaseBanner()) { - showUpdateDialog(getActivity(), getFragmentManager(), - settings, listAdapter.mapsList, null); + showUpdateDialog(getActivity(), getFragmentManager(), UpdatesIndexFragment.this); } } }); @@ -417,9 +417,22 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download } } + @Override + public void processFinish() { + } + + @Override + public List getMapsToUpdate() { + return LiveUpdatesFragment.getMapsToUpdate(listAdapter.mapsList, settings); + } + + @Override + public Fragment currentFragment() { + return this; + } + @ColorRes public static int getDefaultIconColorId(boolean nightMode) { return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java index 78d84bf220..a51140fbab 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesAlarmReceiver.java @@ -32,7 +32,8 @@ public class LiveUpdatesAlarmReceiver extends BroadcastReceiver { final OsmandSettings settings = application.getSettings(); if (!preferenceDownloadViaWiFi(localIndexInfoFile, settings).get() || wifi.isWifiEnabled()) { - new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false, null).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName); + new PerformLiveUpdateAsyncTask(context, localIndexInfoFile, false) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fileName); } else { PerformLiveUpdateAsyncTask.tryRescheduleDownload(context, settings, localIndexInfoFile); } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 1ba3a06563..7885ce051c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -24,7 +24,6 @@ import android.widget.TextView; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatImageButton; import androidx.appcompat.widget.AppCompatImageView; @@ -56,7 +55,7 @@ import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; import net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.OnLiveUpdatesForLocalChange; import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.TextViewEx; @@ -92,7 +91,7 @@ import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getActiveTextC import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getOsmandIconColorId; import static net.osmand.plus.monitoring.TripRecordingBottomSheet.getSecondaryIconColorId; -public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange { +public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnLiveUpdatesForLocalChange, LiveUpdateListener { public static final String URL = "https://osmand.net/api/osmlive_status"; public static final String TAG = LiveUpdatesFragment.class.getSimpleName(); @@ -111,13 +110,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL private GetLastUpdateDateTask getLastUpdateDateTask; private LoadLiveMapsTask loadLiveMapsTask; - private final LiveUpdateListener liveUpdateListener = new LiveUpdateListener() { - @Override - public void processFinish() { - adapter.notifyDataSetChanged(); - } - }; - public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { if (!fragmentManager.isStateSaved()) { LiveUpdatesFragment fragment = new LiveUpdatesFragment(); @@ -126,6 +118,23 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL } } + public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, final LiveUpdateListener listener) { + List mapsToUpdate = listener.getMapsToUpdate(); + if (!Algorithms.isEmpty(mapsToUpdate)) { + int countEnabled = listener.getMapsToUpdate().size(); + if (countEnabled == 1) { + runLiveUpdate(context, mapsToUpdate.get(0).getFileName(), false, new Runnable() { + @Override + public void run() { + listener.processFinish(); + } + }); + } else if (countEnabled > 1) { + LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, listener.currentFragment()); + } + } + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -170,7 +179,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL @Override public void onRefresh() { if (settings.IS_LIVE_UPDATES_ON.get()) { - showUpdateDialog(getActivity(), getFragmentManager(), settings, adapter.mapsList, liveUpdateListener); + showUpdateDialog(getActivity(), getFragmentManager(), LiveUpdatesFragment.this); startUpdateDateAsyncTask(); } swipeRefresh.setRefreshing(false); @@ -326,23 +335,10 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL private void switchOnLiveUpdates() { settings.IS_LIVE_UPDATES_ON.set(true); enableLiveUpdates(true); - showUpdateDialog(getMyActivity(), getFragmentManager(), settings, adapter.mapsList, liveUpdateListener); + showUpdateDialog(getMyActivity(), getFragmentManager(), this); startUpdateDateAsyncTask(); } - public static void showUpdateDialog(Activity context, FragmentManager fragmentManager, OsmandSettings settings, - List mapsList, @Nullable LiveUpdateListener listener) { - if (!Algorithms.isEmpty(mapsList)) { - int countEnabled = updateCountEnabled(null, mapsList, settings); - if (countEnabled == 1) { - LocalIndexInfo li = mapsList.get(0); - runLiveUpdate(context, li.getFileName(), false, listener); - } else if (countEnabled > 1) { - LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, getMapsToUpdate(mapsList, settings), listener); - } - } - } - private void enableLiveUpdates(boolean enable) { if (!Algorithms.isEmpty(adapter.mapsList)) { AlarmManager alarmMgr = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); @@ -562,7 +558,12 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL compoundButton.setOnCheckedChangeListener(new SwitchCompat.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - onUpdateLocalIndex(item, isChecked, null); + onUpdateLocalIndex(item, isChecked, new Runnable() { + @Override + public void run() { + runSort(); + } + }); } }); } else { @@ -639,6 +640,21 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL return description; } + @Override + public void processFinish() { + adapter.notifyDataSetChanged(); + } + + @Override + public List getMapsToUpdate() { + return getMapsToUpdate(adapter.mapsList, settings); + } + + @Override + public Fragment currentFragment() { + return this; + } + @Override public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { @@ -650,15 +666,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL final CommonPreference liveUpdatePreference = preferenceForLocalIndex(fileName, settings); liveUpdatePreference.set(newValue); if (settings.IS_LIVE_UPDATES_ON.get() && liveUpdatePreference.get()) { - runLiveUpdate(getActivity(), fileName, true, new LiveUpdateListener() { - @Override - public void processFinish() { - runSort(); - if (callback != null) { - callback.run(); - } - } - }); + runLiveUpdate(getActivity(), fileName, true, callback); UpdateFrequency updateFrequency = UpdateFrequency.values()[frequencyId]; TimeOfDay timeOfDayToUpdate = TimeOfDay.values()[timeOfDateToUpdateId]; setAlarmForPendingIntent(alarmIntent, alarmManager, updateFrequency, timeOfDayToUpdate); @@ -673,15 +681,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL @Override public void forceUpdateLocal(String fileName, boolean userRequested, final Runnable callback) { if (settings.IS_LIVE_UPDATES_ON.get()) { - runLiveUpdate(getActivity(), fileName, userRequested, new LiveUpdateListener() { - @Override - public void processFinish() { - updateList(); - if (callback != null) { - callback.run(); - } - } - }); + runLiveUpdate(getActivity(), fileName, userRequested, callback); } } @@ -703,5 +703,4 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL public static int getDefaultIconColorId(boolean nightMode) { return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; } - } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java index afcb313217..c8e4c42fdf 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java @@ -9,9 +9,10 @@ import android.text.format.DateUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.R; @@ -20,6 +21,7 @@ import net.osmand.util.Algorithms; import java.io.File; import java.util.Calendar; +import java.util.List; import java.util.concurrent.TimeUnit; public class LiveUpdatesHelper { @@ -254,8 +256,29 @@ public class LiveUpdatesHelper { } } - public static void runLiveUpdate(Context context, final String fileName, boolean userRequested, @Nullable final LiveUpdateListener listener) { + public static void runLiveUpdate(Context context, final String fileName, boolean userRequested, @Nullable final Runnable runOnSuccess) { final String fnExt = Algorithms.getFileNameWithoutExtension(new File(fileName)); - new PerformLiveUpdateAsyncTask(context, fileName, userRequested, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt); + PerformLiveUpdateAsyncTask task = new PerformLiveUpdateAsyncTask(context, fileName, userRequested); + task.setRunOnSuccess(runOnSuccess); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, fnExt); + } + + public static void runLiveUpdate(Context context, boolean userRequested, final LiveUpdateListener listener) { + for (LocalIndexInfo mapToUpdate : listener.getMapsToUpdate()) { + runLiveUpdate(context, mapToUpdate.getFileName(), userRequested, new Runnable() { + @Override + public void run() { + listener.processFinish(); + } + }); + } + } + + public interface LiveUpdateListener { + void processFinish(); + + List getMapsToUpdate(); + + Fragment currentFragment(); } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java index e91d5d9f3c..a40d0e956c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesSettingsBottomSheet.java @@ -157,6 +157,10 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen updateLastCheck(); updateFrequencyHelpMessage(); updateFileSize(); + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdatesFragment) { + ((LiveUpdatesFragment) target).runSort(); + } } })) { item.setTitle(getStateText(!checked)); @@ -276,6 +280,10 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen updateLastCheck(); updateFrequencyHelpMessage(); updateFileSize(); + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdatesFragment) { + ((LiveUpdatesFragment) target).updateList(); + } } }); } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java index 9357210328..a8adc5e9ce 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesUpdateAllBottomSheet.java @@ -1,7 +1,6 @@ package net.osmand.plus.liveupdates; import android.os.Bundle; -import android.os.Parcelable; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; @@ -9,24 +8,21 @@ import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import net.osmand.PlatformUtil; import net.osmand.plus.R; import net.osmand.plus.UiUtilities.DialogButtonType; -import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.base.MenuBottomSheetDialogFragment; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem; -import net.osmand.plus.liveupdates.PerformLiveUpdateAsyncTask.LiveUpdateListener; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.widgets.TextViewEx; import org.apache.commons.logging.Log; -import java.util.ArrayList; -import java.util.List; - import static net.osmand.AndroidUtils.getPrimaryTextColorId; import static net.osmand.plus.liveupdates.LiveUpdatesHelper.runLiveUpdate; @@ -34,40 +30,20 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme public static final String TAG = LiveUpdatesUpdateAllBottomSheet.class.getSimpleName(); private static final Log LOG = PlatformUtil.getLog(LiveUpdatesUpdateAllBottomSheet.class); - private static final String MAPS_TO_UPDATE = "maps_to_update"; - private static final String LIVE_UPDATE_LISTENER = "live_update_listener"; private BaseBottomSheetItem itemTitle; private BaseBottomSheetItem itemDescription; - private List mapsList; - private LiveUpdateListener listener; - - public void setMapsList(List mapsList) { - this.mapsList = mapsList; - } - - public void setListener(LiveUpdateListener listener) { - this.listener = listener; - } - - public static void showInstance(@NonNull FragmentManager fragmentManager, - List mapsList, LiveUpdateListener listener) { + public static void showInstance(@NonNull FragmentManager fragmentManager, Fragment target) { if (!fragmentManager.isStateSaved()) { LiveUpdatesUpdateAllBottomSheet fragment = new LiveUpdatesUpdateAllBottomSheet(); - fragment.setMapsList(mapsList); - fragment.setListener(listener); + fragment.setTargetFragment(target, 0); fragment.show(fragmentManager, TAG); } } @Override public void createMenuItems(Bundle savedInstanceState) { - if (savedInstanceState != null) { - mapsList = savedInstanceState.getParcelableArrayList(MAPS_TO_UPDATE); - listener = (LiveUpdateListener) savedInstanceState.getSerializable(LIVE_UPDATE_LISTENER); - } - updateBottomButtons(); itemTitle = new SimpleBottomSheetItem.Builder() @@ -97,17 +73,10 @@ public class LiveUpdatesUpdateAllBottomSheet extends MenuBottomSheetDialogFragme return view; } - @Override - @SuppressWarnings("unchecked") - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putParcelableArrayList(MAPS_TO_UPDATE, (ArrayList) mapsList); - outState.putSerializable(LIVE_UPDATE_LISTENER, listener); - } - private void updateAll() { - for (LocalIndexInfo li : mapsList) { - runLiveUpdate(getActivity(), li.getFileName(), false, listener); + Fragment target = getTargetFragment(); + if (target instanceof LiveUpdateListener) { + runLiveUpdate(getActivity(), false, (LiveUpdateListener) target); } } diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java index d60470107d..9729cd9b3a 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/PerformLiveUpdateAsyncTask.java @@ -6,7 +6,6 @@ import android.content.Context; import android.os.AsyncTask; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils.OnRequestResultListener; @@ -25,7 +24,6 @@ import net.osmand.util.Algorithms; import org.apache.commons.logging.Log; -import java.io.Serializable; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -47,20 +45,18 @@ public class PerformLiveUpdateAsyncTask @NonNull private final String localIndexFileName; private final boolean userRequested; - private final LiveUpdateListener listener; - - public interface LiveUpdateListener extends Serializable { - void processFinish(); - } + private Runnable runOnSuccess; public PerformLiveUpdateAsyncTask(@NonNull Context context, @NonNull String localIndexFileName, - boolean userRequested, - @Nullable LiveUpdateListener listener) { + boolean userRequested) { this.context = context; this.localIndexFileName = localIndexFileName; this.userRequested = userRequested; - this.listener = listener; + } + + public void setRunOnSuccess(Runnable runOnSuccess) { + this.runOnSuccess = runOnSuccess; } @Override @@ -150,9 +146,6 @@ public class PerformLiveUpdateAsyncTask ((DownloadIndexesThread.DownloadEvents) context).downloadInProgress(); } updateLatestAvailability(application, localIndexFileName); - if (listener != null) { - listener.processFinish(); - } } else { LOG.debug("onPostExecute: Not enough space for updates"); } @@ -164,9 +157,6 @@ public class PerformLiveUpdateAsyncTask ((DownloadIndexesThread.DownloadEvents) context).downloadInProgress(); if (userRequested && context instanceof DownloadActivity) { updateLatestAvailability(application, localIndexFileName); - if (listener != null) { - listener.processFinish(); - } application.showShortToastMessage(R.string.no_updates_available); } } @@ -214,6 +204,9 @@ public class PerformLiveUpdateAsyncTask long dateTime = parsed.getTime(); preferenceLatestUpdateAvailable(settings).set(dateTime); preferenceLatestUpdateAvailable(localIndexFileName, settings).set(dateTime); + if (runOnSuccess != null) { + runOnSuccess.run(); + } } } catch (ParseException e) { long dateTime = preferenceLatestUpdateAvailable(settings).get(); From 0b361afaec5fe7f70a9ca5cb16688b9cdabc9b43 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 16:44:38 +0300 Subject: [PATCH 077/109] Quick action list fix for show/hide for editable items --- .../osmand/plus/quickaction/QuickActionListFragment.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index ec282deb4c..b750aac1a1 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -593,7 +593,13 @@ public class QuickActionListFragment extends BaseOsmAndFragment List actions = getQuickActions(); int actionGlobalPosition = actions.indexOf(action); int actionPosition = actionGlobalPosition % ITEMS_IN_GROUP + 1; - h.title.setText(action.getName(app)); + int test = action.getType(); + if (test == 5) { + String prefAction = getString(R.string.quick_action_show_hide_title); + h.title.setText(getString(R.string.ltr_or_rtl_combine_via_dash, prefAction, action.getName(app))); + } else { + h.title.setText(action.getName(app)); + } h.subTitle.setText(getResources().getString(R.string.quick_action_item_action, actionPosition)); h.icon.setImageDrawable(getContentIcon(action.getIconRes(app))); From 07280935c06428b3301c61f6474b868cb4b30715 Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 19:18:56 +0300 Subject: [PATCH 078/109] some fixes --- .../monitoring/TripRecordingBottomSheet.java | 16 +-- .../TripRecordingClearDataBottomSheet.java | 11 +- .../TripRecordingDiscardBottomSheet.java | 13 ++- .../TripRecordingOptionsBottomSheet.java | 11 +- .../plus/myplaces/GPXItemPagerAdapter.java | 100 ++++++++---------- 5 files changed, 70 insertions(+), 81 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index aa2a5b6cb6..d4b3115f39 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -329,7 +329,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } }); - graphsAdapter = new GPXItemPagerAdapter(app, nightMode, this, true, true); + graphsAdapter = new GPXItemPagerAdapter(app, null, null, nightMode, this, true); graphsAdapter.setChartHMargin(getResources().getDimensionPixelSize(R.dimen.content_padding)); pager.setAdapter(graphsAdapter); @@ -607,23 +607,11 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } } - private TrackDisplayHelper getDisplayHelper() { - TrackDisplayHelper displayHelper = new TrackDisplayHelper(app); - GPXFile gpxFile = getGPXFile(); - if (!selectedGpxFile.isShowCurrentTrack()) { - File file = new File(gpxFile.path); - displayHelper.setFile(file); - displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); - } - displayHelper.setGpx(gpxFile); - return displayHelper; - } - @Override public void onPointSelected(TrkSegment segment, double lat, double lon) { if (trackChartPoints == null) { trackChartPoints = new TrackChartPoints(); - trackChartPoints.setGpx(getDisplayHelper().getGpx()); + trackChartPoints.setGpx(getGPXFile()); } MapActivity mapActivity = getMapActivity(); if (mapActivity != null) { diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java index cf09a2e7f0..aeb33abf93 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingClearDataBottomSheet.java @@ -112,10 +112,15 @@ public class TripRecordingClearDataBottomSheet extends MenuBottomSheetDialogFrag @Override public void dismissTarget() { Fragment target = getTargetFragment(); - Bundle args = new Bundle(); - args.putBoolean(ACTION_CLEAR_DATA, true); - target.setArguments(args); if (target instanceof TripRecordingOptionsBottomSheet) { + Bundle args = target.getArguments(); + if (args != null) { + args.putBoolean(ACTION_CLEAR_DATA, true); + } else { + args = new Bundle(); + args.putBoolean(ACTION_CLEAR_DATA, true); + target.setArguments(args); + } ((TripRecordingOptionsBottomSheet) target).dismiss(); } } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java index 1136980b51..6739187152 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingDiscardBottomSheet.java @@ -68,10 +68,15 @@ public class TripRecordingDiscardBottomSheet extends MenuBottomSheetDialogFragme dismiss(); Fragment target = getTargetFragment(); - if (target != null) { - Bundle args = new Bundle(); - args.putBoolean(ACTION_STOP_AND_DISMISS, true); - target.setArguments(args); + if (target instanceof TripRecordingOptionsBottomSheet) { + Bundle args = target.getArguments(); + if (args != null) { + args.putBoolean(ACTION_STOP_AND_DISMISS, true); + } else { + args = new Bundle(); + args.putBoolean(ACTION_STOP_AND_DISMISS, true); + target.setArguments(args); + } } dismissTarget(); } diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java index f72de8a640..6004adb74a 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingOptionsBottomSheet.java @@ -259,9 +259,14 @@ public class TripRecordingOptionsBottomSheet extends MenuBottomSheetDialogFragme if (mapActivity != null && plugin != null) { stopUpdatingTimeTrackSaved(); plugin.saveCurrentTrack(null, mapActivity, false, true); - Bundle args = new Bundle(); - args.putBoolean(ACTION_STOP_AND_DISMISS, true); - setArguments(args); + Bundle args = getArguments(); + if (args != null) { + args.putBoolean(ACTION_STOP_AND_DISMISS, true); + } else { + args = new Bundle(); + args.putBoolean(ACTION_STOP_AND_DISMISS, true); + setArguments(args); + } dismiss(); dismissTarget(); } diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index cea3454fbc..2df66263e4 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -12,6 +12,7 @@ import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; import androidx.viewpager.widget.PagerAdapter; @@ -89,50 +90,19 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private boolean chartClicked; private boolean nightMode; private boolean onlyGraphs; - private boolean recordingTrack = false; private int chartHMargin = 0; public void setChartHMargin(int chartHMargin) { this.chartHMargin = chartHMargin; } - private SelectedGpxFile getCurrentTrack() { - return app.getSavingTrackHelper().getCurrentTrack(); - } - - private GPXFile getGpxFile() { - return recordingTrack ? getCurrentTrack().getGpxFile() : displayHelper.getGpx(); + private boolean isShowCurrentTrack() { + return displayHelper.getGpx() != null && displayHelper.getGpx().showCurrentTrack; } public GPXItemPagerAdapter(@NonNull OsmandApplication app, - boolean nightMode, - @NonNull SegmentActionsListener actionsListener, - boolean onlyGraphs, - boolean recordingTrack) { - super(); - this.app = app; - this.nightMode = nightMode; - this.actionsListener = actionsListener; - this.onlyGraphs = onlyGraphs; - this.recordingTrack = recordingTrack; - iconsCache = app.getUIUtilities(); - - displayHelper = new TrackDisplayHelper(app); - GPXFile gpxFile = getGpxFile(); - if (!getCurrentTrack().isShowCurrentTrack()) { - File file = new File(gpxFile.path); - displayHelper.setFile(file); - displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); - } - displayHelper.setGpx(gpxFile); - - updateAnalysis(); - fetchTabTypes(); - } - - public GPXItemPagerAdapter(@NonNull OsmandApplication app, - @NonNull GpxDisplayItem gpxItem, - @NonNull TrackDisplayHelper displayHelper, + @Nullable GpxDisplayItem gpxItem, + @Nullable TrackDisplayHelper displayHelper, boolean nightMode, @NonNull SegmentActionsListener actionsListener, boolean onlyGraphs) { @@ -140,22 +110,36 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid this.app = app; this.gpxItem = gpxItem; this.nightMode = nightMode; - this.displayHelper = displayHelper; this.actionsListener = actionsListener; this.onlyGraphs = onlyGraphs; iconsCache = app.getUIUtilities(); + + if (displayHelper == null) { + this.displayHelper = new TrackDisplayHelper(app); + SelectedGpxFile currentTrack = app.getSavingTrackHelper().getCurrentTrack(); + GPXFile gpxFile = currentTrack.getGpxFile(); + if (currentTrack.isShowCurrentTrack()) { + File file = new File(gpxFile.path); + this.displayHelper.setFile(file); + this.displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); + } + this.displayHelper.setGpx(gpxFile); + } else { + this.displayHelper = displayHelper; + } + updateAnalysis(); fetchTabTypes(); } private void updateAnalysis() { analysis = null; - if (recordingTrack) { - GPXFile currentGpx = getCurrentTrack().getGpxFile(); - if (!currentGpx.isEmpty()) { - analysis = currentGpx.getAnalysis(0); + if (isShowCurrentTrack()) { + GPXFile gpxFile = displayHelper.getGpx(); + if (gpxFile != null && !gpxFile.isEmpty()) { + analysis = gpxFile.getAnalysis(0); + gpxItem = GpxUiHelper.makeGpxDisplayItem(app, gpxFile); } - gpxItem = GpxUiHelper.makeGpxDisplayItem(app, currentGpx); } else { if (gpxItem != null) { analysis = gpxItem.analysis; @@ -165,7 +149,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid private void fetchTabTypes() { List tabTypeList = new ArrayList<>(); - if (recordingTrack) { + if (isShowCurrentTrack()) { if (analysis != null && (analysis.hasElevationData || analysis.hasSpeedData)) { tabTypeList.add(GPXTabItemType.GPX_TAB_ITEM_GENERAL); } @@ -187,17 +171,17 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid LineGraphType firstType, LineGraphType secondType) { List dataSets = dataSetsMap.get(tabType); boolean withoutGaps = true; - if (recordingTrack) { - GPXFile currentGpx = getGpxFile(); - withoutGaps = !getCurrentTrack().isJoinSegments() - && (Algorithms.isEmpty(currentGpx.tracks) || currentGpx.tracks.get(0).generalTrack); + if (isShowCurrentTrack()) { + GPXFile gpxFile = displayHelper.getGpx(); + withoutGaps = !app.getSavingTrackHelper().getCurrentTrack().isJoinSegments() && gpxFile != null + && (Algorithms.isEmpty(gpxFile.tracks) || gpxFile.tracks.get(0).generalTrack); } else if (gpxItem != null) { GpxDataItem gpxDataItem = displayHelper.getGpxDataItem(); withoutGaps = gpxItem.isGeneralTrack() && gpxDataItem != null && !gpxDataItem.isJoinSegments(); } if (chart != null && analysis != null) { dataSets = GpxUiHelper.getDataSets(chart, app, analysis, firstType, secondType, withoutGaps); - if (dataSets != null) { + if (!Algorithms.isEmpty(dataSets)) { dataSetsMap.remove(tabType); } dataSetsMap.put(tabType, dataSets); @@ -212,7 +196,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid if (ds != null && ds.size() > 0) { for (GPXUtilities.Track t : gpxItem.group.getGpx().tracks) { for (TrkSegment s : t.segments) { - if (s.points.size() > 0 && s.points.get(0).equals(gpxItem.analysis.locationStart)) { + if (s.points.size() > 0 && s.points.get(0).equals(analysis.locationStart)) { segment = s; break; } @@ -236,7 +220,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid if (gpxItem.chartAxisType == GPXDataSetAxisType.TIME) { float time = pos * 1000; for (WptPt p : segment.points) { - if (p.time - gpxItem.analysis.startTime >= time) { + if (p.time - analysis.startTime >= time) { wpt = p; break; } @@ -739,20 +723,21 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid void updateJoinGapsInfo(View view, int position) { if (view != null) { GPXTabItemType tabType = tabTypes[position]; - boolean visible = gpxItem.isGeneralTrack() && analysis != null && tabType.equals(GPXTabItemType.GPX_TAB_ITEM_GENERAL); - AndroidUiHelper.updateVisibility(view.findViewById(R.id.gpx_join_gaps_container), visible); + boolean generalTrack = gpxItem.isGeneralTrack(); boolean joinSegments = displayHelper.isJoinSegments(); + boolean visible = generalTrack && analysis != null && tabType.equals(GPXTabItemType.GPX_TAB_ITEM_GENERAL); + AndroidUiHelper.updateVisibility(view.findViewById(R.id.gpx_join_gaps_container), visible); ((SwitchCompat) view.findViewById(R.id.gpx_join_gaps_switch)).setChecked(joinSegments); if (analysis != null) { if (tabType.equals(GPXTabItemType.GPX_TAB_ITEM_GENERAL)) { - float totalDistance = !joinSegments && gpxItem.isGeneralTrack() ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; - float timeSpan = !joinSegments && gpxItem.isGeneralTrack() ? analysis.timeSpanWithoutGaps : analysis.timeSpan; + float totalDistance = !joinSegments && generalTrack ? analysis.totalDistanceWithoutGaps : analysis.totalDistance; + float timeSpan = !joinSegments && generalTrack ? analysis.timeSpanWithoutGaps : analysis.timeSpan; ((TextView) view.findViewById(R.id.distance_text)).setText(OsmAndFormatter.getFormattedDistance(totalDistance, app)); ((TextView) view.findViewById(R.id.duration_text)).setText(Algorithms.formatDuration((int) (timeSpan / 1000), app.accessibilityEnabled())); } else if (tabType.equals(GPX_TAB_ITEM_SPEED)) { - long timeMoving = !joinSegments && gpxItem.isGeneralTrack() ? analysis.timeMovingWithoutGaps : analysis.timeMoving; - float totalDistanceMoving = !joinSegments && gpxItem.isGeneralTrack() ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving; + long timeMoving = !joinSegments && generalTrack ? analysis.timeMovingWithoutGaps : analysis.timeMoving; + float totalDistanceMoving = !joinSegments && generalTrack ? analysis.totalDistanceMovingWithoutGaps : analysis.totalDistanceMoving; ((TextView) view.findViewById(R.id.time_moving_text)).setText(Algorithms.formatDuration((int) (timeMoving / 1000), app.accessibilityEnabled())); ((TextView) view.findViewById(R.id.distance_text)).setText(OsmAndFormatter.getFormattedDistance(totalDistanceMoving, app)); @@ -777,10 +762,11 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid } public boolean isTabsVisible() { - if (getCount() > 0 && views.size() > 0) { + GPXFile gpxFile = displayHelper.getGpx(); + if (gpxFile != null && getCount() > 0 && views.size() > 0) { for (int i = 0; i < getCount(); i++) { LineChart lc = getViewAtPosition(i).findViewById(R.id.chart); - if (!lc.isEmpty() && !getGpxFile().isEmpty()) { + if (!lc.isEmpty() && !gpxFile.isEmpty()) { return true; } } From 896ae118789a6b49b48a185ea13e66a52da9ecab Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 19:34:44 +0300 Subject: [PATCH 079/109] Add constant, rename variable --- .../osmand/plus/quickaction/QuickActionListFragment.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index b750aac1a1..6a9cd6c310 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -72,6 +72,8 @@ public class QuickActionListFragment extends BaseOsmAndFragment private static final int ITEMS_IN_GROUP = 6; + public static final int GROUP_POI_ID = 5; + private RecyclerView rv; private FloatingActionButton fab; private View bottomPanel; @@ -593,8 +595,8 @@ public class QuickActionListFragment extends BaseOsmAndFragment List actions = getQuickActions(); int actionGlobalPosition = actions.indexOf(action); int actionPosition = actionGlobalPosition % ITEMS_IN_GROUP + 1; - int test = action.getType(); - if (test == 5) { + int actionType = action.getType(); + if (actionType == GROUP_POI_ID) { String prefAction = getString(R.string.quick_action_show_hide_title); h.title.setText(getString(R.string.ltr_or_rtl_combine_via_dash, prefAction, action.getName(app))); } else { From 40b5220caaa8960ef88f56e6196d2ae05e412a99 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 29 Mar 2021 20:24:06 +0300 Subject: [PATCH 080/109] Map widgets visibility refactoring, part 1 --- .../osmand/plus/activities/MapActivity.java | 7 + .../plus/activities/MapActivityLayers.java | 3 +- .../plus/views/layers/MapControlsLayer.java | 107 ++------- .../views/layers/MapQuickActionLayer.java | 45 +--- .../mapwidgets/MapInfoWidgetsFactory.java | 8 +- .../mapwidgets/MapMarkersWidgetsFactory.java | 16 +- .../mapwidgets/WidgetsVisibilityHelper.java | 222 ++++++++++++++++++ 7 files changed, 258 insertions(+), 150 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 953691b272..c4c63e0376 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -140,6 +140,7 @@ import net.osmand.plus.views.layers.MapControlsLayer; import net.osmand.plus.views.layers.MapInfoLayer; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController; import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType; +import net.osmand.plus.views.mapwidgets.WidgetsVisibilityHelper; import net.osmand.render.RenderingRulesStorage; import net.osmand.router.GeneralRouter; import net.osmand.util.Algorithms; @@ -210,6 +211,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven private MapActivityActions mapActions; private MapActivityLayers mapLayers; + private WidgetsVisibilityHelper mapWidgetsVisibilityHelper; // App variables private OsmandApplication app; @@ -305,6 +307,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven } mapActions = new MapActivityActions(this); mapLayers = new MapActivityLayers(this); + mapWidgetsVisibilityHelper = new WidgetsVisibilityHelper(this); dashboardOnMap.createDashboardView(); checkAppInitialization(); @@ -1597,6 +1600,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven return mapLayers; } + public WidgetsVisibilityHelper getWidgetsVisibilityHelper() { + return mapWidgetsVisibilityHelper; + } + public static void launchMapActivityMoveToTop(Context activity, Bundle prevIntentParams, Uri intentData, Bundle intentParams) { if (activity instanceof MapActivity) { if (((MapActivity) activity).getDashboard().isVisible()) { diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index ccdef9484e..8c26c705f8 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -13,7 +13,6 @@ import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ContextThemeWrapper; -import androidx.core.content.ContextCompat; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities.GPXFile; @@ -184,7 +183,7 @@ public class MapActivityLayers { mapControlsLayer = new MapControlsLayer(activity); mapView.addLayer(mapControlsLayer, 11); // 12. quick actions layer - mapQuickActionLayer = new MapQuickActionLayer(activity, contextMenuLayer); + mapQuickActionLayer = new MapQuickActionLayer(activity); mapView.addLayer(mapQuickActionLayer, 12); contextMenuLayer.setMapQuickActionLayer(mapQuickActionLayer); mapControlsLayer.setMapQuickActionLayer(mapQuickActionLayer); diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 0bfde7edcf..6eaf25b608 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -71,6 +71,7 @@ import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.corenative.NativeCoreContext; +import net.osmand.plus.views.mapwidgets.WidgetsVisibilityHelper; import java.util.ArrayList; import java.util.HashSet; @@ -851,47 +852,36 @@ public class MapControlsLayer extends OsmandMapLayer { // TODOnightMode // updatextColor(textColor, shadw, rulerControl, zoomControls, mapMenuControls); // default buttons - boolean routePlanningMode = false; + RoutingHelper rh = mapActivity.getRoutingHelper(); - if (rh.isRoutePlanningMode()) { - routePlanningMode = true; - } else if ((rh.isRouteCalculated() || rh.isRouteBeingCalculated()) && !rh.isFollowingMode()) { - routePlanningMode = true; - } + WidgetsVisibilityHelper vh = mapActivity.getWidgetsVisibilityHelper(); + + boolean routePlanningMode = isInRoutePlanningMode(); boolean routeFollowingMode = !routePlanningMode && rh.isFollowingMode(); boolean trackDialogOpened = mapActivity.getTrackDetailsMenu().isVisible(); boolean shouldHideTopControls = mapActivity.shouldHideTopControls(); boolean showRouteCalculationControls = routePlanningMode || ((app.accessibilityEnabled() || (System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS)) && routeFollowingMode); boolean routeDialogOpened = mapRouteInfoMenu.isVisible() || (showRouteCalculationControls && mapRouteInfoMenu.needShowMenu()); - updateMyLocationVisibility(backToLocationControl, rh, routeDialogOpened || shouldHideTopControls); - //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); + boolean dialogOpened = routeDialogOpened || shouldHideTopControls; + boolean showBackToLocation = mapActivity.getWidgetsVisibilityHelper().shouldShowBackToLocationButton(); + backToLocationControl.updateVisibility(!dialogOpened && showBackToLocation); + + //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); updateRoutePlaningButton(rh, routePlanningMode); - boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode) - && !isInMovingMarkerMode() && !isInGpxDetailsMode() && !isInMeasurementToolMode() - && !isInPlanRouteMode() && !shouldHideTopControls && !isInChoosingRoutesMode() - && !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInTrackAppearanceMode() - && !isInRouteLineAppearanceMode(); + boolean showBottomMenuButtons = + (showRouteCalculationControls || !routeFollowingMode) && vh.shouldShowBottomMenuButtons(); routePlanningBtn.updateVisibility(showBottomMenuButtons); menuControl.updateVisibility(showBottomMenuButtons); - boolean additionalDialogsHide = !isInGpxApproximationMode() - && !isInTrackAppearanceMode() - && !isInChoosingRoutesMode() - && !isInWaypointsChoosingMode() - && !isInRouteLineAppearanceMode(); - boolean showZoomButtons = !routeDialogOpened && !shouldHideTopControls - && !isInFollowTrackMode() - && (additionalDialogsHide || !portrait); + + boolean showZoomButtons = !routeDialogOpened && !shouldHideTopControls && vh.shouldShowZoomButtons(); mapZoomIn.updateVisibility(showZoomButtons); mapZoomOut.updateVisibility(showZoomButtons); - boolean forceHideCompass = routeDialogOpened || trackDialogOpened || isInMeasurementToolMode() - || isInPlanRouteMode() || shouldHideTopControls || isInChoosingRoutesMode() - || isInTrackAppearanceMode() || isInWaypointsChoosingMode() || isInFollowTrackMode() - || isInRouteLineAppearanceMode(); + boolean forceHideCompass = routeDialogOpened || trackDialogOpened || vh.shouldHideCompass(); compassHud.forceHideCompass = forceHideCompass; compassHud.updateVisibility(!forceHideCompass && shouldShowCompass()); @@ -900,10 +890,8 @@ public class MapControlsLayer extends OsmandMapLayer { if (layersHud.setIconResId(appMode.getIconRes())) { layersHud.update(app, isNight); } - boolean showTopButtons = !routeDialogOpened && !trackDialogOpened && !shouldHideTopControls - && !isInMeasurementToolMode() && !isInPlanRouteMode() && !isInChoosingRoutesMode() - && !isInTrackAppearanceMode() && !isInWaypointsChoosingMode() && !isInFollowTrackMode() - && !isInRouteLineAppearanceMode(); + boolean showTopButtons = !routeDialogOpened && !trackDialogOpened + && !shouldHideTopControls && vh.shouldShowTopButtons(); layersHud.updateVisibility(showTopButtons); quickSearchHud.updateVisibility(showTopButtons); @@ -1026,19 +1014,6 @@ public class MapControlsLayer extends OsmandMapLayer { } } - public void updateMyLocationVisibility(MapHudButton backToLocationControl, RoutingHelper rh, boolean dialogOpened) { - boolean tracked = mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); - boolean visible = !(tracked && rh.isFollowingMode()); - boolean additionalDialogsHide = !isInTrackAppearanceMode() - && !isInGpxApproximationMode() - && !isInChoosingRoutesMode() - && !isInWaypointsChoosingMode() - && !isInFollowTrackMode() - && !isInRouteLineAppearanceMode(); - backToLocationControl.updateVisibility(visible && !dialogOpened && !isInPlanRouteMode() - && (additionalDialogsHide || !isPotrait())); - } - public boolean onSingleTap(PointF point, RotatedTileBox tileBox) { return mapRouteInfoMenu.onSingleTap(point, tileBox); } @@ -1365,49 +1340,11 @@ public class MapControlsLayer extends OsmandMapLayer { this.mapQuickActionLayer = mapQuickActionLayer; } - private boolean isInMovingMarkerMode() { - return mapQuickActionLayer == null ? contextMenuLayer.isInChangeMarkerPositionMode() || contextMenuLayer.isInAddGpxPointMode() : - mapQuickActionLayer.isInMovingMarkerMode() || contextMenuLayer.isInChangeMarkerPositionMode() || contextMenuLayer.isInAddGpxPointMode(); - } - - private boolean isInGpxDetailsMode() { - return contextMenuLayer.isInGpxDetailsMode(); - } - - private boolean isInMeasurementToolMode() { - return mapActivity.getMapLayers().getMeasurementToolLayer().isInMeasurementMode(); - } - - private boolean isInPlanRouteMode() { - return mapActivity.getMapLayers().getMapMarkersLayer().isInPlanRouteMode(); - } - - private boolean isInTrackAppearanceMode() { - return mapActivity.getMapLayers().getGpxLayer().isInTrackAppearanceMode(); - } - - private boolean isInGpxApproximationMode() { - return mapActivity.getMapLayers().getMeasurementToolLayer().isTapsDisabled(); - } - - public boolean isInTrackMenuMode() { - return mapActivity.getTrackMenuFragment() != null && mapActivity.getTrackMenuFragment().isVisible(); - } - - private boolean isInChoosingRoutesMode() { - return MapRouteInfoMenu.chooseRoutesVisible; - } - - private boolean isInWaypointsChoosingMode() { - return MapRouteInfoMenu.waypointsVisible; - } - - private boolean isInRouteLineAppearanceMode() { - return mapActivity.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode(); - } - - private boolean isInFollowTrackMode() { - return MapRouteInfoMenu.followTrackVisible; + private boolean isInRoutePlanningMode() { + RoutingHelper routingHelper = mapActivity.getRoutingHelper(); + return routingHelper.isRoutePlanningMode() + || ((routingHelper.isRouteCalculated() || routingHelper.isRouteBeingCalculated()) + && !routingHelper.isFollowingMode()); } public static View.OnLongClickListener getOnClickMagnifierListener(final OsmandMapTileView view) { diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index 3591a2eca9..4ce6443f32 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -19,7 +19,6 @@ import android.widget.ImageView; import androidx.annotation.DimenRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.util.Pair; -import androidx.fragment.app.Fragment; import com.getkeepsafe.taptargetview.TapTarget; import com.getkeepsafe.taptargetview.TapTargetView; @@ -33,18 +32,13 @@ import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.MapContextMenu; -import net.osmand.plus.mapcontextmenu.MapContextMenuFragment; -import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu; -import net.osmand.plus.measurementtool.MeasurementToolLayer; import net.osmand.plus.quickaction.QuickAction; import net.osmand.plus.quickaction.QuickActionRegistry; import net.osmand.plus.quickaction.QuickActionsWidget; -import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.views.OsmandMapLayer; import net.osmand.plus.views.OsmandMapTileView; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; @@ -56,12 +50,6 @@ import static net.osmand.plus.views.layers.ContextMenuLayer.VIBRATE_SHORT; public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRegistry.QuickActionUpdatesListener, QuickAction.QuickActionSelectionListener { - private final ContextMenuLayer contextMenuLayer; - private final MeasurementToolLayer measurementToolLayer; - private final MapMarkersLayer mapMarkersLayer; - private final MapControlsLayer mapControlsLayer; - private final GPXLayer gpxLayer; - private final RouteLayer routeLayer; private ImageView contextMarker; private final MapActivity mapActivity; private final OsmandApplication app; @@ -81,17 +69,11 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe private boolean nightMode; private Boolean currentWidgetState; - public MapQuickActionLayer(MapActivity activity, ContextMenuLayer contextMenuLayer) { + public MapQuickActionLayer(MapActivity activity) { this.mapActivity = activity; - this.contextMenuLayer = contextMenuLayer; app = activity.getMyApplication(); settings = activity.getMyApplication().getSettings(); quickActionRegistry = app.getQuickActionRegistry(); - measurementToolLayer = mapActivity.getMapLayers().getMeasurementToolLayer(); - mapMarkersLayer = mapActivity.getMapLayers().getMapMarkersLayer(); - gpxLayer = mapActivity.getMapLayers().getGpxLayer(); - mapControlsLayer = mapActivity.getMapLayers().getMapControlsLayer(); - routeLayer = mapActivity.getMapLayers().getRouteLayer(); } @Override @@ -415,29 +397,8 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe } private void setupQuickActionBtnVisibility() { - MapContextMenu contextMenu = mapActivity.getContextMenu(); - MapRouteInfoMenu mapRouteInfoMenu = mapActivity.getMapRouteInfoMenu(); - MapMultiSelectionMenu multiSelectionMenu = contextMenu.getMultiSelectionMenu(); - WeakReference contextMenuMenuFragmentRef = contextMenu.findMenuFragment(); - MapContextMenuFragment contextMenuMenuFragment = contextMenuMenuFragmentRef != null ? contextMenuMenuFragmentRef.get() : null; - Fragment multiMenuFragment = multiSelectionMenu.getFragmentByTag(); - boolean hideQuickButton = !isLayerOn || - contextMenuLayer.isInChangeMarkerPositionMode() || - contextMenuLayer.isInGpxDetailsMode() || - measurementToolLayer.isInMeasurementMode() || - mapMarkersLayer.isInPlanRouteMode() || - gpxLayer.isInTrackAppearanceMode() || - mapControlsLayer.isInTrackMenuMode() || - routeLayer.isInRouteLineAppearanceMode() || - mapRouteInfoMenu.isVisible() || - MapRouteInfoMenu.chooseRoutesVisible || - MapRouteInfoMenu.waypointsVisible || - MapRouteInfoMenu.followTrackVisible || - contextMenu.isVisible() && contextMenuMenuFragment != null && !contextMenuMenuFragment.isRemoving() || - contextMenu.isVisible() && contextMenuMenuFragment != null && contextMenuMenuFragment.isAdded() || - multiSelectionMenu.isVisible() && multiMenuFragment != null && multiMenuFragment.isAdded() || - multiSelectionMenu.isVisible() && multiMenuFragment != null && !multiMenuFragment.isRemoving(); - quickActionButton.setVisibility(hideQuickButton ? View.GONE : View.VISIBLE); + boolean visible = mapActivity.getWidgetsVisibilityHelper().shouldShowQuickActionButton(); + quickActionButton.setVisibility(visible ? View.VISIBLE : View.GONE); } @Override diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java index 993790bfea..601749d3dc 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapInfoWidgetsFactory.java @@ -1204,13 +1204,7 @@ public class MapInfoWidgetsFactory { @SuppressLint("SetTextI18n") public boolean updateInfo() { - boolean visible = settings.SHOW_COORDINATES_WIDGET.get() && !map.shouldHideTopControls() - && map.getMapRouteInfoMenu().shouldShowTopControls() && !map.isTopToolbarActive() - && !map.getMapLayers().getGpxLayer().isInTrackAppearanceMode() - && !map.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode() - && !MapRouteInfoMenu.chooseRoutesVisible && !MapRouteInfoMenu.waypointsVisible - && !MapRouteInfoMenu.followTrackVisible; - + boolean visible = map.getWidgetsVisibilityHelper().shouldShowTopCoordinatesWidget(); updateVisibility(visible); if (visible) { lastKnownLocation = locationProvider.getLastKnownLocation(); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java index 1490ab32b1..8794414553 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/MapMarkersWidgetsFactory.java @@ -36,7 +36,6 @@ public class MapMarkersWidgetsFactory { private boolean portraitMode; private View topBar; - private View addressTopBar; private View topBar2nd; private View rowView; private View rowView2nd; @@ -60,7 +59,6 @@ public class MapMarkersWidgetsFactory { helper = map.getMyApplication().getMapMarkersHelper(); portraitMode = AndroidUiHelper.isOrientationPortrait(map); - addressTopBar = map.findViewById(R.id.map_top_bar); topBar = map.findViewById(R.id.map_markers_top_bar); topBar2nd = map.findViewById(R.id.map_markers_top_bar_2nd); rowView = map.findViewById(R.id.map_marker_row); @@ -181,18 +179,8 @@ public class MapMarkersWidgetsFactory { } List markers = helper.getMapMarkers(); - if (zoom < 3 || markers.size() == 0 - || !map.getMyApplication().getSettings().MARKERS_DISTANCE_INDICATION_ENABLED.get() - || !map.getMyApplication().getSettings().MAP_MARKERS_MODE.get().isToolbar() - || map.getMyApplication().getRoutingHelper().isFollowingMode() - || map.getMyApplication().getRoutingHelper().isRoutePlanningMode() - || map.getMapRouteInfoMenu().isVisible() - || addressTopBar.getVisibility() == View.VISIBLE - || map.isTopToolbarActive() - || map.shouldHideTopControls() - || map.getMapLayers().getGpxLayer().isInTrackAppearanceMode() - || map.getMapLayers().getMapMarkersLayer().isInPlanRouteMode() - || map.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode()) { + WidgetsVisibilityHelper vh = map.getWidgetsVisibilityHelper(); + if (zoom < 3 || markers.size() == 0 || vh.shouldHideMapMarkersWidget()) { updateVisibility(false); return; } diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java new file mode 100644 index 0000000000..b0b13b346e --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java @@ -0,0 +1,222 @@ +package net.osmand.plus.views.mapwidgets; + +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import net.osmand.plus.R; +import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.helpers.AndroidUiHelper; +import net.osmand.plus.mapcontextmenu.MapContextMenu; +import net.osmand.plus.mapcontextmenu.MapContextMenuFragment; +import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu; +import net.osmand.plus.routepreparationmenu.MapRouteInfoMenu; +import net.osmand.plus.routing.RoutingHelper; +import net.osmand.plus.settings.backend.OsmandSettings; +import net.osmand.plus.views.layers.MapQuickActionLayer; + +import java.lang.ref.WeakReference; + +public class WidgetsVisibilityHelper { + + private MapActivity mapActivity; + private OsmandSettings settings; + private RoutingHelper routingHelper; + + public WidgetsVisibilityHelper(@NonNull MapActivity mapActivity) { + this.mapActivity = mapActivity; + this.settings = mapActivity.getMyApplication().getSettings(); + this.routingHelper = mapActivity.getRoutingHelper(); + } + + public boolean shouldShowQuickActionButton() { + return isQuickActionLayerOn() + && !isInChangeMarkerPositionMode() + && !isInGpxDetailsMode() + && !isInMeasurementToolMode() + && !isInPlanRouteMode() + && !isInTrackAppearanceMode() + && !isInTrackMenuMode() + && !isInRouteLineAppearanceMode() + && !isMapRouteInfoMenuVisible() + && !isInChoosingRoutesMode() + && !isInWaypointsChoosingMode() + && !isInFollowTrackMode() + && !isContextMenuFragmentVisible() + && !isMultiSelectionMenuFragmentVisible(); + } + + public boolean shouldShowTopCoordinatesWidget() { + return settings.SHOW_COORDINATES_WIDGET.get() + && !mapActivity.shouldHideTopControls() + && mapActivity.getMapRouteInfoMenu().shouldShowTopControls() + && !mapActivity.isTopToolbarActive() + && !isInTrackAppearanceMode() + && !isInRouteLineAppearanceMode() + && !isInChoosingRoutesMode() + && !isInWaypointsChoosingMode() + && !isInFollowTrackMode(); + } + + public boolean shouldHideMapMarkersWidget() { + View addressTopBar = mapActivity.findViewById(R.id.map_top_bar); + return !settings.MARKERS_DISTANCE_INDICATION_ENABLED.get() + || !settings.MAP_MARKERS_MODE.get().isToolbar() + || addressTopBar != null && addressTopBar.getVisibility() == View.VISIBLE + || routingHelper.isFollowingMode() + || routingHelper.isRoutePlanningMode() + || isMapRouteInfoMenuVisible() + || mapActivity.isTopToolbarActive() + || mapActivity.shouldHideTopControls() + || isInTrackAppearanceMode() + || isInPlanRouteMode() + || isInRouteLineAppearanceMode(); + } + + public boolean shouldShowBottomMenuButtons() { + return !mapActivity.shouldHideTopControls() + && !isInMovingMarkerMode() + && !isInGpxDetailsMode() + && !isInMeasurementToolMode() + && !isInPlanRouteMode() + && !isInChoosingRoutesMode() + && !isInWaypointsChoosingMode() + && !isInFollowTrackMode() + && !isInTrackAppearanceMode() + && !isInRouteLineAppearanceMode(); + } + + public boolean shouldShowZoomButtons() { + boolean additionalDialogsHide = !isInGpxApproximationMode() + && !isInTrackAppearanceMode() + && !isInChoosingRoutesMode() + && !isInWaypointsChoosingMode() + && !isInRouteLineAppearanceMode(); + return !isInFollowTrackMode() && (additionalDialogsHide || !isPortrait()); + } + + public boolean shouldHideCompass() { + return mapActivity.shouldHideTopControls() + || isInMeasurementToolMode() + || isInPlanRouteMode() + || isInChoosingRoutesMode() + || isInTrackAppearanceMode() + || isInWaypointsChoosingMode() + || isInFollowTrackMode() + || isInRouteLineAppearanceMode(); + } + + public boolean shouldShowTopButtons() { + return !isInMeasurementToolMode() + && !isInPlanRouteMode() + && !isInChoosingRoutesMode() + && !isInTrackAppearanceMode() + && !isInWaypointsChoosingMode() + && !isInFollowTrackMode() + && !isInRouteLineAppearanceMode(); + } + + public boolean shouldShowBackToLocationButton() { + boolean additionalDialogsHide = !isInTrackAppearanceMode() + && !isInGpxApproximationMode() + && !isInChoosingRoutesMode() + && !isInWaypointsChoosingMode() + && !isInFollowTrackMode() + && !isInRouteLineAppearanceMode(); + return !isInPlanRouteMode() + && !(isMapLinkedToLocation() && routingHelper.isFollowingMode()) + && (additionalDialogsHide || !isPortrait()); + } + + private boolean isQuickActionLayerOn() { + return mapActivity.getMapLayers().getMapQuickActionLayer().isLayerOn(); + } + + private boolean isMapRouteInfoMenuVisible() { + return mapActivity.getMapRouteInfoMenu().isVisible(); + } + + private boolean isInMovingMarkerMode() { + MapQuickActionLayer quickActionLayer = mapActivity.getMapLayers().getMapQuickActionLayer(); + boolean isInMovingMarkerMode = quickActionLayer != null && quickActionLayer.isInMovingMarkerMode(); + return isInMovingMarkerMode || isInChangeMarkerPositionMode() || isInAddGpxPointMode(); + } + + private boolean isInGpxDetailsMode() { + return mapActivity.getMapLayers().getContextMenuLayer().isInGpxDetailsMode(); + } + + private boolean isInAddGpxPointMode() { + return mapActivity.getMapLayers().getContextMenuLayer().isInAddGpxPointMode(); + } + + private boolean isInChangeMarkerPositionMode() { + return mapActivity.getMapLayers().getContextMenuLayer().isInChangeMarkerPositionMode(); + } + + private boolean isInMeasurementToolMode() { + return mapActivity.getMapLayers().getMeasurementToolLayer().isInMeasurementMode(); + } + + private boolean isInPlanRouteMode() { + return mapActivity.getMapLayers().getMapMarkersLayer().isInPlanRouteMode(); + } + + private boolean isInTrackAppearanceMode() { + return mapActivity.getMapLayers().getGpxLayer().isInTrackAppearanceMode(); + } + + private boolean isInGpxApproximationMode() { + return mapActivity.getMapLayers().getMeasurementToolLayer().isTapsDisabled(); + } + + public boolean isInTrackMenuMode() { + return mapActivity.getTrackMenuFragment() != null && mapActivity.getTrackMenuFragment().isVisible(); + } + + private boolean isInChoosingRoutesMode() { + return MapRouteInfoMenu.chooseRoutesVisible; + } + + private boolean isInWaypointsChoosingMode() { + return MapRouteInfoMenu.waypointsVisible; + } + + private boolean isInRouteLineAppearanceMode() { + return mapActivity.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode(); + } + + private boolean isInFollowTrackMode() { + return MapRouteInfoMenu.followTrackVisible; + } + + private boolean isContextMenuFragmentVisible() { + MapContextMenu contextMenu = mapActivity.getContextMenu(); + WeakReference contextMenuMenuFragmentRef = contextMenu.findMenuFragment(); + MapContextMenuFragment contextMenuMenuFragment = contextMenuMenuFragmentRef != null ? contextMenuMenuFragmentRef.get() : null; + if (contextMenuMenuFragment != null && contextMenu.isVisible()) { + return !contextMenuMenuFragment.isRemoving() || contextMenuMenuFragment.isAdded(); + } + return false; + } + + private boolean isMultiSelectionMenuFragmentVisible() { + MapContextMenu contextMenu = mapActivity.getContextMenu(); + MapMultiSelectionMenu multiSelectionMenu = contextMenu.getMultiSelectionMenu(); + Fragment multiMenuFragment = multiSelectionMenu.getFragmentByTag(); + if (multiMenuFragment != null && multiSelectionMenu.isVisible()) { + return multiMenuFragment.isAdded() || !multiMenuFragment.isRemoving(); + } + return false; + } + + private boolean isMapLinkedToLocation() { + return mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); + } + + private boolean isPortrait() { + return AndroidUiHelper.isOrientationPortrait(mapActivity); + } + +} From dacbc9b4cfff641993336dc67bd3b8086b708611 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 29 Mar 2021 20:26:55 +0300 Subject: [PATCH 081/109] fix spaces --- .../src/net/osmand/plus/views/layers/MapQuickActionLayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java index 4ce6443f32..87fa1f5cbf 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapQuickActionLayer.java @@ -397,7 +397,7 @@ public class MapQuickActionLayer extends OsmandMapLayer implements QuickActionRe } private void setupQuickActionBtnVisibility() { - boolean visible = mapActivity.getWidgetsVisibilityHelper().shouldShowQuickActionButton(); + boolean visible = mapActivity.getWidgetsVisibilityHelper().shouldShowQuickActionButton(); quickActionButton.setVisibility(visible ? View.VISIBLE : View.GONE); } From 5e1a5e8d3eaebea78e2baec9bea6fc4863152cf5 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Mon, 29 Mar 2021 20:43:41 +0300 Subject: [PATCH 082/109] Review --- .../plus/quickaction/QuickActionListFragment.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java index 6a9cd6c310..28981e5db6 100644 --- a/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java +++ b/OsmAnd/src/net/osmand/plus/quickaction/QuickActionListFragment.java @@ -72,8 +72,6 @@ public class QuickActionListFragment extends BaseOsmAndFragment private static final int ITEMS_IN_GROUP = 6; - public static final int GROUP_POI_ID = 5; - private RecyclerView rv; private FloatingActionButton fab; private View bottomPanel; @@ -595,12 +593,12 @@ public class QuickActionListFragment extends BaseOsmAndFragment List actions = getQuickActions(); int actionGlobalPosition = actions.indexOf(action); int actionPosition = actionGlobalPosition % ITEMS_IN_GROUP + 1; - int actionType = action.getType(); - if (actionType == GROUP_POI_ID) { - String prefAction = getString(R.string.quick_action_show_hide_title); + String name = action.getName(app); + if (action.getActionNameRes() != 0 && !name.contains(getString(action.getActionNameRes()))) { + String prefAction = getString(action.getActionNameRes()); h.title.setText(getString(R.string.ltr_or_rtl_combine_via_dash, prefAction, action.getName(app))); } else { - h.title.setText(action.getName(app)); + h.title.setText(name); } h.subTitle.setText(getResources().getString(R.string.quick_action_item_action, actionPosition)); h.icon.setImageDrawable(getContentIcon(action.getIconRes(app))); From fc3589288383b51256cd326e4c1e7a0ecbe3abba Mon Sep 17 00:00:00 2001 From: cepprice Date: Mon, 29 Mar 2021 22:50:51 +0500 Subject: [PATCH 083/109] Fix nigth mode for cards --- .../plus/routepreparationmenu/cards/BaseCard.java | 6 +++++- .../settings/fragments/SubscriptionsCard.java | 2 +- .../settings/fragments/SubscriptionsListCard.java | 2 +- .../TroubleshootingOrPurchasingCard.java | 15 +++++++-------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java index d4101e58ec..fc24f9bace 100644 --- a/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java +++ b/OsmAnd/src/net/osmand/plus/routepreparationmenu/cards/BaseCard.java @@ -39,9 +39,13 @@ public abstract class BaseCard { } public BaseCard(@NonNull MapActivity mapActivity) { + this(mapActivity, true); + } + + public BaseCard(@NonNull MapActivity mapActivity, boolean usedOnMap) { this.mapActivity = mapActivity; this.app = mapActivity.getMyApplication(); - nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls(); + nightMode = usedOnMap ? app.getDaynightHelper().isNightModeForMapControls() : !app.getSettings().isLightContent(); } public abstract int getCardLayoutId(); diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index 100bab00df..3b5e537196 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -40,7 +40,7 @@ public class SubscriptionsCard extends BaseCard { } public SubscriptionsCard(@NonNull MapActivity mapActivity, @NonNull Fragment target, @NonNull InAppPurchaseHelper purchaseHelper) { - super(mapActivity); + super(mapActivity, false); this.target = target; this.purchaseHelper = purchaseHelper; } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java index 9d8d4f9568..645a68b037 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsListCard.java @@ -39,7 +39,7 @@ public class SubscriptionsListCard extends BaseCard { } public SubscriptionsListCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper) { - super(mapActivity); + super(mapActivity, false); this.purchaseHelper = purchaseHelper; this.dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.getDefault()); } diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java index c53950ee2b..44fb4a980b 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/TroubleshootingOrPurchasingCard.java @@ -20,7 +20,6 @@ import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.wikipedia.WikipediaDialogFragment; -import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.core.content.ContextCompat; @@ -41,15 +40,15 @@ public class TroubleshootingOrPurchasingCard extends BaseCard { } public TroubleshootingOrPurchasingCard(@NonNull MapActivity mapActivity, @NonNull InAppPurchaseHelper purchaseHelper, boolean isPaidVersion) { - super(mapActivity); + super(mapActivity, false); this.purchaseHelper = purchaseHelper; this.isPaidVersion = isPaidVersion; } @Override protected void updateContent() { - setupRestorePurchasesBtn(R.id.restore_purchases); - setupNewDeviceOrAccountBtn(R.id.new_device_account_container); + setupRestorePurchasesBtn(); + setupNewDeviceOrAccountBtn(); setupSupportDescription(); setupContactUsLink(); @@ -82,8 +81,8 @@ public class TroubleshootingOrPurchasingCard extends BaseCard { } } - protected void setupRestorePurchasesBtn(@IdRes int btnId) { - View purchasesRestore = view.findViewById(btnId); + protected void setupRestorePurchasesBtn() { + View purchasesRestore = view.findViewById(R.id.restore_purchases); purchasesRestore.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -94,8 +93,8 @@ public class TroubleshootingOrPurchasingCard extends BaseCard { }); } - protected void setupNewDeviceOrAccountBtn(@IdRes int btnId) { - View newDeviceAccountContainer = view.findViewById(btnId); + protected void setupNewDeviceOrAccountBtn() { + View newDeviceAccountContainer = view.findViewById(R.id.new_device_account_container); newDeviceAccountContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { From 7420b7104873504f384dca99216f7bf2393a736a Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 21:00:39 +0300 Subject: [PATCH 084/109] small fixes --- OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 2e1a697729..2058c6e31b 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -656,7 +656,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL @Override public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { - int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); int timeOfDateToUpdateId = preferenceTimeOfDayToUpdate(fileName, settings).get(); final AlarmManager alarmManager = (AlarmManager) app.getSystemService(Context.ALARM_SERVICE); @@ -673,7 +672,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL alarmManager.cancel(alarmIntent); runSort(); } - return true; } From 9a6d6049a4891bc5132207df70d54bfae6f5747e Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 21:15:16 +0300 Subject: [PATCH 085/109] fixes after merge --- .../plus/liveupdates/LiveUpdatesFragment.java | 36 +++++++++++++++++++ .../settings/fragments/SubscriptionsCard.java | 3 +- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 2058c6e31b..6e3c951f6c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -50,6 +50,7 @@ import net.osmand.plus.base.BaseOsmAndDialogFragment; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.inapp.InAppPurchaseHelper; +import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; @@ -696,6 +697,41 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL } } + public static String getSupportRegionName(OsmandApplication app, InAppPurchaseHelper purchaseHelper) { + OsmandSettings settings = app.getSettings(); + String countryName = settings.BILLING_USER_COUNTRY.get(); + if (purchaseHelper != null) { + List subscriptions = purchaseHelper.getLiveUpdates().getVisibleSubscriptions(); + boolean donationSupported = false; + for (InAppSubscription s : subscriptions) { + if (s.isDonationSupported()) { + donationSupported = true; + break; + } + } + if (donationSupported) { + if (Algorithms.isEmpty(countryName)) { + if (OsmandSettings.BILLING_USER_DONATION_NONE_PARAMETER.equals(settings.BILLING_USER_COUNTRY_DOWNLOAD_NAME.get())) { + countryName = app.getString(R.string.osmand_team); + } else { + countryName = app.getString(R.string.shared_string_world); + } + } + } else { + countryName = app.getString(R.string.osmand_team); + } + } else { + countryName = app.getString(R.string.osmand_team); + } + return countryName; + } + + public static String getSupportRegionHeader(OsmandApplication app, String supportRegion) { + return supportRegion.equals(app.getString(R.string.osmand_team)) ? + app.getString(R.string.default_buttons_support) : + app.getString(R.string.osm_live_support_region); + } + @ColorRes public static int getDefaultIconColorId(boolean nightMode) { return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; diff --git a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java index 100bab00df..300b5b55dd 100644 --- a/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java +++ b/OsmAnd/src/net/osmand/plus/settings/fragments/SubscriptionsCard.java @@ -14,7 +14,6 @@ import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.liveupdates.CountrySelectionFragment; import net.osmand.plus.liveupdates.LiveUpdatesFragment; -import net.osmand.plus.liveupdates.LiveUpdatesFragmentNew; import net.osmand.plus.liveupdates.OsmLiveActivity; import net.osmand.plus.routepreparationmenu.cards.BaseCard; import net.osmand.plus.settings.backend.OsmandSettings; @@ -71,7 +70,7 @@ public class SubscriptionsCard extends BaseCard { liveUpdatesContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - LiveUpdatesFragmentNew.showInstance(mapActivity.getSupportFragmentManager(), target); + LiveUpdatesFragment.showInstance(mapActivity.getSupportFragmentManager(), target); } }); From a8f780a46c40557ea2da440058ec3bf64bc728a2 Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 21:48:37 +0300 Subject: [PATCH 086/109] fix hiding gpx files on maps after deleting from my places p1 --- .../net/osmand/plus/myplaces/AvailableGPXFragment.java | 8 +++----- OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index b5f33884ac..12bcca4b51 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -1507,17 +1507,15 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement int total = 0; for (GpxInfo info : params) { if (!isCancelled() && (info.gpx == null || !info.gpx.showCurrentTrack)) { - boolean successfull; - successfull = removeAllFiles(info.file); - app.getGpxDbHelper().remove(info.file); + boolean successful = FileUtils.removeGpxFile(app, info.file); total++; - if (successfull) { + if (successful) { count++; publishProgress(info); } } } - return app.getString(R.string.local_index_items_deleted, count, total); + return getString(R.string.local_index_items_deleted, count, total); } @Override diff --git a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java index b2d3aaa7dd..ef2bd196a7 100644 --- a/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java +++ b/OsmAnd/src/net/osmand/plus/track/TrackMenuFragment.java @@ -866,7 +866,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card R.string.shared_string_ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - if (FileUtils.removeGpxFile(app, new File((gpxFile.path)))) { + if (FileUtils.removeGpxFile(app, new File(gpxFile.path))) { dismiss(); } } From 48092f0e23d38b8abf942df1d2f4d15b02c0d9dd Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 21:48:50 +0300 Subject: [PATCH 087/109] fix hiding gpx files on maps after deleting from my places p2 --- OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java index 12bcca4b51..a2eaae19d0 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/AvailableGPXFragment.java @@ -1290,13 +1290,14 @@ public class AvailableGPXFragment extends OsmandExpandableListFragment implement // local_indexes_cat_gpx now obsolete in new UI screen which shows only GPX data // if (Algorithms.objectEquals(getActivity().getString(R.string.local_indexes_cat_gpx) + " " + // g.subfolder, cat)) { - if (objectEquals("" + g.subfolder, cat)) { + if (objectEquals(g.subfolder, cat)) { found = i; break; } } if (found != -1) { data.get(category.get(found)).remove(g); + selected.remove(g); } } } From 82fa75db1d843d2e24296052e6194a1b5f4688c5 Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 22:11:37 +0300 Subject: [PATCH 088/109] small fixes --- .../monitoring/TripRecordingBottomSheet.java | 9 ++++++++- .../plus/myplaces/GPXItemPagerAdapter.java | 17 ++--------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java index d4b3115f39..89734b7415 100644 --- a/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java +++ b/OsmAnd/src/net/osmand/plus/monitoring/TripRecordingBottomSheet.java @@ -329,7 +329,14 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl } }); - graphsAdapter = new GPXItemPagerAdapter(app, null, null, nightMode, this, true); + TrackDisplayHelper displayHelper = new TrackDisplayHelper(app); + GPXFile gpxFile = getGPXFile(); + File file = new File(gpxFile.path); + displayHelper.setFile(file); + displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); + displayHelper.setGpx(gpxFile); + + graphsAdapter = new GPXItemPagerAdapter(app, null, displayHelper, nightMode, this, true); graphsAdapter.setChartHMargin(getResources().getDimensionPixelSize(R.dimen.content_padding)); pager.setAdapter(graphsAdapter); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index 2df66263e4..8f0c5a1dc5 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -102,32 +102,19 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid public GPXItemPagerAdapter(@NonNull OsmandApplication app, @Nullable GpxDisplayItem gpxItem, - @Nullable TrackDisplayHelper displayHelper, + @NonNull TrackDisplayHelper displayHelper, boolean nightMode, @NonNull SegmentActionsListener actionsListener, boolean onlyGraphs) { super(); this.app = app; this.gpxItem = gpxItem; + this.displayHelper = displayHelper; this.nightMode = nightMode; this.actionsListener = actionsListener; this.onlyGraphs = onlyGraphs; iconsCache = app.getUIUtilities(); - if (displayHelper == null) { - this.displayHelper = new TrackDisplayHelper(app); - SelectedGpxFile currentTrack = app.getSavingTrackHelper().getCurrentTrack(); - GPXFile gpxFile = currentTrack.getGpxFile(); - if (currentTrack.isShowCurrentTrack()) { - File file = new File(gpxFile.path); - this.displayHelper.setFile(file); - this.displayHelper.setGpxDataItem(app.getGpxDbHelper().getItem(file)); - } - this.displayHelper.setGpx(gpxFile); - } else { - this.displayHelper = displayHelper; - } - updateAnalysis(); fetchTabTypes(); } From 7dd3795ebe22bc0a4a72b67850540366aeb17b1f Mon Sep 17 00:00:00 2001 From: Skalii Date: Mon, 29 Mar 2021 22:21:12 +0300 Subject: [PATCH 089/109] small fixes --- .../osmand/plus/download/ui/UpdatesIndexFragment.java | 6 ------ .../osmand/plus/liveupdates/LiveUpdatesFragment.java | 11 +++++------ .../osmand/plus/liveupdates/LiveUpdatesHelper.java | 2 -- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java index 1dbd8782ba..ae0ab9b560 100644 --- a/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/ui/UpdatesIndexFragment.java @@ -29,7 +29,6 @@ import androidx.appcompat.content.res.AppCompatResources; import androidx.cardview.widget.CardView; import androidx.core.content.ContextCompat; import androidx.core.view.MenuItemCompat; -import androidx.fragment.app.Fragment; import net.osmand.AndroidUtils; import net.osmand.Collator; @@ -426,11 +425,6 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download return LiveUpdatesFragment.getMapsToUpdate(listAdapter.mapsList, settings); } - @Override - public Fragment currentFragment() { - return this; - } - @ColorRes public static int getDefaultIconColorId(boolean nightMode) { return nightMode ? R.color.icon_color_default_dark : R.color.icon_color_default_light; diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 6e3c951f6c..520af19810 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -131,7 +131,11 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL } }); } else if (countEnabled > 1) { - LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, listener.currentFragment()); + Fragment target = null; + if (listener instanceof Fragment) { + target = (Fragment) listener; + } + LiveUpdatesUpdateAllBottomSheet.showInstance(fragmentManager, target); } } } @@ -650,11 +654,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL return getMapsToUpdate(adapter.mapsList, settings); } - @Override - public Fragment currentFragment() { - return this; - } - @Override public boolean onUpdateLocalIndex(String fileName, boolean newValue, final Runnable callback) { int frequencyId = preferenceUpdateFrequency(fileName, settings).get(); diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java index c8e4c42fdf..1833cd397c 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesHelper.java @@ -278,7 +278,5 @@ public class LiveUpdatesHelper { void processFinish(); List getMapsToUpdate(); - - Fragment currentFragment(); } } From 3dff56da46836947ecb01ef905d9b84590be9ef1 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 29 Mar 2021 23:09:02 +0300 Subject: [PATCH 090/109] Map widgets visibility refactoring, part 2 --- .../plus/views/layers/MapControlsLayer.java | 22 +++++++------------ .../mapwidgets/WidgetsVisibilityHelper.java | 16 +++++++++++--- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 6eaf25b608..614ecce575 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -858,30 +858,25 @@ public class MapControlsLayer extends OsmandMapLayer { boolean routePlanningMode = isInRoutePlanningMode(); boolean routeFollowingMode = !routePlanningMode && rh.isFollowingMode(); - boolean trackDialogOpened = mapActivity.getTrackDetailsMenu().isVisible(); - boolean shouldHideTopControls = mapActivity.shouldHideTopControls(); - boolean showRouteCalculationControls = routePlanningMode || - ((app.accessibilityEnabled() || (System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS)) && routeFollowingMode); + boolean timeToShowButtons = System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS; + boolean showRouteCalculationControls = routePlanningMode || ((app.accessibilityEnabled() || timeToShowButtons) && routeFollowingMode); boolean routeDialogOpened = mapRouteInfoMenu.isVisible() || (showRouteCalculationControls && mapRouteInfoMenu.needShowMenu()); - boolean dialogOpened = routeDialogOpened || shouldHideTopControls; - boolean showBackToLocation = mapActivity.getWidgetsVisibilityHelper().shouldShowBackToLocationButton(); - backToLocationControl.updateVisibility(!dialogOpened && showBackToLocation); + boolean showBackToLocation = !routeDialogOpened && mapActivity.getWidgetsVisibilityHelper().shouldShowBackToLocationButton(); + backToLocationControl.updateVisibility(showBackToLocation); //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); updateRoutePlaningButton(rh, routePlanningMode); - boolean showBottomMenuButtons = - (showRouteCalculationControls || !routeFollowingMode) && vh.shouldShowBottomMenuButtons(); + boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode) && vh.shouldShowBottomMenuButtons(); routePlanningBtn.updateVisibility(showBottomMenuButtons); menuControl.updateVisibility(showBottomMenuButtons); - - boolean showZoomButtons = !routeDialogOpened && !shouldHideTopControls && vh.shouldShowZoomButtons(); + boolean showZoomButtons = !routeDialogOpened && vh.shouldShowZoomButtons(); mapZoomIn.updateVisibility(showZoomButtons); mapZoomOut.updateVisibility(showZoomButtons); - boolean forceHideCompass = routeDialogOpened || trackDialogOpened || vh.shouldHideCompass(); + boolean forceHideCompass = routeDialogOpened || vh.shouldHideCompass(); compassHud.forceHideCompass = forceHideCompass; compassHud.updateVisibility(!forceHideCompass && shouldShowCompass()); @@ -890,8 +885,7 @@ public class MapControlsLayer extends OsmandMapLayer { if (layersHud.setIconResId(appMode.getIconRes())) { layersHud.update(app, isNight); } - boolean showTopButtons = !routeDialogOpened && !trackDialogOpened - && !shouldHideTopControls && vh.shouldShowTopButtons(); + boolean showTopButtons = !routeDialogOpened && vh.shouldShowTopButtons(); layersHud.updateVisibility(showTopButtons); quickSearchHud.updateVisibility(showTopButtons); diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java index b0b13b346e..7cc747c1b6 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java @@ -93,11 +93,14 @@ public class WidgetsVisibilityHelper { && !isInChoosingRoutesMode() && !isInWaypointsChoosingMode() && !isInRouteLineAppearanceMode(); - return !isInFollowTrackMode() && (additionalDialogsHide || !isPortrait()); + return !mapActivity.shouldHideTopControls() + && !isInFollowTrackMode() + && (additionalDialogsHide || !isPortrait()); } public boolean shouldHideCompass() { return mapActivity.shouldHideTopControls() + || isTrackDetailsMenuOpened() || isInMeasurementToolMode() || isInPlanRouteMode() || isInChoosingRoutesMode() @@ -108,7 +111,9 @@ public class WidgetsVisibilityHelper { } public boolean shouldShowTopButtons() { - return !isInMeasurementToolMode() + return !mapActivity.shouldHideTopControls() + && !isTrackDetailsMenuOpened() + && !isInMeasurementToolMode() && !isInPlanRouteMode() && !isInChoosingRoutesMode() && !isInTrackAppearanceMode() @@ -124,7 +129,8 @@ public class WidgetsVisibilityHelper { && !isInWaypointsChoosingMode() && !isInFollowTrackMode() && !isInRouteLineAppearanceMode(); - return !isInPlanRouteMode() + return !mapActivity.shouldHideTopControls() + && !isInPlanRouteMode() && !(isMapLinkedToLocation() && routingHelper.isFollowingMode()) && (additionalDialogsHide || !isPortrait()); } @@ -215,6 +221,10 @@ public class WidgetsVisibilityHelper { return mapActivity.getMapViewTrackingUtilities().isMapLinkedToLocation(); } + private boolean isTrackDetailsMenuOpened() { + return mapActivity.getTrackDetailsMenu().isVisible(); + } + private boolean isPortrait() { return AndroidUiHelper.isOrientationPortrait(mapActivity); } From 5149d6543b9477717da7b598f423fecdb5275073 Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Mon, 29 Mar 2021 23:13:53 +0300 Subject: [PATCH 091/109] Map widgets visibility refactoring, part 3 --- .../plus/views/layers/MapControlsLayer.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java index 614ecce575..22c077f02d 100644 --- a/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/layers/MapControlsLayer.java @@ -856,27 +856,27 @@ public class MapControlsLayer extends OsmandMapLayer { RoutingHelper rh = mapActivity.getRoutingHelper(); WidgetsVisibilityHelper vh = mapActivity.getWidgetsVisibilityHelper(); - boolean routePlanningMode = isInRoutePlanningMode(); - boolean routeFollowingMode = !routePlanningMode && rh.isFollowingMode(); - boolean timeToShowButtons = System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS; - boolean showRouteCalculationControls = routePlanningMode || ((app.accessibilityEnabled() || timeToShowButtons) && routeFollowingMode); - boolean routeDialogOpened = mapRouteInfoMenu.isVisible() || (showRouteCalculationControls && mapRouteInfoMenu.needShowMenu()); + boolean isRoutePlanningMode = isInRoutePlanningMode(); + boolean isRouteFollowingMode = !isRoutePlanningMode && rh.isFollowingMode(); + boolean isTimeToShowButtons = System.currentTimeMillis() - touchEvent < TIMEOUT_TO_SHOW_BUTTONS; + boolean shouldShowRouteCalculationControls = isRoutePlanningMode || ((app.accessibilityEnabled() || isTimeToShowButtons) && isRouteFollowingMode); + boolean isRouteDialogOpened = mapRouteInfoMenu.isVisible() || (shouldShowRouteCalculationControls && mapRouteInfoMenu.needShowMenu()); - boolean showBackToLocation = !routeDialogOpened && mapActivity.getWidgetsVisibilityHelper().shouldShowBackToLocationButton(); + boolean showBackToLocation = !isRouteDialogOpened && vh.shouldShowBackToLocationButton(); backToLocationControl.updateVisibility(showBackToLocation); - //routePlanningBtn.setIconResId(routeFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); - updateRoutePlaningButton(rh, routePlanningMode); + //routePlanningBtn.setIconResId(isRouteFollowingMode ? R.drawable.ic_action_info_dark : R.drawable.ic_action_gdirections_dark); + updateRoutePlaningButton(rh, isRoutePlanningMode); - boolean showBottomMenuButtons = (showRouteCalculationControls || !routeFollowingMode) && vh.shouldShowBottomMenuButtons(); + boolean showBottomMenuButtons = (shouldShowRouteCalculationControls || !isRouteFollowingMode) && vh.shouldShowBottomMenuButtons(); routePlanningBtn.updateVisibility(showBottomMenuButtons); menuControl.updateVisibility(showBottomMenuButtons); - boolean showZoomButtons = !routeDialogOpened && vh.shouldShowZoomButtons(); + boolean showZoomButtons = !isRouteDialogOpened && vh.shouldShowZoomButtons(); mapZoomIn.updateVisibility(showZoomButtons); mapZoomOut.updateVisibility(showZoomButtons); - boolean forceHideCompass = routeDialogOpened || vh.shouldHideCompass(); + boolean forceHideCompass = isRouteDialogOpened || vh.shouldHideCompass(); compassHud.forceHideCompass = forceHideCompass; compassHud.updateVisibility(!forceHideCompass && shouldShowCompass()); @@ -885,7 +885,7 @@ public class MapControlsLayer extends OsmandMapLayer { if (layersHud.setIconResId(appMode.getIconRes())) { layersHud.update(app, isNight); } - boolean showTopButtons = !routeDialogOpened && vh.shouldShowTopButtons(); + boolean showTopButtons = !isRouteDialogOpened && vh.shouldShowTopButtons(); layersHud.updateVisibility(showTopButtons); quickSearchHud.updateVisibility(showTopButtons); @@ -900,7 +900,7 @@ public class MapControlsLayer extends OsmandMapLayer { zoomText.setText(getZoomLevel(tileBox)); } - mapRouteInfoMenu.setVisible(showRouteCalculationControls); + mapRouteInfoMenu.setVisible(shouldShowRouteCalculationControls); if (!forceHideCompass) { updateCompass(isNight); } From 6f5236e8b47e1c7d7e7fa82bc6861eea01cbef44 Mon Sep 17 00:00:00 2001 From: Vitaliy Date: Mon, 29 Mar 2021 23:16:37 +0300 Subject: [PATCH 092/109] Small fixes --- .../net/osmand/plus/liveupdates/LiveUpdatesFragment.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 520af19810..23d963c4e5 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -52,11 +52,11 @@ import net.osmand.plus.helpers.FontCache; import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchases.InAppSubscription; import net.osmand.plus.liveupdates.LiveUpdatesClearBottomSheet.RefreshLiveUpdates; +import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.liveupdates.LiveUpdatesHelper.TimeOfDay; import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency; import net.osmand.plus.liveupdates.LiveUpdatesSettingsBottomSheet.OnLiveUpdatesForLocalChange; import net.osmand.plus.liveupdates.LoadLiveMapsTask.LocalIndexInfoAdapter; -import net.osmand.plus.liveupdates.LiveUpdatesHelper.LiveUpdateListener; import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.widgets.TextViewEx; @@ -393,8 +393,6 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL protected class LiveMapsAdapter extends OsmandBaseExpandableListAdapter implements LocalIndexInfoAdapter { private final ArrayList mapsList = new ArrayList<>(); - private int countEnabled = 0; - private TextViewEx countView; @Override public void addData(LocalIndexInfo info) { @@ -409,11 +407,9 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL @Override public void onDataUpdated() { sort(); - countEnabled = updateCountEnabled(countView, mapsList, settings); } public void sort() { - Collections.sort(mapsList); Collections.sort(mapsList, new Comparator() { @Override public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { @@ -464,7 +460,7 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL TextViewEx titleView = ((TextViewEx) view.findViewById(R.id.title)); titleView.setText(getGroup(groupPosition)); - countView = ((TextViewEx) view.findViewById(R.id.description)); + TextViewEx countView = ((TextViewEx) view.findViewById(R.id.description)); AndroidUtils.setTextSecondaryColor(app, countView, nightMode); return view; From cd3333dd61d205bd54e5e3835e98c06c12d796b0 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Sun, 28 Mar 2021 23:56:31 +0000 Subject: [PATCH 093/109] Translated using Weblate (Ukrainian) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-uk/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-uk/phrases.xml b/OsmAnd/res/values-uk/phrases.xml index 454bd79608..578640f3c5 100644 --- a/OsmAnd/res/values-uk/phrases.xml +++ b/OsmAnd/res/values-uk/phrases.xml @@ -3894,4 +3894,5 @@ Локальне посилання Геодезист Конференц-центр + Місце для табору \ No newline at end of file From 6c531bebc7e7475776367e90569ff11677f5eb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Babos=20G=C3=A1bor?= Date: Mon, 29 Mar 2021 15:05:56 +0000 Subject: [PATCH 094/109] Translated using Weblate (Hungarian) Currently translated at 99.9% (3893 of 3895 strings) --- OsmAnd/res/values-hu/phrases.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-hu/phrases.xml b/OsmAnd/res/values-hu/phrases.xml index 8176745fa7..525e77d214 100644 --- a/OsmAnd/res/values-hu/phrases.xml +++ b/OsmAnd/res/values-hu/phrases.xml @@ -270,7 +270,7 @@ Búvárfelszerelés Barkácsáruház Horgászfelszerelés - Képkeretbolt + Képkeretező Bútorbolt Egyéb bolt Üveges @@ -3892,4 +3892,5 @@ Vágány / kocsiállás Földmérő Konferencia-központ + Sátorhely \ No newline at end of file From 86bdcb9415167645d38bdac53f3bc45ec4555010 Mon Sep 17 00:00:00 2001 From: Franco Date: Mon, 29 Mar 2021 00:43:34 +0000 Subject: [PATCH 095/109] Translated using Weblate (Spanish (Argentina)) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-es-rAR/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-es-rAR/phrases.xml b/OsmAnd/res/values-es-rAR/phrases.xml index 7d21230273..0c361ffa33 100644 --- a/OsmAnd/res/values-es-rAR/phrases.xml +++ b/OsmAnd/res/values-es-rAR/phrases.xml @@ -3894,4 +3894,5 @@ Referencia local Geodésico Centro de conferencias + Parcela de campamento \ No newline at end of file From 84a6d663f4da4e8f86c5d8873682aa72171df3ac Mon Sep 17 00:00:00 2001 From: Eduardo Addad de Oliveira Date: Mon, 29 Mar 2021 02:37:53 +0000 Subject: [PATCH 096/109] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-pt-rBR/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-pt-rBR/phrases.xml b/OsmAnd/res/values-pt-rBR/phrases.xml index 560f405680..2b9315b6d7 100644 --- a/OsmAnd/res/values-pt-rBR/phrases.xml +++ b/OsmAnd/res/values-pt-rBR/phrases.xml @@ -3894,4 +3894,5 @@ Centro de conferências Geodesia Geodesia + Campo de acampamento \ No newline at end of file From 412fa4d33d5f12b1f1c5b7c40cb4a5ddc05c7746 Mon Sep 17 00:00:00 2001 From: Shjosan Date: Mon, 29 Mar 2021 14:58:05 +0000 Subject: [PATCH 097/109] Translated using Weblate (Swedish) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-sv/phrases.xml | 504 ++++++++++++++++++++++++++++++- 1 file changed, 503 insertions(+), 1 deletion(-) diff --git a/OsmAnd/res/values-sv/phrases.xml b/OsmAnd/res/values-sv/phrases.xml index e209110762..0a5b1b8c4d 100644 --- a/OsmAnd/res/values-sv/phrases.xml +++ b/OsmAnd/res/values-sv/phrases.xml @@ -2557,7 +2557,7 @@ Explosion: enhet Husnamn Plantskola - JA + Ja Tryckluft: nej Ja Ja @@ -3393,4 +3393,506 @@ Uttag: NEMA 5-20 Uttag: NEMA 5-15R: utgång Uttag: NEMA 5-15R: ström + Lägerplats + Lokal referens + Geolog + Konferenscenter + Stoppläge för det mobila biblioteket + Toppregister: nej + Toppregister: ja + Piststatus: stängd + Piststatus: öppen + Patrullerat: ja + I skogen: ja + Pistnamn + Skidhopp + Tunnel för fladdermöss + Fladdermusbro + Korsning för vilda djur + Badplats + Lavoir + Avfallsöverföringsstation + Viktbro + Ranger-station + Sjö + Flod + Brunn + Driven pump + Vattentank + Kran + Vattenverk + Rörbrunn + Vaccination: COVID19 + Vaccination + Livräddarbas + Siren + Sjuksköterska + Agent för mobila pengar + Subnationellt + Representationskontor + Kontor + Honorärkonsulat + Generalkonsulat + Konsulat + Konsulär byrå + Leds av en konsul + Bostad + Nuntiatur + Uppdrag + Intresseavdelning + Hög provision + Delegation + Filial + Leds av en ambassadör + Förbindelse + Ambassad + Radartorn + Parkeringsficka + Skjul + Tak + GPX-punkt + LNG + Nötbutik + Bikupa + Tidtabell + Realtid + Fördröjning + Hiss + Kvarter + Kommun + Ge låda + Vibration: nej + Pumpstatus: saknad stråle + Sugning + Trycksatt + Grundvatten + Rör + Nätverk för påfyllning av dricksvatten + Påfyllning av dricksvatten: nej + Hinder + Vattennivå: över medelvattennivå + Vattennivå: under medelvattennivå + Vattennivå: flytande + Vattennivå: översvämning + Vattennivå: överflödig + Vattennivå: täcker + Vattennivå: torr + Vattennivå: nedsäkt + Vattennivå: delvis nedsänkt + Felaktig + Primitiv + Kontrastfärgad + Endast tillåtet när du går + Internetåtkomst: kunder + Bås typ + Bås + Dykcenter + Jaktbas + Referensummer för pist + Bowlingcenter + Säkerhetsbutik + Fjällräddning + Paintball + Spökcykel + Antal utbrott + Inaktiv + Aktiv + Vilande + Utdöd + Senaste utbrottet + Lera + Lavakupol + Caldera + Maar + Sköld + Stratovulkan + Scoria + URL + Parkeringsplats + Grav + Kön: bladat + Kön: man + Kön: kvinna + Turistläger + Klostertyp: kontorister regelbundet + Klostertyp: eremitage + Klostertyp: kanoneri + Klostertyp: kloster + Klostertyp: kloster + Fotbad + Sjö + Flod + Termisk + Hammam + Patrullerad: nej + Avgångstavla: nej + Nej + Nej + Nej + Pil: nej + Nej + Nej + Nej + Ja + Ja + Ja + Ja + Ja + Ja + Ja + Ja + Ja + Ja + Onsen + Varm källa + Postbank + Girokort + Migros bank + Postfinanskort + Kontantuttag: utländska kort + Kontantuttag: minsta köp + Kontantuttagsavgift: nej + Kontantuttagsavgift: ja + Kontantuttag: inget köp krävs + Kontantuttag: köp krävs + Kontantuttagvaluta + Kontantuttag gräns + Kontantuttag typ: självuttag + Kontantuttag typ: kassa + Kontantuttagoperatör + Kontantuttag + Kontantuttag: ja + Djurskötsel + Avgift + Snickare + Bageri + Golvare + Snickare + Bränneri + Byggare + Hälsokost + Källaringång + Anvisad + Ja + Anvisad + Ja + Leverans + Anvisad + Tillåtande + Destination + Ja + Anvisad + Ja + Anvisad + Ja + Anvisad + Desination + Tillåtande + Ja + Anvisad + Ja + Anvisad + Ja + Anvisad + Ja + Anvisad + Ja + Tillåtande + Anvisad + Ja + Tillgänglighet för funktionshindrade: nej + Taxiåtkomst: nej + Taxiåtkomst: anvisad + Taxiåtkomst: ja + Tillträde för jordbruksfordon: nej + Tillträde för jordbruksfordon: ja + Snöskoteråtkomst: nej + Snöskoteråtkomst: privat + Skidåtkomst: ja + Skidåtkomst: ja + Bussåtkomst: nej + Bussåtkomst: ja + Turistbussåtkomst: nej + Turistbussåtkomst: utsedd + Turistbussåtkomst: ja + Bussåtkomst: nej + PSV-åtkomst: nej + PSV-åtkomst: utsedd + PSV-åtkomst: ja + Släpvansåtkomst: nej + Husbilsåtkomst: nej + Husvangsåtkomst: nej + Fotgängareåtkomst: kunder + Fotgängareåtkomst: tillåtet + Fotgängareåtkomst: destination + Fotgängareåtkomst: nej + Fotgängareåtkomst: privat + Fotgängareåtkomst: ja + Häståtkomst: skogsbruk + Häståtkomst: tillåtet + Häståtkomst: destination + Häståtkomst: privat + Cykelåtkomst: kunder + Cykelåtkomst: tillåtet + Cyckelåtkomst: desitnation + Cykelåtkomst: gående + Cykelåtkomst: privat + Mofa-åtkomst: nej + Mopedåtkomst: nej + Motorcykelåtkomst: nej + Motorcykelåtkomst: privat + Åtkomst för lätta lastbilar: nej + HGV-åtkomst: olämpligt + HGV-åtkomst: avråds + HGV-åtkomst: jordbruk + HGV-åtkomst: nej + HGV-åtkomst: privat + Motorfordonåtkomst: jordbruk + Motorfordonåtkomst: skogsbruk + Motorfordonåtkomst: levernas + Motorfordonåtkomst: militär + Motorfordonåtkomst: kunder + Motorfordonåtkomst: tillåtet + Motorfordonåtkomst: desination + Motorfordonåtkomst: nej + Motorfordonåtkomst: privat + Motorfordonåtkomst: ja + Bilåtkomst: skogsbruk + Bilåtkomst: kunder + Bilåtkomst: tillåtet + Bilåtkomst: destination + Bilåtkomst: nej + Bilåtkomst: privat + Bilåtkomst: ja + Fordonsåtkomst: skogsbruk + Fordonsåtkomst: leverans + Fordonsåtkomst: militär + Fordonsåtkomst: kunder + Fordonsåtkomst: tillåtet + Fordonsåtkomst: destination + Fordonsåtkomst: nej + Fordonsåtkomst: privat + Fordonåtkomst: ja + Taxikontor + Vattenpipa longue + Kolhög + Avgift för skötbord: nej + Avgift för skötbord: ja + Antal skötbord + Plats för skötbord: unisextoalett + Plats för skötbord: rum + Plats för skötbord: toalett för män + Plats för skötbord: toalett för kvinnor + Skötbord: begränsat + Skötbord: nej + Skötbord: ja + Plats + Fara: kontaminering + Fara: minfält + Fara: lavin + Fara: översvämmning + Fara: nukleär + Fara: stenfall + Fara: erosion + Räddningslåda + Borttaget objekt + Gasfackla + 3B* + 3B + 3A* + 3A + 2B* + 2B + 2A* + 2A + 1B* + 1B + 1A* + 1A + n/c* + n/c + Färja + Spårvagn + HOV + Tunnelbana + Buss + Tåg + Ja + Landmärke + Naturligt monument + Barnomsorg + Vägtull + Korallö + Barn + Akademisk + Religion + Antikvarisk + Serie + Blodgivning + Medicinskt laboratorium + Partihandel + Konfektyrproduktion + Fältsamling + Inspektionsmätare + Ventilgrupp + Ventil + Mått + Kompession + Ersättning + Omvandlare + Dragkraft + Övergång + Industriell + Mindre distribution + Distribution + Överföring + Rörledningsstation + Bara + Ja + Skoreparation + Kulle + Licensklasser + Ruiner + Minfält + Översvämningsrisk + Hal väg + Lavinfara + Erosionsrisk + Kärnkraftfara + Fara + Kontaktlöst accepteras inte + Kontaktlöst + Utskjutning + Vitvarubutik + Slutdatum + Sten + Kurs + Elektronisk + Nålstift + Anteckningsbok + Kod + Stämplingspunkt + Kontrollpunkt för vandring + Genomsnittlig lutning + Lägsta punkt + Högsta punkt + Istunga + Rester + Hylla + Sten + Isfall + Hängande + Berg + Tidvatten + Utlopp + Dal + Platå + Isfält + Istäcket + Svårighetsgrad + Kabelnummer + Via ferrata + Klättringsäventyr + Zip line + Däck + Försäkring + Motor + Reparation av växellådan + Justering + Ljuddämpare + Lastbilsreparation + Glas + Hjul + Elektrisk + Reparation av kaross + Luftkonditionering + Batterier + Bildelar + Diagnostik + Försäljning av nya bilar + Bromsar + Försäljning av begagnade bilar + Oljebyte + Bilverkstad + Spelcenter för vuxna + Spelhall + Vattenverks kontor + Keramik + Golvbutik + Låg + Medium + Hög + Låg + Medium + Hög + Låg + Medium + Hög + Låg + Medium + Hög + Låg + Medium + Hög + Låg + Medium + Hög + AS/NZS 3112 + BS 1363 + Schuko + NEMA 14-50 + NEMA 14-30 + NEMA 5-20 + NEMA 5-15R + Tesla Roadster + Tesla Supercharger + Telsa-standard + CHAdeMO + Typ 3 + Typ 2 kombo + Typ 2 + Typ 1 kombo + Typ 1 + CEE röd 125A + CEE röd 64A + CEE röd 32A + CEE röd 16A + CEE blå + Cannabisbutik + Båtbutik + Butik för eldstäder + Jurdbruksbutik + Fryst mat + Typ: betesmark + Typ: övergång + Typ: evig + Typ: jordbruk + Kronans diameter + Omkrets + Klättervägar + Loggbok för toppbestigning: nej + Loggbok för toppbestigning: ja + Väggens orientering: NV + Väggens orientering: V + Väggens orientering: SV + Väggens orientering: S + Väggens orientering: SÖ + Väggens orientering: Ö + Väggens orientering: NÖ + Väggens orientering: N + Fasta ankare: nej + Fasta ankare: ja + Klätterstenkvalitet: bräcklig + Klätterstenkvalitet: solid + Klättersten: porfyr + Klättersten: gnejs + Klättersten: kvarsit + Klättersten: sandsten + Klättersten: granit + Klättersten: kalksten + Maximal klättringslängd + Minsta klättringslängd + Klättringslängd + Djupvatten solo: nej + Djupvatten solo: ja \ No newline at end of file From 7f39af3310010bfe05812138f4d47446da043bfc Mon Sep 17 00:00:00 2001 From: Verdulo Date: Sun, 28 Mar 2021 22:44:58 +0000 Subject: [PATCH 098/109] Translated using Weblate (Esperanto) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-eo/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-eo/phrases.xml b/OsmAnd/res/values-eo/phrases.xml index 51c2b11059..36abea3e77 100644 --- a/OsmAnd/res/values-eo/phrases.xml +++ b/OsmAnd/res/values-eo/phrases.xml @@ -3894,4 +3894,5 @@ Loka referenco Oficejo de geodeziisto Konferenca centro + Loko por kampadveturilo/tendo \ No newline at end of file From a31b0c1d61eef2ac0b06f518083488b42bf4457c Mon Sep 17 00:00:00 2001 From: Jeff Huang Date: Mon, 29 Mar 2021 01:58:25 +0000 Subject: [PATCH 099/109] Translated using Weblate (Chinese (Traditional)) Currently translated at 100.0% (3895 of 3895 strings) --- OsmAnd/res/values-zh-rTW/phrases.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/res/values-zh-rTW/phrases.xml b/OsmAnd/res/values-zh-rTW/phrases.xml index 56516b9292..55a13b5e8c 100644 --- a/OsmAnd/res/values-zh-rTW/phrases.xml +++ b/OsmAnd/res/values-zh-rTW/phrases.xml @@ -3894,4 +3894,5 @@ 月台/站牌編號 土地測量師 會議中心 + 營地 \ No newline at end of file From 66717cb23c3178368e6861b0a0114579e1ab6f6e Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 30 Mar 2021 10:13:11 +0300 Subject: [PATCH 100/109] after code review --- .../mapwidgets/WidgetsVisibilityHelper.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java index 7cc747c1b6..4c538ddba1 100644 --- a/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java +++ b/OsmAnd/src/net/osmand/plus/views/mapwidgets/WidgetsVisibilityHelper.java @@ -7,6 +7,7 @@ import androidx.fragment.app.Fragment; import net.osmand.plus.R; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.MapActivityLayers; import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.mapcontextmenu.MapContextMenu; import net.osmand.plus.mapcontextmenu.MapContextMenuFragment; @@ -23,11 +24,13 @@ public class WidgetsVisibilityHelper { private MapActivity mapActivity; private OsmandSettings settings; private RoutingHelper routingHelper; + private MapActivityLayers mapLayers; public WidgetsVisibilityHelper(@NonNull MapActivity mapActivity) { this.mapActivity = mapActivity; this.settings = mapActivity.getMyApplication().getSettings(); this.routingHelper = mapActivity.getRoutingHelper(); + this.mapLayers = mapActivity.getMapLayers(); } public boolean shouldShowQuickActionButton() { @@ -136,7 +139,7 @@ public class WidgetsVisibilityHelper { } private boolean isQuickActionLayerOn() { - return mapActivity.getMapLayers().getMapQuickActionLayer().isLayerOn(); + return mapLayers.getMapQuickActionLayer().isLayerOn(); } private boolean isMapRouteInfoMenuVisible() { @@ -144,37 +147,37 @@ public class WidgetsVisibilityHelper { } private boolean isInMovingMarkerMode() { - MapQuickActionLayer quickActionLayer = mapActivity.getMapLayers().getMapQuickActionLayer(); + MapQuickActionLayer quickActionLayer = mapLayers.getMapQuickActionLayer(); boolean isInMovingMarkerMode = quickActionLayer != null && quickActionLayer.isInMovingMarkerMode(); return isInMovingMarkerMode || isInChangeMarkerPositionMode() || isInAddGpxPointMode(); } private boolean isInGpxDetailsMode() { - return mapActivity.getMapLayers().getContextMenuLayer().isInGpxDetailsMode(); + return mapLayers.getContextMenuLayer().isInGpxDetailsMode(); } private boolean isInAddGpxPointMode() { - return mapActivity.getMapLayers().getContextMenuLayer().isInAddGpxPointMode(); + return mapLayers.getContextMenuLayer().isInAddGpxPointMode(); } private boolean isInChangeMarkerPositionMode() { - return mapActivity.getMapLayers().getContextMenuLayer().isInChangeMarkerPositionMode(); + return mapLayers.getContextMenuLayer().isInChangeMarkerPositionMode(); } private boolean isInMeasurementToolMode() { - return mapActivity.getMapLayers().getMeasurementToolLayer().isInMeasurementMode(); + return mapLayers.getMeasurementToolLayer().isInMeasurementMode(); } private boolean isInPlanRouteMode() { - return mapActivity.getMapLayers().getMapMarkersLayer().isInPlanRouteMode(); + return mapLayers.getMapMarkersLayer().isInPlanRouteMode(); } private boolean isInTrackAppearanceMode() { - return mapActivity.getMapLayers().getGpxLayer().isInTrackAppearanceMode(); + return mapLayers.getGpxLayer().isInTrackAppearanceMode(); } private boolean isInGpxApproximationMode() { - return mapActivity.getMapLayers().getMeasurementToolLayer().isTapsDisabled(); + return mapLayers.getMeasurementToolLayer().isTapsDisabled(); } public boolean isInTrackMenuMode() { @@ -190,7 +193,7 @@ public class WidgetsVisibilityHelper { } private boolean isInRouteLineAppearanceMode() { - return mapActivity.getMapLayers().getRouteLayer().isInRouteLineAppearanceMode(); + return mapLayers.getRouteLayer().isInRouteLineAppearanceMode(); } private boolean isInFollowTrackMode() { From 2b794f9b46c82af042055ea638b0b030a5e8801b Mon Sep 17 00:00:00 2001 From: xmd5a Date: Tue, 30 Mar 2021 10:52:54 +0300 Subject: [PATCH 101/109] Add phrases --- OsmAnd/res/values/phrases.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index 1f4afe5537..f6f6cfed0a 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4349,4 +4349,8 @@ Camp pitch + Hoops + Karate + Jiu-jitsu + From 919e488ea0b8c15992fa7a5604937cbd804041ad Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 30 Mar 2021 11:17:54 +0300 Subject: [PATCH 102/109] fix sort --- .../net/osmand/plus/liveupdates/LiveUpdatesFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java index 23d963c4e5..9f91391af3 100644 --- a/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java +++ b/OsmAnd/src/net/osmand/plus/liveupdates/LiveUpdatesFragment.java @@ -415,7 +415,11 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL public int compare(LocalIndexInfo o1, LocalIndexInfo o2) { CommonPreference preference1 = preferenceForLocalIndex(o1.getFileName(), getSettings()); CommonPreference preference2 = preferenceForLocalIndex(o2.getFileName(), getSettings()); - return preference2.get().compareTo(preference1.get()); + int prefSort = preference2.get().compareTo(preference1.get()); + if (prefSort != 0) { + return prefSort; + } + return o1.compareTo(o2); } }); notifyDataSetInvalidated(); From 446650a80e6eb38da646efbb63c70bd208b94a1a Mon Sep 17 00:00:00 2001 From: xmd5a Date: Tue, 30 Mar 2021 11:54:01 +0300 Subject: [PATCH 103/109] Add phrases --- OsmAnd/res/values/phrases.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/OsmAnd/res/values/phrases.xml b/OsmAnd/res/values/phrases.xml index f6f6cfed0a..bfe9be1e13 100644 --- a/OsmAnd/res/values/phrases.xml +++ b/OsmAnd/res/values/phrases.xml @@ -4352,5 +4352,31 @@ Hoops Karate Jiu-jitsu + Pilates + Shot put + Snooker + Speedway + Sumo + Table soccer + Taekwondo + Ultimate + Wakeboarding + Weightlifting + Wrestling + Zurkhaneh sport + Water polo + Water ski + Aikido + Biathlon + Bobsleigh + Bullfighting + Cliff diving + Cockfighting + Crossfit + Curling + Cycle polo + Fencing + Horseshoes + Kickboxing From 1affe2f6024987d860ea4fb9ffa2b6211de7df8a Mon Sep 17 00:00:00 2001 From: nazar-kutz Date: Tue, 30 Mar 2021 12:27:26 +0300 Subject: [PATCH 104/109] Fix: can't save route line appearance after select "map style" color in editing --- OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java b/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java index 838e553b5b..88a033edae 100644 --- a/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java +++ b/OsmAnd/src/net/osmand/plus/routing/RouteLineDrawInfo.java @@ -175,8 +175,8 @@ public class RouteLineDrawInfo { RouteLineDrawInfo that = (RouteLineDrawInfo) o; - if (!Algorithms.objectEquals(colorDay, that.colorDay)) return false; - if (!Algorithms.objectEquals(colorNight, that.colorNight)) return false; + if (!Algorithms.objectEquals(getColor(false), that.getColor(false))) return false; + if (!Algorithms.objectEquals(getColor(true), that.getColor(true))) return false; return Algorithms.objectEquals(width, that.width); } From 84ad07a7b5c732e7c070e1cce5749796fc600086 Mon Sep 17 00:00:00 2001 From: Dima-1 Date: Tue, 30 Mar 2021 14:27:15 +0300 Subject: [PATCH 105/109] return getTag --- .../src/main/java/net/osmand/binary/RouteDataObject.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index 5d0f842021..602a2f1682 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -584,7 +584,7 @@ public class RouteDataObject { int ks; for (ks = 0; ks < pointTypes[i].length; ks++) { RouteTypeRule toReplace = region.quickGetEncodingRule(pointTypes[i][ks]); - if (toReplace != null && toReplace.getNonConditionalTag().contentEquals(nonCondTag)) { + if (toReplace != null && toReplace.getTag().contentEquals(nonCondTag)) { break; } } From 8fe9fc99d3bf2d000f8d9558452921e6f232fe57 Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 30 Mar 2021 14:39:35 +0300 Subject: [PATCH 106/109] Favorites icon groups jump after selection. --- .../editors/PointEditorFragmentNew.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java index b8fb261f09..464e8b6375 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java @@ -619,6 +619,26 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen } private void createIconForCategory() { + createIconList(); + final HorizontalSelectionAdapter horizontalSelectionAdapter = new HorizontalSelectionAdapter(app, nightMode); + horizontalSelectionAdapter.setTitledItems(new ArrayList<>(iconCategories.keySet())); + horizontalSelectionAdapter.setSelectedItemByTitle(selectedIconCategory); + horizontalSelectionAdapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() { + @Override + public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) { + selectedIconCategory = item.getTitle(); + createIconList(); + updateIconSelector(selectedIcon, PointEditorFragmentNew.this.view); + horizontalSelectionAdapter.notifyDataSetChanged(); + } + }); + RecyclerView iconCategoriesRecyclerView = view.findViewById(R.id.group_name_recycler_view); + iconCategoriesRecyclerView.setAdapter(horizontalSelectionAdapter); + iconCategoriesRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); + } + + + private void createIconList() { FlowLayout selectIcon = view.findViewById(R.id.select_icon); selectIcon.removeAllViews(); JSONArray iconJsonArray = iconCategories.get(selectedIconCategory); @@ -631,22 +651,6 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen e.printStackTrace(); } } - HorizontalSelectionAdapter horizontalSelectionAdapter = new HorizontalSelectionAdapter(app, nightMode); - horizontalSelectionAdapter.setTitledItems(new ArrayList<>(iconCategories.keySet())); - horizontalSelectionAdapter.setSelectedItemByTitle(selectedIconCategory); - horizontalSelectionAdapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() { - @Override - public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) { - selectedIconCategory = item.getTitle(); - createIconForCategory(); - updateIconSelector(selectedIcon, PointEditorFragmentNew.this.view); - } - }); - RecyclerView iconCategoriesRecyclerView = view.findViewById(R.id.group_name_recycler_view); - iconCategoriesRecyclerView.setAdapter(horizontalSelectionAdapter); - iconCategoriesRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); - horizontalSelectionAdapter.notifyDataSetChanged(); - iconCategoriesRecyclerView.smoothScrollToPosition(horizontalSelectionAdapter.getItemPositionByTitle(selectedIconCategory)); for (String name : iconNameList) { int minimalPaddingBetweenIcon = app.getResources().getDimensionPixelSize(R.dimen.favorites_select_icon_button_right_padding); selectIcon.addView(createIconItemView(name, selectIcon), new FlowLayout.LayoutParams(minimalPaddingBetweenIcon, 0)); From 77e61515d8010ab0e8d4126fab663d1f22997090 Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 30 Mar 2021 14:46:01 +0300 Subject: [PATCH 107/109] fix replace elements "Time moving" with "Time in motion" --- OsmAnd/res/layout/gpx_item_speed.xml | 4 ++-- .../mapcontextmenu/builders/SelectedGpxMenuBuilder.java | 2 +- .../src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java | 2 +- .../net/osmand/plus/track/GpxBlockStatisticsBuilder.java | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/OsmAnd/res/layout/gpx_item_speed.xml b/OsmAnd/res/layout/gpx_item_speed.xml index 40e1d283b5..66a1d3b74b 100644 --- a/OsmAnd/res/layout/gpx_item_speed.xml +++ b/OsmAnd/res/layout/gpx_item_speed.xml @@ -200,7 +200,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" - android:text="@string/shared_string_time_moving" + android:text="@string/moving_time" android:textColor="?android:attr/textColorSecondary" android:textSize="@dimen/default_desc_text_size" /> @@ -221,7 +221,7 @@ android:layout_width="wrap_content" android:layout_height="@dimen/poi_icon_size" android:layout_marginTop="2dp" - osmand:srcCompat="@drawable/ic_action_time_span" /> + osmand:srcCompat="@drawable/ic_action_time_moving_16" /> diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java index 6005ab7215..e4c2bc71ed 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/SelectedGpxMenuBuilder.java @@ -70,7 +70,7 @@ public class SelectedGpxMenuBuilder extends MenuBuilder { String timeSpan = Algorithms.formatDuration((int) (analysis.timeSpan / 1000), app.accessibilityEnabled()); String timeMoving = Algorithms.formatDuration((int) (analysis.timeMoving / 1000), app.accessibilityEnabled()); - String timeSpanTitle = app.getString(R.string.shared_string_time_span) + " / " + app.getString(R.string.shared_string_time_moving); + String timeSpanTitle = app.getString(R.string.shared_string_time_span) + " / " + app.getString(R.string.moving_time); buildRow(view, getThemedIcon(R.drawable.ic_action_time_span), null, timeSpanTitle, timeSpan + " / " + timeMoving, 0, null, false, null, false, 0, false, false, false, null, false); diff --git a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java index 8f0c5a1dc5..6f5083d8b2 100644 --- a/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java +++ b/OsmAnd/src/net/osmand/plus/myplaces/GPXItemPagerAdapter.java @@ -308,7 +308,7 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid ((ImageView) view.findViewById(R.id.max_icon)) .setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_max_speed)); ((ImageView) view.findViewById(R.id.time_moving_icon)) - .setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_span)); + .setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_time_moving_16)); ((ImageView) view.findViewById(R.id.distance_icon)) .setImageDrawable(iconsCache.getThemedIcon(R.drawable.ic_action_polygom_dark)); diff --git a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java index 35ee1e08bb..d4bef49ecf 100644 --- a/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java +++ b/OsmAnd/src/net/osmand/plus/track/GpxBlockStatisticsBuilder.java @@ -253,10 +253,8 @@ public class GpxBlockStatisticsBuilder { } public void prepareDataTimeMoving(long timeMoving) { - prepareData(app.getString(tabItem == GPX_TAB_ITEM_SPEED ? R.string.shared_string_time_moving : R.string.moving_time), - Algorithms.formatDuration((int) (timeMoving / 1000), app.accessibilityEnabled()), - tabItem == GPX_TAB_ITEM_SPEED ? R.drawable.ic_action_time_span_16 : R.drawable.ic_action_time_moving_16, - GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_MOVING); + prepareData(app.getString(R.string.moving_time), Algorithms.formatDuration((int) (timeMoving / 1000), app.accessibilityEnabled()), + R.drawable.ic_action_time_moving_16, GPXDataSetType.SPEED, null, ItemType.ITEM_TIME_MOVING); } public void prepareDataDistanceCorrected(float totalDistanceMoving) { From 69d4c717654140587eb28989684a3c917361bd9e Mon Sep 17 00:00:00 2001 From: androiddevkotlin <64539346+androiddevkotlin@users.noreply.github.com> Date: Tue, 30 Mar 2021 15:06:07 +0300 Subject: [PATCH 108/109] Fix scroll after open edit favorite point --- .../plus/mapcontextmenu/editors/PointEditorFragmentNew.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java index 464e8b6375..b00ff19efd 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/editors/PointEditorFragmentNew.java @@ -635,6 +635,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment implemen RecyclerView iconCategoriesRecyclerView = view.findViewById(R.id.group_name_recycler_view); iconCategoriesRecyclerView.setAdapter(horizontalSelectionAdapter); iconCategoriesRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false)); + iconCategoriesRecyclerView.scrollToPosition(horizontalSelectionAdapter.getItemPositionByTitle(selectedIconCategory)); } From a24d5e607ae0a683aba3d91aa6ac083b98a27c0a Mon Sep 17 00:00:00 2001 From: Skalii Date: Tue, 30 Mar 2021 17:33:38 +0300 Subject: [PATCH 109/109] fix empty altitude in favorites; --- .../src/main/java/net/osmand/binary/RouteDataObject.java | 5 +++-- OsmAnd/src/net/osmand/data/FavouritePoint.java | 2 +- .../src/net/osmand/plus/mapcontextmenu/MapContextMenu.java | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java index 602a2f1682..6e063b8ecb 100644 --- a/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java +++ b/OsmAnd-java/src/main/java/net/osmand/binary/RouteDataObject.java @@ -38,7 +38,7 @@ public class RouteDataObject { public int[] nameIds; // mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2 public float[] heightDistanceArray = null; - public float heightByCurrentLocation; + public float heightByCurrentLocation = Float.NaN; private static final Log LOG = PlatformUtil.getLog(RouteDataObject.class); public RouteDataObject(RouteRegion region) { @@ -185,7 +185,8 @@ public class RouteDataObject { heightDistanceArray = new float[2 * getPointsLength()]; double plon = 0; double plat = 0; - float prevHeight = heightByCurrentLocation = startHeight; + float prevHeight = startHeight; + heightByCurrentLocation = Float.NaN; double prevDistance = 0; for (int k = 0; k < getPointsLength(); k++) { double lon = MapUtils.get31LongitudeX(getPoint31XTile(k)); diff --git a/OsmAnd/src/net/osmand/data/FavouritePoint.java b/OsmAnd/src/net/osmand/data/FavouritePoint.java index f87083363f..414299e575 100644 --- a/OsmAnd/src/net/osmand/data/FavouritePoint.java +++ b/OsmAnd/src/net/osmand/data/FavouritePoint.java @@ -45,7 +45,7 @@ public class FavouritePoint implements Serializable, LocationPoint { private boolean visible = true; private SpecialPointType specialPointType = null; private BackgroundType backgroundType = null; - private double altitude; + private double altitude = Double.NaN; private long timestamp; public FavouritePoint() { diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java index 38bf3feb78..cf032a5393 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MapContextMenu.java @@ -1036,7 +1036,7 @@ public class MapContextMenu extends MenuTitleController implements StateChangedL title = ""; } String originObjectName = ""; - double altitude = 0; + double altitude = Double.NaN; long timestamp = System.currentTimeMillis(); Object object = getObject(); if (object != null) {