Show all available obf travel files in the card to download

This commit is contained in:
Dima-1 2021-02-04 11:43:53 +02:00
parent 9483c80790
commit f55c64159e
6 changed files with 166 additions and 522 deletions

View file

@ -1,198 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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_marginLeft="@dimen/text_margin_small"
android:layout_marginRight="@dimen/text_margin_small"
android:background="?attr/wikivoyage_travel_card_bg"
android:orientation="vertical"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginStart="@dimen/text_margin_small">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/content_padding"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_sheet_content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Download file"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="ContentDescription"
tools:src="@drawable/travel_card_download_icon"/>
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingMultiplier="@dimen/text_button_line_spacing_multiplier"
android:textColor="@color/wikivoyage_secondary_text"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Download this Wikivoyage travel guides file to view articles about places around the world without an internet connection."/>
</LinearLayout>
<LinearLayout
android:id="@+id/file_data_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:background="?attr/wikivoyage_travel_card_stroke_bg"
android:minHeight="@dimen/bottom_sheet_selected_item_title_height"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/file_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_action_read_article"
tools:tint="?attr/wikivoyage_active_color"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/file_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Wikivoyage"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/file_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/wikivoyage_secondary_text"
android:textSize="@dimen/default_sub_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="255 Mb • Update 11 April"/>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/bottom_sheet_content_margin_small"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin_small"
android:layout_marginRight="@dimen/bottom_sheet_content_margin_small"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin_small"
android:layout_marginStart="@dimen/bottom_sheet_content_margin_small">
<FrameLayout
android:id="@+id/secondary_btn_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?attr/wikivoyage_secondary_btn_bg">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/secondary_button"
android:layout_width="match_parent"
android:layout_height="@dimen/wikivoyage_card_button_height"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless"
android:ellipsize="end"
android:gravity="center"
android:letterSpacing="@dimen/text_button_letter_spacing"
android:maxLines="1"
android:textColor="?attr/wikivoyage_active_color"
android:textSize="@dimen/text_button_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:ignore="UnusedAttribute"
tools:text="Later"/>
</FrameLayout>
<View
android:id="@+id/buttons_divider"
android:layout_width="@dimen/bottom_sheet_content_margin_small"
android:layout_height="match_parent"/>
<FrameLayout
android:id="@+id/primary_btn_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="?attr/wikivoyage_primary_btn_bg">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/primary_button"
android:layout_width="match_parent"
android:layout_height="@dimen/wikivoyage_card_button_height"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless"
android:ellipsize="end"
android:gravity="center"
android:letterSpacing="@dimen/text_button_letter_spacing"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_btn_text_color"
android:textSize="@dimen/text_button_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:ignore="UnusedAttribute"
tools:text="Update"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -18,16 +18,34 @@
android:layout_margin="@dimen/content_padding" android:layout_margin="@dimen/content_padding"
android:orientation="vertical"> android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding" android:layout_marginBottom="@dimen/bottom_sheet_content_padding_small">
android:ellipsize="end"
android:maxLines="1" <net.osmand.plus.widgets.TextViewEx
android:text="@string/maps_you_need" android:id="@+id/title"
android:textColor="?attr/wikivoyage_primary_text_color" android:layout_width="0dp"
android:textSize="@dimen/travel_card_primary_text_size" android:layout_height="wrap_content"
osmand:typeface="@string/font_roboto_medium"/> android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="4dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?attr/wikivoyage_primary_text_color"
android:textSize="@dimen/travel_card_primary_text_size"
osmand:typeface="@string/font_roboto_medium"
tools:text="Download file" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="ContentDescription"
tools:src="@drawable/travel_card_download_icon" />
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/description" android:id="@+id/description"

View file

@ -19,7 +19,6 @@ import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard.OpenBet
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard;
import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard.StartEditingTravelVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelDownloadUpdateCard.DownloadUpdateVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH; import net.osmand.plus.wikivoyage.explore.travelcards.TravelGpxCard.TravelGpxVH;
import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard; import net.osmand.plus.wikivoyage.explore.travelcards.TravelNeededMapsCard;
@ -53,12 +52,10 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
case TravelGpxCard.TYPE: case TravelGpxCard.TYPE:
return new TravelGpxVH(inflate(parent, R.layout.wikivoyage_travel_gpx_card)); return new TravelGpxVH(inflate(parent, R.layout.wikivoyage_travel_gpx_card));
case TravelDownloadUpdateCard.TYPE:
return new DownloadUpdateVH(inflate(parent, R.layout.travel_download_update_card));
case HeaderTravelCard.TYPE: case HeaderTravelCard.TYPE:
return new HeaderTravelVH(inflate(parent, R.layout.wikivoyage_list_header)); return new HeaderTravelVH(inflate(parent, R.layout.wikivoyage_list_header));
case TravelDownloadUpdateCard.TYPE:
case TravelNeededMapsCard.TYPE: case TravelNeededMapsCard.TYPE:
return new NeededMapsVH(inflate(parent, R.layout.travel_needed_maps_card)); return new NeededMapsVH(inflate(parent, R.layout.travel_needed_maps_card));
@ -205,7 +202,7 @@ public class ExploreRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
if(onlyProgress) { if(onlyProgress) {
TravelDownloadUpdateCard dc = this.downloadCard; TravelDownloadUpdateCard dc = this.downloadCard;
if(dc != null) { if(dc != null) {
dc.updateProgresBar(); dc.updateView();
} }
return; return;
} }

View file

@ -1,7 +1,6 @@
package net.osmand.plus.wikivoyage.explore; package net.osmand.plus.wikivoyage.explore;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.util.Pair; import android.util.Pair;
@ -63,9 +62,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private DownloadValidationManager downloadManager; private DownloadValidationManager downloadManager;
@Nullable @Nullable
private IndexItem currentDownloadingIndexItem; private IndexItem currentDownloadingIndexItem;
@Nullable private final List<IndexItem> mainIndexItems = new ArrayList<>();
private IndexItem mainIndexItem;
private final List<IndexItem> neededIndexItems = new ArrayList<>(); private final List<IndexItem> neededIndexItems = new ArrayList<>();
private boolean waitForIndexes; private boolean waitForIndexes;
@ -199,17 +196,24 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
private void removeRedundantCards() { private void removeRedundantCards() {
if (mainIndexItem != null && mainIndexItem.isDownloaded() && !mainIndexItem.isOutdated()) { boolean allTravelGuideDownloaded = true;
removeDownloadUpdateCard(); for (IndexItem item : mainIndexItems) {
}
boolean allMapsDownloaded = true;
for (IndexItem item : neededIndexItems) {
if (!item.isDownloaded()) { if (!item.isDownloaded()) {
allMapsDownloaded = false; allTravelGuideDownloaded = false;
break; break;
} }
} }
if (allMapsDownloaded) { if (allTravelGuideDownloaded) {
removeDownloadUpdateCard();
}
boolean neededMapsDownloaded = true;
for (IndexItem item : neededIndexItems) {
if (!item.isDownloaded()) {
neededMapsDownloaded = false;
break;
}
}
if (neededMapsDownloaded) {
removeNeededMapsCard(); removeNeededMapsCard();
} }
} }
@ -218,8 +222,9 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
new ProcessIndexItemsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); new ProcessIndexItemsTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
private void addIndexItemCards(IndexItem mainIndexItem, List<IndexItem> neededIndexItems) { private void addIndexItemCards(List<IndexItem> mainIndexItem, List<IndexItem> neededIndexItems) {
this.mainIndexItem = mainIndexItem; this.mainIndexItems.clear();
this.mainIndexItems.addAll(mainIndexItem);
this.neededIndexItems.clear(); this.neededIndexItems.clear();
this.neededIndexItems.addAll(neededIndexItems); this.neededIndexItems.addAll(neededIndexItems);
addDownloadUpdateCard(); addDownloadUpdateCard();
@ -228,53 +233,58 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private void addDownloadUpdateCard() { private void addDownloadUpdateCard() {
final OsmandApplication app = getMyApplication(); final OsmandApplication app = getMyApplication();
if (app != null) { if (app != null && !mainIndexItems.isEmpty() && SHOW_TRAVEL_UPDATE_CARD) {
final DownloadIndexesThread downloadThread = app.getDownloadThread(); boolean outdated = isMapsOutdated();
downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, mainIndexItems, !outdated);
boolean outdated = mainIndexItem != null && mainIndexItem.isOutdated(); downloadUpdateCard.setListener(new TravelDownloadUpdateCard.CardListener() {
boolean needsDownloading = mainIndexItem != null && !mainIndexItem.isDownloaded(); @Override
public void onPrimaryButtonClick() {
if (!app.getTravelHelper().isAnyTravelBookPresent() || needsDownloading || (outdated && SHOW_TRAVEL_UPDATE_CARD)) { if (downloadManager != null) {
boolean showOtherMaps = false; downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(mainIndexItems));
if (needsDownloading) { adapter.updateDownloadUpdateCard(false);
List<IndexItem> items = downloadThread.getIndexes().getWikivoyageItems(); }
showOtherMaps = items != null && items.size() > 1;
} }
downloadUpdateCard = new TravelDownloadUpdateCard(app, nightMode, !outdated); @Override
downloadUpdateCard.setShowOtherMapsBtn(showOtherMaps); public void onSecondaryButtonClick() {
downloadUpdateCard.setListener(new TravelDownloadUpdateCard.ClickListener() { if (downloadUpdateCard.isDownloading()) {
@Override app.getDownloadThread().cancelDownload(mainIndexItems);
public void onPrimaryButtonClick() { adapter.updateDownloadUpdateCard(false);
if (mainIndexItem != null && downloadManager != null) { } else {
downloadManager.startDownload(getMyActivity(), mainIndexItem); SHOW_TRAVEL_UPDATE_CARD = false;
adapter.updateDownloadUpdateCard(false); removeDownloadUpdateCard();
}
} }
}
@Override @Override
public void onSecondaryButtonClick() { public void onIndexItemClick(IndexItem item) {
if (downloadUpdateCard.isLoading()) { if (item.getType() == DownloadActivityType.WIKIPEDIA_FILE && !Version.isPaidVersion(app)) {
downloadThread.cancelDownload(mainIndexItem); FragmentManager fm = getFragmentManager();
adapter.updateDownloadUpdateCard(false); if (fm != null) {
} else if (!downloadUpdateCard.isDownload()) { ChoosePlanDialogFragment.showWikipediaInstance(fm);
SHOW_TRAVEL_UPDATE_CARD = false;
removeDownloadUpdateCard();
} else if (downloadUpdateCard.isShowOtherMapsBtn()) {
Activity activity = getActivity();
if (activity != null) {
Intent newIntent = new Intent(activity,
((OsmandApplication) activity.getApplication()).getAppCustomization().getDownloadActivity());
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
activity.startActivity(newIntent);
}
} }
} else {
DownloadIndexesThread downloadThread = app.getDownloadThread();
if (downloadThread.isDownloading(item)) {
downloadThread.cancelDownload(item);
} else if (!item.isDownloaded() && downloadManager != null) {
downloadManager.startDownload(getMyActivity(), item);
}
adapter.updateDownloadUpdateCard(false);
} }
}); }
downloadUpdateCard.setIndexItem(mainIndexItem); });
adapter.addDownloadUpdateCard(downloadUpdateCard); adapter.addDownloadUpdateCard(downloadUpdateCard);
}
}
private boolean isMapsOutdated() {
for (IndexItem indexItem : mainIndexItems) {
if (indexItem.isOutdated()) {
return true;
} }
} }
return false;
} }
private void addNeededMapsCard() { private void addNeededMapsCard() {
@ -285,7 +295,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
@Override @Override
public void onPrimaryButtonClick() { public void onPrimaryButtonClick() {
if (downloadManager != null) { if (downloadManager != null) {
downloadManager.startDownload(getMyActivity(), getAllItemsForDownload()); downloadManager.startDownload(getMyActivity(), getAllItemsForDownload(neededIndexItems));
adapter.updateNeededMapsCard(false); adapter.updateNeededMapsCard(false);
} }
} }
@ -323,10 +333,10 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
} }
} }
private IndexItem[] getAllItemsForDownload() { private IndexItem[] getAllItemsForDownload(List<IndexItem> indexItems) {
boolean paidVersion = Version.isPaidVersion(getMyApplication()); boolean paidVersion = Version.isPaidVersion(getMyApplication());
ArrayList<IndexItem> res = new ArrayList<>(); ArrayList<IndexItem> res = new ArrayList<>();
for (IndexItem item : neededIndexItems) { for (IndexItem item : indexItems) {
if (!item.isDownloaded() && (paidVersion || item.getType() != DownloadActivityType.WIKIPEDIA_FILE)) { if (!item.isDownloaded() && (paidVersion || item.getType() != DownloadActivityType.WIKIPEDIA_FILE)) {
res.add(item); res.add(item);
} }
@ -344,7 +354,7 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
neededMapsCard = null; neededMapsCard = null;
} }
private static class ProcessIndexItemsTask extends AsyncTask<Void, Void, Pair<IndexItem, List<IndexItem>>> { private static class ProcessIndexItemsTask extends AsyncTask<Void, Void, Pair<List<IndexItem>, List<IndexItem>>> {
private static final DownloadActivityType[] types = new DownloadActivityType[]{ private static final DownloadActivityType[] types = new DownloadActivityType[]{
DownloadActivityType.NORMAL_FILE, DownloadActivityType.NORMAL_FILE,
@ -354,40 +364,41 @@ public class ExploreTabFragment extends BaseOsmAndFragment implements DownloadEv
private final OsmandApplication app; private final OsmandApplication app;
private final WeakReference<ExploreTabFragment> weakFragment; private final WeakReference<ExploreTabFragment> weakFragment;
private final String fileName;
ProcessIndexItemsTask(ExploreTabFragment fragment) { ProcessIndexItemsTask(ExploreTabFragment fragment) {
app = fragment.getMyApplication(); app = fragment.getMyApplication();
weakFragment = new WeakReference<>(fragment); weakFragment = new WeakReference<>(fragment);
fileName = app != null ? app.getTravelHelper().getWikivoyageFileName() : null;
} }
@Override @Override
protected Pair<IndexItem, List<IndexItem>> doInBackground(Void... voids) { protected Pair<List<IndexItem>, List<IndexItem>> doInBackground(Void... voids) {
if (fileName != null) { List<IndexItem> mainItems = new ArrayList<>();
IndexItem mainItem = app.getDownloadThread().getIndexes().getWikivoyageItem(fileName); List<IndexItem> allWikivoyageItems = app.getDownloadThread().getIndexes().getWikivoyageItems();
if (allWikivoyageItems != null) {
List<IndexItem> neededItems = new ArrayList<>(); for (IndexItem item : allWikivoyageItems) {
for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) { if (!item.isDownloaded() && !mainItems.contains(item)) {
LatLon latLon = new LatLon(article.getLat(), article.getLon()); mainItems.add(item);
try {
for (DownloadActivityType type : types) {
IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type);
if (item != null && !item.isDownloaded() && !neededItems.contains(item)) {
neededItems.add(item);
}
}
} catch (IOException e) {
// ignore
} }
} }
return new Pair<>(mainItem, neededItems);
} }
return null; List<IndexItem> neededItems = new ArrayList<>();
for (TravelArticle article : app.getTravelHelper().getBookmarksHelper().getSavedArticles()) {
LatLon latLon = new LatLon(article.getLat(), article.getLon());
try {
for (DownloadActivityType type : types) {
IndexItem item = DownloadResources.findSmallestIndexItemAt(app, latLon, type);
if (item != null && !item.isDownloaded() && !neededItems.contains(item)) {
neededItems.add(item);
}
}
} catch (IOException e) {
// ignore
}
}
return new Pair<>(mainItems, neededItems);
} }
@Override @Override
protected void onPostExecute(Pair<IndexItem, List<IndexItem>> res) { protected void onPostExecute(Pair<List<IndexItem>, List<IndexItem>> res) {
ExploreTabFragment fragment = weakFragment.get(); ExploreTabFragment fragment = weakFragment.get();
if (res != null && fragment != null && fragment.isResumed()) { if (res != null && fragment != null && fragment.isResumed()) {
fragment.addIndexItemCards(res.first, res.second); fragment.addIndexItemCards(res.first, res.second);

View file

@ -1,257 +1,47 @@
package net.osmand.plus.wikivoyage.explore.travelcards; package net.osmand.plus.wikivoyage.explore.travelcards;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import java.lang.ref.WeakReference; import java.util.List;
import java.text.DateFormat;
public class TravelDownloadUpdateCard extends BaseTravelCard { public class TravelDownloadUpdateCard extends TravelNeededMapsCard {
public static final int TYPE = 50; public static final int TYPE = 50;
private boolean download; private final boolean download;
private boolean showOtherMapsBtn;
private WeakReference<DownloadUpdateVH> ref;
private ClickListener listener; public TravelDownloadUpdateCard(@NonNull OsmandApplication app, boolean nightMode, @NonNull List<IndexItem> items,
boolean download) {
@Nullable super(app, nightMode, items);
private IndexItem indexItem;
private DateFormat dateFormat;
public boolean isDownload() {
return download;
}
public boolean isShowOtherMapsBtn() {
return showOtherMapsBtn;
}
public void setShowOtherMapsBtn(boolean showOtherMapsBtn) {
this.showOtherMapsBtn = showOtherMapsBtn;
}
public void setListener(ClickListener listener) {
this.listener = listener;
}
public void setIndexItem(@Nullable IndexItem indexItem) {
this.indexItem = indexItem;
}
public TravelDownloadUpdateCard(OsmandApplication app, boolean nightMode, boolean download) {
super(app, nightMode);
this.download = download; this.download = download;
dateFormat = android.text.format.DateFormat.getMediumDateFormat(app); }
public int getTitle() {
if (isDownloading()) {
return R.string.shared_string_downloading;
}
return download ? R.string.download_file : R.string.update_is_available;
} }
@Override @Override
public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { public int getDescription() {
if (viewHolder instanceof DownloadUpdateVH) { if (!isInternetAvailable()) {
boolean loading = isLoading(); return R.string.no_index_file_to_download;
DownloadUpdateVH holder = (DownloadUpdateVH) viewHolder;
this.ref = new WeakReference<TravelDownloadUpdateCard.DownloadUpdateVH>(holder);
holder.title.setText(getTitle(loading));
holder.icon.setImageResource(getIconRes());
holder.description.setText(getDescription());
if (indexItem == null) {
holder.fileDataContainer.setVisibility(View.GONE);
} else {
holder.fileDataContainer.setVisibility(View.VISIBLE);
holder.fileIcon.setImageDrawable(getFileIcon());
holder.fileTitle.setText(getFileTitle());
holder.fileDescription.setText(getFileDescription());
holder.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
updateProgressBar(holder);
}
boolean primaryBtnVisible = updatePrimaryButton(holder, loading);
boolean secondaryBtnVisible = updateSecondaryButton(holder, loading);
holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE);
}
}
public void updateProgresBar() {
if(ref != null) {
DownloadUpdateVH holder = ref.get();
if (holder != null && holder.itemView.isShown()) {
updateProgressBar(holder);
}
} }
return download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr;
} }
private void updateProgressBar(DownloadUpdateVH holder) { @Override
if (isLoadingInProgress()) { public int getIconRes() {
int progress = app.getDownloadThread().getCurrentDownloadingItemProgress(); return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon;
holder.progressBar.setProgress(progress < 0 ? 0 : progress);
} else {
holder.progressBar.setProgress(0);
}
} }
@Override @Override
public int getCardType() { public int getCardType() {
return TYPE; return TYPE;
} }
@NonNull
private String getTitle(boolean loading) {
if (loading) {
return app.getString(R.string.shared_string_downloading);
}
return app.getString(download ? R.string.download_file : R.string.update_is_available);
}
private int getIconRes() {
return download ? R.drawable.travel_card_download_icon : R.drawable.travel_card_update_icon;
}
@NonNull
private String getDescription() {
if (!isInternetAvailable()) {
return app.getString(R.string.no_index_file_to_download);
}
return app.getString(download ? R.string.travel_card_download_descr : R.string.travel_card_update_descr);
}
@NonNull
private String getFileTitle() {
return indexItem == null ? "" : indexItem.getVisibleName(app, app.getRegions(), false);
}
@NonNull
private String getFileDescription() {
StringBuilder sb = new StringBuilder();
if (indexItem != null) {
sb.append(app.getString(R.string.file_size_in_mb, indexItem.getArchiveSizeMB()));
sb.append("");
sb.append(indexItem.getRemoteDate(dateFormat));
}
return sb.toString();
}
private Drawable getFileIcon() {
return getActiveIcon(R.drawable.ic_action_read_article);
}
/**
* @return true if button is visible, false otherwise.
*/
private boolean updateSecondaryButton(DownloadUpdateVH vh, boolean loading) {
if (loading || !download || showOtherMapsBtn) {
vh.secondaryBtnContainer.setVisibility(View.VISIBLE);
vh.secondaryBtn.setText(getSecondaryBtnTextId(loading));
vh.secondaryBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onSecondaryButtonClick();
}
}
});
return true;
}
vh.secondaryBtnContainer.setVisibility(View.GONE);
return false;
}
@StringRes
private int getSecondaryBtnTextId(boolean loading) {
if (loading) {
return R.string.shared_string_cancel;
}
if (!download) {
return R.string.later;
}
return R.string.download_select_map_types;
}
/**
* @return true if button is visible, false otherwise.
*/
private boolean updatePrimaryButton(DownloadUpdateVH vh, boolean loading) {
if (!loading) {
boolean enabled = isInternetAvailable();
vh.primaryBtnContainer.setVisibility(View.VISIBLE);
vh.primaryBtnContainer.setBackgroundResource(getPrimaryBtnBgRes(enabled));
vh.primaryButton.setTextColor(getResolvedColor(getPrimaryBtnTextColorRes(enabled)));
vh.primaryButton.setEnabled(enabled);
vh.primaryButton.setText(download ? R.string.shared_string_download : R.string.shared_string_update);
vh.primaryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) {
listener.onPrimaryButtonClick();
}
}
});
return true;
}
vh.primaryBtnContainer.setVisibility(View.GONE);
return false;
}
public boolean isLoading() {
return indexItem != null && app.getDownloadThread().isDownloading(indexItem);
}
private boolean isLoadingInProgress() {
IndexItem current = app.getDownloadThread().getCurrentDownloadingItem();
return indexItem != null && current != null && indexItem == current;
}
public interface ClickListener {
void onPrimaryButtonClick();
void onSecondaryButtonClick();
}
public static class DownloadUpdateVH extends RecyclerView.ViewHolder {
final TextView title;
final ImageView icon;
final TextView description;
final View fileDataContainer;
final ImageView fileIcon;
final TextView fileTitle;
final TextView fileDescription;
final ProgressBar progressBar;
final View secondaryBtnContainer;
final TextView secondaryBtn;
final View buttonsDivider;
final View primaryBtnContainer;
final TextView primaryButton;
@SuppressWarnings("RedundantCast")
public DownloadUpdateVH(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
icon = (ImageView) itemView.findViewById(R.id.icon);
description = (TextView) itemView.findViewById(R.id.description);
fileDataContainer = itemView.findViewById(R.id.file_data_container);
fileIcon = (ImageView) itemView.findViewById(R.id.file_icon);
fileTitle = (TextView) itemView.findViewById(R.id.file_title);
fileDescription = (TextView) itemView.findViewById(R.id.file_description);
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container);
secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button);
buttonsDivider = itemView.findViewById(R.id.buttons_divider);
primaryBtnContainer = itemView.findViewById(R.id.primary_btn_container);
primaryButton = (TextView) itemView.findViewById(R.id.primary_button);
}
}
} }

View file

@ -9,7 +9,9 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
@ -60,8 +62,12 @@ public class TravelNeededMapsCard extends BaseTravelCard {
if (viewHolder instanceof NeededMapsVH) { if (viewHolder instanceof NeededMapsVH) {
NeededMapsVH holder = (NeededMapsVH) viewHolder; NeededMapsVH holder = (NeededMapsVH) viewHolder;
ref = new WeakReference<NeededMapsVH>(holder); ref = new WeakReference<NeededMapsVH>(holder);
holder.description.setText(isInternetAvailable() holder.title.setText(getTitle());
? R.string.maps_you_need_descr : R.string.no_index_file_to_download); holder.description.setText(getDescription());
int iconRes = getIconRes();
if (iconRes > 0) {
holder.icon.setImageResource(iconRes);
}
adjustChildCount(holder.itemsContainer); adjustChildCount(holder.itemsContainer);
updateView(holder); updateView(holder);
@ -71,7 +77,23 @@ public class TravelNeededMapsCard extends BaseTravelCard {
holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE); holder.buttonsDivider.setVisibility(primaryBtnVisible && secondaryBtnVisible ? View.VISIBLE : View.GONE);
} }
} }
@StringRes
public int getTitle() {
return R.string.maps_you_need;
}
@StringRes
public int getDescription() {
return isInternetAvailable()
? R.string.maps_you_need_descr : R.string.no_index_file_to_download;
}
@DrawableRes
public int getIconRes() {
return 0;
}
public void updateView() { public void updateView() {
if (ref != null) { if (ref != null) {
NeededMapsVH holder = ref.get(); NeededMapsVH holder = ref.get();
@ -227,7 +249,9 @@ public class TravelNeededMapsCard extends BaseTravelCard {
public static class NeededMapsVH extends RecyclerView.ViewHolder { public static class NeededMapsVH extends RecyclerView.ViewHolder {
final TextView title;
final TextView description; final TextView description;
final ImageView icon;
final LinearLayout itemsContainer; final LinearLayout itemsContainer;
final View secondaryBtnContainer; final View secondaryBtnContainer;
final TextView secondaryBtn; final TextView secondaryBtn;
@ -238,7 +262,9 @@ public class TravelNeededMapsCard extends BaseTravelCard {
@SuppressWarnings("RedundantCast") @SuppressWarnings("RedundantCast")
public NeededMapsVH(View itemView) { public NeededMapsVH(View itemView) {
super(itemView); super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description); description = (TextView) itemView.findViewById(R.id.description);
icon = (ImageView) itemView.findViewById(R.id.icon);
itemsContainer = (LinearLayout) itemView.findViewById(R.id.items_container); itemsContainer = (LinearLayout) itemView.findViewById(R.id.items_container);
secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container); secondaryBtnContainer = itemView.findViewById(R.id.secondary_btn_container);
secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button); secondaryBtn = (TextView) itemView.findViewById(R.id.secondary_button);