Merge pull request #8831 from osmandapp/custom_downloads_improvements
Custom downloads improvements first part
This commit is contained in:
commit
549933f0b6
20 changed files with 392 additions and 89 deletions
|
@ -49,7 +49,7 @@ public class Algorithms {
|
|||
return map == null || map.size() == 0;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String s) {
|
||||
public static boolean isEmpty(CharSequence s) {
|
||||
return s == null || s.length() == 0;
|
||||
}
|
||||
|
||||
|
|
17
OsmAnd/res/layout/download_description_button.xml
Normal file
17
OsmAnd/res/layout/download_description_button.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<net.osmand.plus.widgets.TextViewEx xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/button_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:letterSpacing="@dimen/description_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding_half"
|
||||
android:paddingTop="@dimen/content_padding_half"
|
||||
android:paddingRight="@dimen/content_padding_half"
|
||||
android:paddingBottom="@dimen/content_padding_half"
|
||||
android:textColor="?attr/active_color_basic"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
app:typeface="@string/font_roboto_medium"
|
||||
tools:text="@string/read_more" />
|
45
OsmAnd/res/layout/group_description_item.xml
Normal file
45
OsmAnd/res/layout/group_description_item.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="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:background="?attr/card_and_list_background_basic">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/list_header_settings_top_margin">
|
||||
|
||||
<net.osmand.plus.LockableViewPager
|
||||
android:id="@+id/images_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="132dp" />
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||
android:paddingLeft="@dimen/content_padding"
|
||||
android:paddingTop="@dimen/list_header_settings_top_margin"
|
||||
android:paddingRight="@dimen/content_padding"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size"
|
||||
app:typeface="@string/font_roboto_regular"
|
||||
tools:text="@string/plugin_disabled_descr" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/buttons_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/content_padding_half"
|
||||
android:layout_marginTop="@dimen/list_header_settings_top_margin"
|
||||
android:layout_marginRight="@dimen/content_padding_half"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/plugin_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:adjustViewBounds="true"
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="download_unsupported_action">Unsupported action %1$s</string>
|
||||
<string name="extra_maps_menu_group">Extra maps</string>
|
||||
<string name="custom_color">Custom color</string>
|
||||
<string name="lang_lmo">Lombard</string>
|
||||
|
|
|
@ -44,12 +44,16 @@ public class JsonUtils {
|
|||
}
|
||||
|
||||
public static Map<String, String> getLocalizedMapFromJson(String key, JSONObject json) throws JSONException {
|
||||
Map<String, String> localizedMap = new HashMap<>();
|
||||
JSONObject jsonObject = json.optJSONObject(key);
|
||||
if (jsonObject != null) {
|
||||
for (Iterator<String> it = jsonObject.keys(); it.hasNext(); ) {
|
||||
return getLocalizedMapFromJson(jsonObject);
|
||||
}
|
||||
|
||||
public static Map<String, String> getLocalizedMapFromJson(JSONObject json) throws JSONException {
|
||||
Map<String, String> localizedMap = new HashMap<>();
|
||||
if (json != null) {
|
||||
for (Iterator<String> it = json.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
String name = jsonObject.getString(localeKey);
|
||||
String name = json.getString(localeKey);
|
||||
localizedMap.put(localeKey, name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus;
|
|||
import android.app.Activity;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Html;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -86,8 +87,9 @@ public class CustomOsmandPlugin extends OsmandPlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return JsonUtils.getLocalizedResFromMap(app, descriptions, null);
|
||||
public CharSequence getDescription() {
|
||||
String description = JsonUtils.getLocalizedResFromMap(app, descriptions, null);
|
||||
return description != null ? Html.fromHtml(description) : null;
|
||||
}
|
||||
|
||||
public String getResourceDirName() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.plus;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.JsonUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -8,6 +9,7 @@ import net.osmand.map.WorldRegion;
|
|||
import net.osmand.plus.download.CustomIndexItem;
|
||||
import net.osmand.plus.download.DownloadActivityType;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.download.ui.DownloadDescriptionInfo;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
@ -31,10 +33,11 @@ public class CustomRegion extends WorldRegion {
|
|||
private String parentPath;
|
||||
private String type;
|
||||
private String subfolder;
|
||||
private String headerButton;
|
||||
|
||||
private JSONArray downloadItemsJson;
|
||||
|
||||
private DownloadDescriptionInfo descriptionInfo;
|
||||
|
||||
private Map<String, String> names = new HashMap<>();
|
||||
private Map<String, String> icons = new HashMap<>();
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
|
@ -66,6 +69,11 @@ public class CustomRegion extends WorldRegion {
|
|||
return headerColor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DownloadDescriptionInfo getDescriptionInfo() {
|
||||
return descriptionInfo;
|
||||
}
|
||||
|
||||
public static CustomRegion fromJson(JSONObject object) throws JSONException {
|
||||
String scopeId = object.optString("scope-id", null);
|
||||
String path = object.optString("path", null);
|
||||
|
@ -90,7 +98,6 @@ public class CustomRegion extends WorldRegion {
|
|||
region.icons = JsonUtils.getLocalizedMapFromJson("icon", object);
|
||||
region.headers = JsonUtils.getLocalizedMapFromJson("header", object);
|
||||
|
||||
region.headerButton = object.optString("header-button", null);
|
||||
region.downloadItemsJson = object.optJSONArray("items");
|
||||
|
||||
String headerColor = object.optString("header-color", null);
|
||||
|
@ -99,10 +106,31 @@ public class CustomRegion extends WorldRegion {
|
|||
} catch (IllegalArgumentException e) {
|
||||
region.headerColor = 0;
|
||||
}
|
||||
region.descriptionInfo = DownloadDescriptionInfo.fromJson(object.optJSONObject("description"));
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
||||
jsonObject.putOpt("scope-id", scopeId);
|
||||
jsonObject.putOpt("path", path);
|
||||
jsonObject.putOpt("type", type);
|
||||
jsonObject.putOpt("subfolder", subfolder);
|
||||
|
||||
JsonUtils.writeLocalizedMapToJson("name", jsonObject, names);
|
||||
JsonUtils.writeLocalizedMapToJson("icon", jsonObject, icons);
|
||||
JsonUtils.writeLocalizedMapToJson("header", jsonObject, headers);
|
||||
|
||||
if (descriptionInfo != null) {
|
||||
jsonObject.putOpt("description", descriptionInfo.toJson());
|
||||
}
|
||||
jsonObject.putOpt("items", downloadItemsJson);
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public List<IndexItem> loadIndexItems() {
|
||||
List<IndexItem> items = new ArrayList<>();
|
||||
if (downloadItemsJson != null) {
|
||||
|
@ -152,22 +180,4 @@ public class CustomRegion extends WorldRegion {
|
|||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
||||
jsonObject.putOpt("scope-id", scopeId);
|
||||
jsonObject.putOpt("path", path);
|
||||
jsonObject.putOpt("type", type);
|
||||
jsonObject.putOpt("subfolder", subfolder);
|
||||
jsonObject.putOpt("header-button", headerButton);
|
||||
|
||||
JsonUtils.writeLocalizedMapToJson("name", jsonObject, names);
|
||||
JsonUtils.writeLocalizedMapToJson("icon", jsonObject, icons);
|
||||
JsonUtils.writeLocalizedMapToJson("header", jsonObject, headers);
|
||||
|
||||
jsonObject.putOpt("items", downloadItemsJson);
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
|
@ -67,8 +67,6 @@ public class OsmAndAppCustomization {
|
|||
|
||||
private Map<String, Bitmap> navDrawerLogos = new HashMap<>();
|
||||
|
||||
private ArrayList<String> navDrawerParams;
|
||||
|
||||
private String navDrawerFooterIntent;
|
||||
private String navDrawerFooterAppName;
|
||||
private String navDrawerFooterPackageName;
|
||||
|
@ -254,8 +252,8 @@ public class OsmAndAppCustomization {
|
|||
}
|
||||
|
||||
@Nullable
|
||||
public ArrayList<String> getNavDrawerLogoParams() {
|
||||
return navDrawerParams;
|
||||
public String getNavDrawerLogoUrl() {
|
||||
return app.getSettings().NAV_DRAWER_URL.get();
|
||||
}
|
||||
|
||||
public boolean setNavDrawerLogo(String uri, @Nullable String packageName, @Nullable String intent) {
|
||||
|
@ -300,10 +298,8 @@ public class OsmAndAppCustomization {
|
|||
} catch (IOException e) {
|
||||
LOG.error("Failed to write file", e);
|
||||
}
|
||||
if (packageName != null && intent != null) {
|
||||
navDrawerParams = new ArrayList<>();
|
||||
navDrawerParams.add(packageName);
|
||||
navDrawerParams.add(intent);
|
||||
if (!Algorithms.isEmpty(intent)) {
|
||||
app.getSettings().NAV_DRAWER_LOGO.set(intent);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -85,7 +85,7 @@ public abstract class OsmandPlugin {
|
|||
|
||||
public abstract String getName();
|
||||
|
||||
public abstract String getDescription();
|
||||
public abstract CharSequence getDescription();
|
||||
|
||||
@Nullable
|
||||
public Drawable getAssetResourceImage() {
|
||||
|
|
|
@ -1453,7 +1453,8 @@ public class OsmandSettings {
|
|||
|
||||
public final CommonPreference<String> API_NAV_DRAWER_ITEMS_JSON = new StringPreference("api_nav_drawer_items_json", "{}").makeGlobal();
|
||||
public final CommonPreference<String> API_CONNECTED_APPS_JSON = new StringPreference("api_connected_apps_json", "[]").makeGlobal();
|
||||
public final CommonPreference<String> NAV_DRAWER_LOGO = new StringPreference("nav_drawer_logo", "").makeProfile();
|
||||
public final CommonPreference<String> NAV_DRAWER_LOGO = new StringPreference("drawer_logo", "").makeProfile();
|
||||
public final CommonPreference<String> NAV_DRAWER_URL = new StringPreference("drawer_url", "").makeProfile();
|
||||
|
||||
public final CommonPreference<Integer> NUMBER_OF_STARTS_FIRST_XMAS_SHOWN = new IntPreference("number_of_starts_first_xmas_shown", 0).makeGlobal();
|
||||
|
||||
|
|
|
@ -981,8 +981,9 @@ public class SettingsHelper {
|
|||
|
||||
@Override
|
||||
void readItemsFromJson(@NonNull JSONObject json) throws IllegalArgumentException {
|
||||
JSONObject prefsJson = json.optJSONObject("prefs");
|
||||
try {
|
||||
JSONObject drawerLogoJson = json.has("drawerLogo") ? json.getJSONObject("drawerLogo") : null;
|
||||
JSONObject drawerLogoJson = prefsJson.optJSONObject("drawer_logo");
|
||||
if (drawerLogoJson != null) {
|
||||
for (Iterator<String> it = drawerLogoJson.keys(); it.hasNext(); ) {
|
||||
String localeKey = it.next();
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.app.Dialog;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
@ -55,6 +56,7 @@ import net.osmand.plus.dialogs.FavoriteDialogs;
|
|||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.liveupdates.OsmLiveActivity;
|
||||
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
|
||||
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment.ContextMenuItemClickListener;
|
||||
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
|
||||
import net.osmand.plus.mapmarkers.MarkersPlanRouteContext;
|
||||
import net.osmand.plus.measurementtool.MeasurementToolFragment;
|
||||
|
@ -64,11 +66,11 @@ import net.osmand.plus.routepreparationmenu.WaypointsFragment;
|
|||
import net.osmand.plus.routing.RouteProvider.GPXRouteParamsBuilder;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.settings.BaseSettingsFragment;
|
||||
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment.ContextMenuItemClickListener;
|
||||
import net.osmand.plus.views.BaseMapLayer;
|
||||
import net.osmand.plus.views.MapControlsLayer;
|
||||
import net.osmand.plus.views.MapTileLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.wikipedia.WikipediaDialogFragment;
|
||||
import net.osmand.plus.wikivoyage.WikivoyageWelcomeDialogFragment;
|
||||
import net.osmand.plus.wikivoyage.data.TravelDbHelper;
|
||||
import net.osmand.plus.wikivoyage.explore.WikivoyageExploreActivity;
|
||||
|
@ -1144,28 +1146,8 @@ public class MapActivityActions implements DialogProvider {
|
|||
menu.show();
|
||||
}
|
||||
|
||||
public void restoreOrReturnDialog(final String packageName) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mapActivity);
|
||||
builder.setTitle("Restore OsmAnd");
|
||||
builder.setMessage("Do you want to Restore OsmAnd or get back to the Client App?");
|
||||
builder.setPositiveButton("Restore", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
restoreOsmand();
|
||||
}
|
||||
});
|
||||
builder.setNeutralButton("Return", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
executeHeadersIntent(packageName);
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("Cancel", null);
|
||||
builder.show();
|
||||
}
|
||||
|
||||
protected void updateDrawerMenu() {
|
||||
boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
||||
final boolean nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
||||
final ListView menuItemsListView = (ListView) mapActivity.findViewById(R.id.menuItems);
|
||||
if (nightMode) {
|
||||
menuItemsListView.setBackgroundColor(ContextCompat.getColor(mapActivity, R.color.list_background_color_dark));
|
||||
|
@ -1174,7 +1156,6 @@ public class MapActivityActions implements DialogProvider {
|
|||
}
|
||||
menuItemsListView.removeHeaderView(drawerLogoHeader);
|
||||
Bitmap navDrawerLogo = getMyApplication().getAppCustomization().getNavDrawerLogo();
|
||||
final ArrayList<String> navDrawerLogoParams = getMyApplication().getAppCustomization().getNavDrawerLogoParams();
|
||||
|
||||
if (navDrawerLogo != null) {
|
||||
drawerLogoHeader.setImageBitmap(navDrawerLogo);
|
||||
|
@ -1193,8 +1174,9 @@ public class MapActivityActions implements DialogProvider {
|
|||
boolean hasHeader = menuItemsListView.getHeaderViewsCount() > 0;
|
||||
boolean hasFooter = menuItemsListView.getFooterViewsCount() > 0;
|
||||
if (hasHeader && position == 0 || (hasFooter && position == menuItemsListView.getCount() - 1)) {
|
||||
if (navDrawerLogoParams != null) {
|
||||
executeHeadersIntent(navDrawerLogoParams.get(0));
|
||||
String drawerLogoParams = getMyApplication().getAppCustomization().getNavDrawerLogoUrl();
|
||||
if (!Algorithms.isEmpty(drawerLogoParams)) {
|
||||
WikipediaDialogFragment.showFullArticle(mapActivity, Uri.parse(drawerLogoParams), nightMode);
|
||||
}
|
||||
} else {
|
||||
position -= menuItemsListView.getHeaderViewsCount();
|
||||
|
@ -1209,20 +1191,4 @@ public class MapActivityActions implements DialogProvider {
|
|||
|
||||
});
|
||||
}
|
||||
|
||||
private void executeHeadersIntent(String packageName) {
|
||||
Intent launchIntent = mapActivity.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
if(launchIntent!=null) mapActivity.startActivity(launchIntent);
|
||||
mapActivity.closeDrawer();
|
||||
}
|
||||
|
||||
private void showReturnConfirmationDialog(String packageName) {
|
||||
restoreOrReturnDialog(packageName);
|
||||
mapActivity.closeDrawer();
|
||||
}
|
||||
|
||||
private void restoreOsmand(){
|
||||
getMyApplication().getAppCustomization().restoreOsmand();
|
||||
mapActivity.closeDrawer();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import android.graphics.drawable.Drawable;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -15,9 +16,11 @@ import android.widget.CompoundButton;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -74,7 +77,15 @@ public class PluginActivity extends OsmandActionBarActivity implements Download
|
|||
TextView descriptionView = (TextView) findViewById(R.id.plugin_description);
|
||||
descriptionView.setText(plugin.getDescription());
|
||||
|
||||
Button settingsButton = (Button)findViewById(R.id.plugin_settings);
|
||||
boolean light = getMyApplication().getSettings().isLightContent();
|
||||
int linkTextColor = ContextCompat.getColor(this,
|
||||
light ? R.color.ctx_menu_bottom_view_url_color_light : R.color.ctx_menu_bottom_view_url_color_dark);
|
||||
|
||||
descriptionView.setLinkTextColor(linkTextColor);
|
||||
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
AndroidUtils.removeLinkUnderline(descriptionView);
|
||||
|
||||
Button settingsButton = (Button) findViewById(R.id.plugin_settings);
|
||||
settingsButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
@ -17,6 +18,7 @@ import android.widget.TextView;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
|
@ -182,6 +184,14 @@ public class PluginsActivity extends OsmandListActivity implements DownloadIndex
|
|||
name = plugin.getName();
|
||||
pluginDescription.setText(plugin.getDescription());
|
||||
|
||||
boolean light = getMyApplication().getSettings().isLightContent();
|
||||
int linkTextColor = ContextCompat.getColor(PluginsActivity.this,
|
||||
light ? R.color.ctx_menu_bottom_view_url_color_light : R.color.ctx_menu_bottom_view_url_color_dark);
|
||||
|
||||
pluginDescription.setLinkTextColor(linkTextColor);
|
||||
pluginDescription.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
AndroidUtils.removeLinkUnderline(pluginDescription);
|
||||
|
||||
OsmandApplication app = getMyApplication();
|
||||
int color = AndroidUtils.getColorFromAttr(app, R.attr.list_background_color);
|
||||
pluginLogo.setImageDrawable(UiUtilities.tintDrawable(plugin.getLogoResource(), color));
|
||||
|
|
|
@ -110,8 +110,9 @@ public class BottomSheetItemWithDescription extends SimpleBottomSheetItem {
|
|||
return this;
|
||||
}
|
||||
|
||||
public void setDescriptionLinksClickable(boolean descriptionLinksClickable) {
|
||||
public Builder setDescriptionLinksClickable(boolean descriptionLinksClickable) {
|
||||
this.descriptionLinksClickable = descriptionLinksClickable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BottomSheetItemWithDescription create() {
|
||||
|
|
|
@ -109,6 +109,7 @@ public class PluginInstalledBottomSheetDialog extends MenuBottomSheetDialogFragm
|
|||
setupHeightAndBackground(getView());
|
||||
}
|
||||
})
|
||||
.setDescriptionLinksClickable(true)
|
||||
.setDescription(plugin.getDescription())
|
||||
.setDescriptionMaxLines(COLLAPSED_DESCRIPTION_LINES)
|
||||
.setLayoutId(R.layout.bottom_sheet_item_with_expandable_descr)
|
||||
|
|
|
@ -470,7 +470,7 @@ public class DownloadResources extends DownloadResourceGroup {
|
|||
mainGrp.addGroup(flatFiles);
|
||||
}
|
||||
}
|
||||
DownloadResourceGroup subRegions = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.SUBREGIONS);
|
||||
DownloadResourceGroup subRegions = new DownloadResourceGroup(mainGrp, DownloadResourceGroupType.EXTRA_MAPS);
|
||||
mainGrp.addGroup(subRegions);
|
||||
// add to processing queue
|
||||
for (WorldRegion rg : subregions) {
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
package net.osmand.plus.download.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Html;
|
||||
|
||||
import net.osmand.JsonUtils;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DownloadDescriptionInfo {
|
||||
|
||||
private static final Log LOG = PlatformUtil.getLog(DownloadDescriptionInfo.class);
|
||||
|
||||
private JSONArray buttonsJson;
|
||||
private List<String> imageUrls;
|
||||
private Map<String, String> texts;
|
||||
|
||||
public List<String> getImageUrls() {
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
public CharSequence getLocalizedDescription(Context ctx) {
|
||||
String description = JsonUtils.getLocalizedResFromMap(ctx, texts, null);
|
||||
return description != null ? Html.fromHtml(description) : null;
|
||||
}
|
||||
|
||||
public List<ActionButton> getActionButtons(Context ctx) {
|
||||
List<ActionButton> actionButtons = new ArrayList<>();
|
||||
if (buttonsJson != null) {
|
||||
try {
|
||||
for (int i = 0; i < buttonsJson.length(); i++) {
|
||||
String url = null;
|
||||
String actionType = null;
|
||||
|
||||
JSONObject object = buttonsJson.getJSONObject(i);
|
||||
if (object.has("url")) {
|
||||
url = object.optString("url");
|
||||
} else if (object.has("action")) {
|
||||
actionType = object.optString("action");
|
||||
}
|
||||
Map<String, String> localizedMap = JsonUtils.getLocalizedMapFromJson(object);
|
||||
String name = JsonUtils.getLocalizedResFromMap(ctx, localizedMap, null);
|
||||
|
||||
ActionButton actionButton = new ActionButton(actionType, name, url);
|
||||
actionButtons.add(actionButton);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return actionButtons;
|
||||
}
|
||||
|
||||
public static DownloadDescriptionInfo fromJson(JSONObject json) {
|
||||
if (json != null) {
|
||||
DownloadDescriptionInfo downloadDescriptionInfo = new DownloadDescriptionInfo();
|
||||
try {
|
||||
downloadDescriptionInfo.texts = JsonUtils.getLocalizedMapFromJson("text", json);
|
||||
downloadDescriptionInfo.imageUrls = JsonUtils.jsonArrayToList("image", json);
|
||||
downloadDescriptionInfo.buttonsJson = json.optJSONArray("button");
|
||||
} catch (JSONException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return downloadDescriptionInfo;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public JSONObject toJson() throws JSONException {
|
||||
JSONObject descrJson = new JSONObject();
|
||||
|
||||
JsonUtils.writeLocalizedMapToJson("text", descrJson, texts);
|
||||
JsonUtils.writeStringListToJson("image", descrJson, imageUrls);
|
||||
|
||||
descrJson.putOpt("button", buttonsJson);
|
||||
|
||||
return descrJson;
|
||||
}
|
||||
|
||||
public static class ActionButton {
|
||||
|
||||
private String actionType;
|
||||
private String name;
|
||||
private String url;
|
||||
|
||||
public ActionButton(String actionType, String name, String url) {
|
||||
this.actionType = actionType;
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.app.ProgressDialog;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
|
@ -21,15 +22,22 @@ import android.widget.ExpandableListView.OnChildClickListener;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.view.MenuItemCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
|
||||
import com.squareup.picasso.Callback;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import net.osmand.AndroidNetworkUtils;
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.PicassoUtils;
|
||||
import net.osmand.plus.CustomRegion;
|
||||
import net.osmand.plus.LockableViewPager;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.UiUtilities;
|
||||
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||
|
@ -43,9 +51,12 @@ import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
|
|||
import net.osmand.plus.download.DownloadResources;
|
||||
import net.osmand.plus.download.DownloadValidationManager;
|
||||
import net.osmand.plus.download.IndexItem;
|
||||
import net.osmand.plus.download.ui.DownloadDescriptionInfo.ActionButton;
|
||||
import net.osmand.plus.helpers.AndroidUiHelper;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
|
||||
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseTaskType;
|
||||
import net.osmand.plus.wikipedia.WikipediaDialogFragment;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONException;
|
||||
|
@ -77,13 +88,15 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
private View searchView;
|
||||
private View restorePurchasesView;
|
||||
private View subscribeEmailView;
|
||||
private View descriptionView;
|
||||
private boolean nightMode;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
purchaseHelper = getDownloadActivity().getPurchaseHelper();
|
||||
boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
|
||||
int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
|
||||
nightMode = !getMyApplication().getSettings().isLightContent();
|
||||
int themeId = nightMode ? R.style.OsmandDarkTheme : R.style.OsmandLightTheme;
|
||||
setStyle(STYLE_NO_FRAME, themeId);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
@ -133,6 +146,7 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
addSubscribeEmailRow();
|
||||
addSearchRow();
|
||||
addRestorePurchasesRow();
|
||||
addDescriptionRow();
|
||||
listView.setOnChildClickListener(this);
|
||||
listAdapter = new DownloadResourceGroupAdapter(activity);
|
||||
listView.setAdapter(listAdapter);
|
||||
|
@ -180,6 +194,11 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
}
|
||||
}
|
||||
|
||||
private void addDescriptionRow() {
|
||||
descriptionView = activity.getLayoutInflater().inflate(R.layout.group_description_item, listView, false);
|
||||
listView.addHeaderView(descriptionView);
|
||||
}
|
||||
|
||||
private void addSearchRow() {
|
||||
if (!openAsDialog() ) {
|
||||
searchView = activity.getLayoutInflater().inflate(R.layout.simple_list_menu_item, null);
|
||||
|
@ -231,6 +250,53 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
}
|
||||
}
|
||||
|
||||
private void updateDescriptionView() {
|
||||
if (descriptionView != null) {
|
||||
if (group != null && group.getRegion() instanceof CustomRegion) {
|
||||
CustomRegion customRegion = (CustomRegion) group.getRegion();
|
||||
DownloadDescriptionInfo downloadDescriptionInfo = customRegion.getDescriptionInfo();
|
||||
if (downloadDescriptionInfo != null) {
|
||||
TextView description = descriptionView.findViewById(R.id.description);
|
||||
CharSequence descr = downloadDescriptionInfo.getLocalizedDescription(activity);
|
||||
description.setText(descr);
|
||||
AndroidUiHelper.updateVisibility(description, !Algorithms.isEmpty(descr));
|
||||
|
||||
ViewGroup buttonsContainer = descriptionView.findViewById(R.id.buttons_container);
|
||||
buttonsContainer.removeAllViews();
|
||||
for (final ActionButton actionButton : downloadDescriptionInfo.getActionButtons(activity)) {
|
||||
String name = actionButton.getName();
|
||||
if (!Algorithms.isEmpty(name)) {
|
||||
TextView buttonText = (TextView) activity.getLayoutInflater().inflate(R.layout.download_description_button, buttonsContainer, false);
|
||||
buttonText.setText(name);
|
||||
buttonText.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (actionButton.getUrl() != null) {
|
||||
WikipediaDialogFragment.showFullArticle(activity, Uri.parse(actionButton.getUrl()), nightMode);
|
||||
} else {
|
||||
activity.getMyApplication().showShortToastMessage(R.string.download_unsupported_action, actionButton.getActionType());
|
||||
}
|
||||
}
|
||||
});
|
||||
buttonsContainer.addView(buttonText);
|
||||
}
|
||||
}
|
||||
LockableViewPager viewPager = descriptionView.findViewById(R.id.images_pager);
|
||||
if (!Algorithms.isEmpty(downloadDescriptionInfo.getImageUrls())) {
|
||||
ImagesPagerAdapter adapter = new ImagesPagerAdapter(downloadDescriptionInfo.getImageUrls());
|
||||
viewPager.setAdapter(adapter);
|
||||
} else {
|
||||
viewPager.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
descriptionView.findViewById(R.id.container).setVisibility(View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
descriptionView.findViewById(R.id.container).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void hideSubscribeEmailView() {
|
||||
if (subscribeEmailView != null && subscribeEmailView.findViewById(R.id.container).getVisibility() == View.VISIBLE) {
|
||||
subscribeEmailView.findViewById(R.id.container).setVisibility(View.GONE);
|
||||
|
@ -389,12 +455,15 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
}
|
||||
|
||||
private void reloadData() {
|
||||
DownloadResources indexes = activity.getDownloadThread().getIndexes();
|
||||
group = indexes.getGroupById(groupId);
|
||||
|
||||
if (!openAsDialog()) {
|
||||
updateSearchView();
|
||||
}
|
||||
updateSubscribeEmailView();
|
||||
DownloadResources indexes = activity.getDownloadThread().getIndexes();
|
||||
group = indexes.getGroupById(groupId);
|
||||
updateDescriptionView();
|
||||
|
||||
if (group != null) {
|
||||
listAdapter.update(group);
|
||||
toolbar.setTitle(group.getName(activity));
|
||||
|
@ -729,4 +798,60 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class ImagesPagerAdapter extends PagerAdapter {
|
||||
|
||||
private PicassoUtils picassoUtils;
|
||||
|
||||
private List<String> imageUrls;
|
||||
|
||||
public ImagesPagerAdapter(List<String> imageUrls) {
|
||||
this.imageUrls = imageUrls;
|
||||
picassoUtils = PicassoUtils.getPicasso(getMyApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return imageUrls.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
View view = createImageView(position);
|
||||
container.addView(view, 0);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup collection, int position, @NonNull Object view) {
|
||||
collection.removeView((View) view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
private View createImageView(int position) {
|
||||
final ImageView imageView = new ImageView(getContext());
|
||||
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
|
||||
|
||||
final String imageUrl = imageUrls.get(position);
|
||||
Picasso.get().load(imageUrl).into(imageView, new Callback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
picassoUtils.setResultLoaded(imageUrl, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception e) {
|
||||
imageView.setVisibility(View.INVISIBLE);
|
||||
picassoUtils.setResultLoaded(imageUrl, false);
|
||||
}
|
||||
});
|
||||
return imageView;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue