[android] Unify custom map server dialog logic and UI

- Add setting icon for custom map server download option.
- Extract shared custom map server dialog helper.
- Clean up based on reviewers' feedback.

Signed-off-by: NoelClick <dev@noel.click>
This commit is contained in:
NoelClick
2025-12-03 12:18:12 -08:00
committed by jeanbaptisteC
parent 76ecd8209e
commit 2b630964d0
15 changed files with 147 additions and 170 deletions

View File

@@ -13,15 +13,11 @@ import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeStartNex
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
@@ -29,18 +25,16 @@ import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.core.view.ViewCompat;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.checkbox.MaterialCheckBox;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.google.android.material.textview.MaterialTextView;
import app.organicmaps.base.BaseMwmFragmentActivity;
import app.organicmaps.dialog.CustomMapServerDialog;
import app.organicmaps.downloader.MapManagerHelper;
import app.organicmaps.intent.Factory;
import app.organicmaps.sdk.Framework;
@@ -281,7 +275,11 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
mChbDownloadCountry = findViewById(R.id.chb_download_country);
mBtnAdvanced = findViewById(R.id.btn_advanced);
mBtnAdvanced.setOnClickListener(v -> openCustomServerDialog());
mBtnAdvanced.setOnClickListener(v -> {
CustomMapServerDialog.show(this, url -> {
prepareFilesDownload(false);
});
});
mBtnAdvanced.setEnabled(true);
mBtnListeners = new View.OnClickListener[BTN_COUNT];
@@ -414,56 +412,6 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
}
}
private void openCustomServerDialog()
{
View dialogView = getLayoutInflater().inflate(R.layout.dialog_custom_map_server, null);
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
edit.setText(current);
MaterialAlertDialogBuilder builder =
new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.download_resources_custom_url_title)
.setMessage(R.string.download_resources_custom_url_message)
.setView(dialogView)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.save, null);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(d -> {
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
ok.setOnClickListener(v -> {
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
if (!url.isEmpty()
&& !url.startsWith("http://")
&& !url.startsWith("https://")) {
til.setError(getString(R.string.download_resources_custom_url_error_scheme));
return;
}
til.setError(null);
prefs.edit()
.putString(getString(R.string.pref_custom_map_download_url), url)
.apply();
// Apply to native + reset meta configs
Framework.applyCustomMapDownloadUrl(this, url);
// Recompute total bytes (it can change with another server)
prepareFilesDownload(false);
dialog.dismiss();
});
});
dialog.show();
}
private void showErrorDialog(int result)
{
if (mAlertDialog != null && mAlertDialog.isShowing())

View File

@@ -0,0 +1,86 @@
package app.organicmaps.dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.PreferenceManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import app.organicmaps.R;
import app.organicmaps.sdk.Framework;
public final class CustomMapServerDialog
{
public interface OnUrlAppliedListener
{
void onUrlApplied(@NonNull String url);
}
private CustomMapServerDialog() {}
public static void show(@NonNull Context context,
@Nullable OnUrlAppliedListener listener)
{
View dialogView = LayoutInflater.from(context)
.inflate(R.layout.dialog_custom_map_server, null);
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(context);
String current = prefs.getString(context.getString(R.string.pref_custom_map_download_url), "");
edit.setText(current);
MaterialAlertDialogBuilder builder =
new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog)
.setTitle(R.string.download_resources_custom_url_title)
.setMessage(R.string.download_resources_custom_url_message)
.setView(dialogView)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.save, null);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(dlg -> {
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
ok.setOnClickListener(v -> {
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
if (!url.isEmpty()
&& !url.startsWith("http://")
&& !url.startsWith("https://"))
{
til.setError(context.getString(R.string.download_resources_custom_url_error_scheme));
return;
}
til.setError(null);
String normalizedUrl = Framework.normalizeServerUrl(url);
prefs.edit()
.putString(context.getString(R.string.pref_custom_map_download_url), normalizedUrl)
.apply();
// Apply to native
Framework.applyCustomMapDownloadUrl(context, normalizedUrl);
if (listener != null)
listener.onUrlApplied(normalizedUrl);
dialog.dismiss();
});
});
dialog.show();
}
}

View File

@@ -3,17 +3,13 @@ package app.organicmaps.settings;
import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
@@ -21,11 +17,10 @@ import androidx.preference.PreferenceManager;
import androidx.preference.TwoStatePreference;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import app.organicmaps.MwmApplication;
import app.organicmaps.R;
import app.organicmaps.dialog.CustomMapServerDialog;
import app.organicmaps.downloader.OnmapDownloader;
import app.organicmaps.editor.LanguagesFragment;
import app.organicmaps.editor.ProfileActivity;
@@ -555,79 +550,25 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
String normalized = current.trim();
if (!normalized.isEmpty() && !normalized.endsWith("/"))
normalized = normalized + "/";
String normalizedUrl = Framework.normalizeServerUrl(current);
// Initial summary
customUrlPref.setSummary(normalized.isEmpty()
customUrlPref.setSummary(normalizedUrl.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: normalized);
: normalizedUrl);
// Sync native
Framework.applyCustomMapDownloadUrl(requireContext(), normalized);
Framework.applyCustomMapDownloadUrl(requireContext(), normalizedUrl);
// Show dialog
customUrlPref.setOnPreferenceClickListener(preference -> {
openCustomServerDialog(customUrlPref);
return true;
});
}
private void openCustomServerDialog(Preference pref)
{
View dialogView = LayoutInflater.from(requireContext())
.inflate(R.layout.dialog_custom_map_server, null);
TextInputLayout til = dialogView.findViewById(R.id.til_custom_map_server);
TextInputEditText edit = dialogView.findViewById(R.id.edit_custom_map_server);
SharedPreferences prefs =
PreferenceManager.getDefaultSharedPreferences(requireContext());
String current = prefs.getString(getString(R.string.pref_custom_map_download_url), "");
edit.setText(current);
MaterialAlertDialogBuilder builder =
new MaterialAlertDialogBuilder(requireContext(), R.style.MwmTheme_AlertDialog)
.setTitle(R.string.download_resources_custom_url_title)
.setMessage(R.string.download_resources_custom_url_message)
.setView(dialogView)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.save, null);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(dlg -> {
Button ok = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
ok.setOnClickListener(v -> {
String url = edit.getText() != null ? edit.getText().toString().trim() : "";
if (!url.isEmpty()
&& !url.startsWith("http://")
&& !url.startsWith("https://")) {
til.setError(getString(R.string.download_resources_custom_url_error_scheme));
return;
}
til.setError(null);
if (!url.isEmpty() && !url.endsWith("/"))
url = url + "/";
prefs.edit()
.putString(getString(R.string.pref_custom_map_download_url), url)
.apply();
// Apply native
Framework.applyCustomMapDownloadUrl(requireContext(), url);
pref.setSummary(url.isEmpty()
CustomMapServerDialog.show(requireContext(), url -> {
preference.setSummary(url.isEmpty()
? getString(R.string.download_resources_custom_url_summary_none)
: url);
dialog.dismiss();
});
return true;
});
dialog.show();
}
private void removePreference(@NonNull String categoryKey, @NonNull Preference preference)