diff --git a/OsmAnd/res/layout/wikivoyage_open_beta_card.xml b/OsmAnd/res/layout/wikivoyage_open_beta_card.xml index 5ba3eefd55..4f45dc23af 100644 --- a/OsmAnd/res/layout/wikivoyage_open_beta_card.xml +++ b/OsmAnd/res/layout/wikivoyage_open_beta_card.xml @@ -2,25 +2,30 @@ + android:layout_marginLeft="@dimen/text_margin_small" + android:layout_marginRight="@dimen/text_margin_small" + android:background="@drawable/travel_card_bg" + android:orientation="vertical"> + android:orientation="vertical" + android:background="@color/wikivoyage_open_beta_card_image_background"> + - \ No newline at end of file diff --git a/OsmAnd/res/layout/wikivoyage_start_editing_card.xml b/OsmAnd/res/layout/wikivoyage_start_editing_card.xml index 9874abc0ab..e2290fd173 100644 --- a/OsmAnd/res/layout/wikivoyage_start_editing_card.xml +++ b/OsmAnd/res/layout/wikivoyage_start_editing_card.xml @@ -2,11 +2,13 @@ 21dp 33dp 82dp + 216dp \ No newline at end of file diff --git a/OsmAnd/res/values/colors.xml b/OsmAnd/res/values/colors.xml index 08e38f2c6d..195697b21a 100644 --- a/OsmAnd/res/values/colors.xml +++ b/OsmAnd/res/values/colors.xml @@ -428,6 +428,7 @@ #212121 #cccccc #727272 - #339966 + #339966 + #008bf8 \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 6e386278dd..76705a0755 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,7 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Popular destinations Paid application Paid plugin We prepared updates and fixes in the Wikivoyage data, update the file to see them. diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java index d7b9ededc8..f4b0a02fae 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/TravelDbHelper.java @@ -199,6 +199,24 @@ public class TravelDbHelper { return list; } + @NonNull + public List searchPopular() { + List res = new ArrayList<>(); + SQLiteConnection conn = openConnection(); + if (conn != null) { + TravelArticle travelArticle; + SQLiteCursor cursor = conn.rawQuery("SELECT * FROM " + ARTICLES_TABLE_NAME + " ORDER BY RANDOM() LIMIT 100", null); + if (cursor.moveToFirst()) { + do { + travelArticle = readArticle(cursor); + res.add(travelArticle); + } while (cursor.moveToNext()); + } + cursor.close(); + } + return res; + } + private void sortSearchResults(final String searchQuery, List list) { Collections.sort(list, new Comparator() { @Override diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java new file mode 100644 index 0000000000..073fd3c6fc --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreRvAdapter.java @@ -0,0 +1,143 @@ +package net.osmand.plus.wikivoyage.explore; + +import android.support.annotation.NonNull; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.explore.travelcards.ArticleTravelCard; +import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; +import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; + +import java.util.ArrayList; +import java.util.List; + +public class ExploreRvAdapter extends RecyclerView.Adapter { + + private static final int HEADER_TYPE = 3; + + private final OsmandSettings settings; + + private final List items = new ArrayList<>(); + + private OsmandApplication app; + + ExploreRvAdapter(OsmandApplication app) { + this.app = app; + this.settings = app.getSettings(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == OpenBetaTravelCard.TYPE) { + View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.wikivoyage_open_beta_card, parent, false); + return new OpenBetaTravelCard.OpenBetaTravelVH(itemView); + } + if (viewType == StartEditingTravelCard.TYPE) { + View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.wikivoyage_start_editing_card, parent, false); + return new StartEditingTravelCard.StartEditingTravelVH(itemView); + + } + if (viewType == ArticleTravelCard.TYPE) { + int layoutId = ArticleTravelCard.USE_ALTERNATIVE_CARD ? R.layout.wikivoyage_article_card_alternative : R.layout.wikivoyage_article_card; + View itemView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); + return new ArticleTravelCard.ArticleTravelVH(itemView); + } + if (viewType == HEADER_TYPE) { + View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.wikivoyage_list_header, parent, false); + return new HeaderVH(itemView); + } + return null; + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + Object object = getItem(position); + if (viewHolder instanceof HeaderVH) { + final HeaderVH holder = (HeaderVH) viewHolder; + holder.title.setText((String) object); + holder.description.setText(String.valueOf(getArticleItemCount())); + } else if (viewHolder instanceof ArticleTravelCard.ArticleTravelVH) { + if (object instanceof ArticleTravelCard) { + ArticleTravelCard articleTravelCard = (ArticleTravelCard) object; + articleTravelCard.bindViewHolder(viewHolder); + } + } else if (viewHolder instanceof OpenBetaTravelCard.OpenBetaTravelVH) { + if (object instanceof OpenBetaTravelCard) { + OpenBetaTravelCard openBetaTravelCard = (OpenBetaTravelCard) object; + openBetaTravelCard.bindViewHolder(viewHolder); + } + } else if (viewHolder instanceof StartEditingTravelCard.StartEditingTravelVH) { + if (object instanceof StartEditingTravelCard) { + StartEditingTravelCard startEditingTravelCard = (StartEditingTravelCard) object; + startEditingTravelCard.bindViewHolder(viewHolder); + } + } + } + + @Override + public int getItemViewType(int position) { + Object object = getItem(position); + if (object instanceof String) { + return HEADER_TYPE; + } + if (object instanceof OpenBetaTravelCard) { + return ((OpenBetaTravelCard) object).getCardType(); + } + if (object instanceof StartEditingTravelCard) { + return ((StartEditingTravelCard) object).getCardType(); + } + if (object instanceof ArticleTravelCard) { + return ((ArticleTravelCard) object).getCardType(); + } + return -1; + } + + @Override + public int getItemCount() { + return items.size(); + } + + public int getArticleItemCount() { + int count = 0; + for (Object o : items) { + if (o instanceof ArticleTravelCard) { + count++; + } + } + return count; + } + + private Object getItem(int position) { + return items.get(position); + } + + @NonNull + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items.clear(); + this.items.addAll(items); + } + + static class HeaderVH extends RecyclerView.ViewHolder { + + final TextView title; + final TextView description; + + HeaderVH(View itemView) { + super(itemView); + title = (TextView) itemView.findViewById(R.id.title); + description = (TextView) itemView.findViewById(R.id.description); + } + } +} diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java index 0a584c615a..98e93308b6 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/ExploreTabFragment.java @@ -3,41 +3,56 @@ package net.osmand.plus.wikivoyage.explore; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.base.BaseOsmAndFragment; -import net.osmand.plus.wikivoyage.explore.travelcards.BaseTravelCard; +import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; +import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.explore.travelcards.ArticleTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.OpenBetaTravelCard; import net.osmand.plus.wikivoyage.explore.travelcards.StartEditingTravelCard; import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; public class ExploreTabFragment extends BaseOsmAndFragment { + @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - OsmandApplication app = getMyApplication(); - boolean nightMode = !getSettings().isLightContent(); - final View mainView = inflater.inflate(R.layout.fragment_explore_tab, container, false); - - ArrayList items = new ArrayList<>(); - - OpenBetaTravelCard openBetaTravelCard = new OpenBetaTravelCard(app, nightMode, getFragmentManager()); - StartEditingTravelCard startEditingTravelCard = new StartEditingTravelCard(app, nightMode); - items.add(openBetaTravelCard); - items.add(startEditingTravelCard); - + ExploreRvAdapter adapter = new ExploreRvAdapter(getMyApplication()); final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view); rv.setLayoutManager(new LinearLayoutManager(getContext())); + adapter.setItems(getItems()); + rv.setAdapter(adapter); + return mainView; } + + private List getItems() { + final OsmandApplication app = getMyApplication(); + boolean nightMode = !getSettings().isLightContent(); + List items = new ArrayList<>(); + List savedArticles = app.getTravelDbHelper().searchPopular(); + items.add(new OpenBetaTravelCard(app, nightMode, getFragmentManager())); + items.add(new StartEditingTravelCard(app, nightMode)); + if (!savedArticles.isEmpty()) { + items.add(getString(R.string.popular_destinations)); + for (TravelArticle article : savedArticles) { + items.add(new ArticleTravelCard(app, nightMode, article, getFragmentManager())); + } + } + return items; + } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java new file mode 100644 index 0000000000..eb80af9b00 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/ArticleTravelCard.java @@ -0,0 +1,131 @@ +package net.osmand.plus.wikivoyage.explore.travelcards; + +import android.graphics.drawable.Drawable; +import android.support.annotation.NonNull; +import android.support.v4.app.FragmentManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.squareup.picasso.Callback; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.RequestCreator; + +import net.osmand.plus.IconsCache; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.widgets.tools.CropCircleTransformation; +import net.osmand.plus.widgets.tools.CropRectTransformation; +import net.osmand.plus.wikivoyage.WikivoyageUtils; +import net.osmand.plus.wikivoyage.article.WikivoyageArticleDialogFragment; +import net.osmand.plus.wikivoyage.data.TravelArticle; +import net.osmand.plus.wikivoyage.data.TravelLocalDataHelper; + +public class ArticleTravelCard extends BaseTravelCard { + + public static final int TYPE = 2; + public static final boolean USE_ALTERNATIVE_CARD = false; + + private TravelArticle article; + private final Drawable readIcon; + private FragmentManager fragmentManager; + + public ArticleTravelCard(OsmandApplication app, boolean nightMode, TravelArticle article, FragmentManager fragmentManager) { + super(app, nightMode); + this.article = article; + readIcon = getActiveIcon(R.drawable.ic_action_read_article); + this.fragmentManager = fragmentManager; + } + + @Override + public void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { + if (viewHolder instanceof ArticleTravelVH) { + final ArticleTravelVH holder = (ArticleTravelVH) viewHolder; + RequestCreator rc = Picasso.get() + .load(TravelArticle.getImageUrl(article.getImageTitle(), false)); + WikivoyageUtils.setupNetworkPolicy(app.getSettings(), rc); + rc.transform(USE_ALTERNATIVE_CARD ? new CropRectTransformation() : new CropCircleTransformation()) + .into(holder.icon, new Callback() { + @Override + public void onSuccess() { + holder.icon.setVisibility(View.VISIBLE); + } + + @Override + public void onError(Exception e) { + holder.icon.setVisibility(View.GONE); + } + }); + holder.title.setText(article.getTitle()); + holder.content.setText(article.getPartialContent()); + holder.partOf.setText(article.getGeoDescription()); + holder.leftButton.setText(app.getString(R.string.shared_string_read)); + View.OnClickListener readClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (fragmentManager != null) { + WikivoyageArticleDialogFragment.showInstance(app, fragmentManager, article.getCityId(), article.getLang()); + } + } + }; + holder.leftButton.setOnClickListener(readClickListener); + holder.itemView.setOnClickListener(readClickListener); + holder.leftButton.setCompoundDrawablesWithIntrinsicBounds(readIcon, null, null, null); + updateSaveButton(holder); + } + } + + private void updateSaveButton(final ArticleTravelVH holder) { + if (article != null) { + final TravelLocalDataHelper helper = app.getTravelDbHelper().getLocalDataHelper(); + final boolean saved = helper.isArticleSaved(article); + Drawable icon = getActiveIcon(saved ? R.drawable.ic_action_read_later_fill : R.drawable.ic_action_read_later); + holder.rightButton.setText(saved ? R.string.shared_string_delete : R.string.shared_string_save); + holder.rightButton.setCompoundDrawablesWithIntrinsicBounds(null, null, icon, null); + holder.rightButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (article != null) { + if (saved) { + helper.removeArticleFromSaved(article); + } else { + app.getTravelDbHelper().createGpxFile(article); + helper.addArticleToSaved(article); + } + updateSaveButton(holder); + } + } + }); + } + } + + public static class ArticleTravelVH extends RecyclerView.ViewHolder { + + final TextView title; + final TextView content; + final TextView partOf; + final ImageView icon; + final TextView leftButton; + final TextView rightButton; + final View divider; + final View shadow; + + public ArticleTravelVH(final View itemView) { + super(itemView); + title = (TextView) itemView.findViewById(R.id.title); + content = (TextView) itemView.findViewById(R.id.content); + partOf = (TextView) itemView.findViewById(R.id.part_of); + icon = (ImageView) itemView.findViewById(R.id.icon); + leftButton = (TextView) itemView.findViewById(R.id.left_button); + rightButton = (TextView) itemView.findViewById(R.id.right_button); + divider = itemView.findViewById(R.id.divider); + shadow = itemView.findViewById(R.id.shadow); + } + } + + @Override + public int getCardType() { + return TYPE; + } +} diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/OpenBetaTravelCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/OpenBetaTravelCard.java index b2200e3bda..017e5c4b4a 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/OpenBetaTravelCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/OpenBetaTravelCard.java @@ -13,6 +13,8 @@ import net.osmand.plus.chooseplan.ChoosePlanDialogFragment; public class OpenBetaTravelCard extends BaseTravelCard { + public static final int TYPE = 0; + private FragmentManager fragmentManager; public OpenBetaTravelCard(OsmandApplication app, boolean nightMode, FragmentManager fragmentManager) { @@ -37,14 +39,14 @@ public class OpenBetaTravelCard extends BaseTravelCard { } } - class OpenBetaTravelVH extends RecyclerView.ViewHolder { + public static class OpenBetaTravelVH extends RecyclerView.ViewHolder { final TextView title; final TextView description; final TextView button; final ImageView backgroundImage; - OpenBetaTravelVH(final View itemView) { + public OpenBetaTravelVH(final View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.title); description = (TextView) itemView.findViewById(R.id.description); @@ -55,6 +57,6 @@ public class OpenBetaTravelCard extends BaseTravelCard { @Override public int getCardType() { - return 0; + return TYPE; } } diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/StartEditingTravelCard.java b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/StartEditingTravelCard.java index cce59cd217..7b57c7a51a 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/StartEditingTravelCard.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/explore/travelcards/StartEditingTravelCard.java @@ -14,6 +14,8 @@ import net.osmand.plus.R; public class StartEditingTravelCard extends BaseTravelCard { + public static final int TYPE = 1; + public StartEditingTravelCard(OsmandApplication app, boolean nightMode) { super(app, nightMode); } @@ -39,14 +41,14 @@ public class StartEditingTravelCard extends BaseTravelCard { } } - class StartEditingTravelVH extends RecyclerView.ViewHolder { + public static class StartEditingTravelVH extends RecyclerView.ViewHolder { final TextView title; final TextView description; final TextView button; final ImageView backgroundImage; - StartEditingTravelVH(final View itemView) { + public StartEditingTravelVH(final View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.title); description = (TextView) itemView.findViewById(R.id.description); @@ -57,6 +59,6 @@ public class StartEditingTravelCard extends BaseTravelCard { @Override public int getCardType() { - return 1; + return TYPE; } }